| author | |
| committer | |
| log | 648f592db10d3354dcf7e36264291dd82f4d0e3a |
| tree | 3658d6c3541a2ae95321d25ef84707f0ab7ef669 |
| parent | 18608223ef5e588598d21dfe71678dbc62f320e4 |
| parent | c6e02044da8ce1176fa67fe2d1c6de7802927171 |
| signature |
compiler: move BuiltinFn and AstRlAnnotate to std.zig namespace9 files changed, 2129 insertions(+), 2137 deletions(-)
CMakeLists.txt+1-1| ... | @@ -508,6 +508,7 @@ set(ZIG_STAGE2_SOURCES | ... | @@ -508,6 +508,7 @@ set(ZIG_STAGE2_SOURCES |
| 508 | "${CMAKE_SOURCE_DIR}/lib/std/unicode.zig" | 508 | "${CMAKE_SOURCE_DIR}/lib/std/unicode.zig" |
| 509 | "${CMAKE_SOURCE_DIR}/lib/std/zig.zig" | 509 | "${CMAKE_SOURCE_DIR}/lib/std/zig.zig" |
| 510 | "${CMAKE_SOURCE_DIR}/lib/std/zig/Ast.zig" | 510 | "${CMAKE_SOURCE_DIR}/lib/std/zig/Ast.zig" |
| 511 | "${CMAKE_SOURCE_DIR}/lib/std/zig/AstRlAnnotate.zig" | ||
| 511 | "${CMAKE_SOURCE_DIR}/lib/std/zig/CrossTarget.zig" | 512 | "${CMAKE_SOURCE_DIR}/lib/std/zig/CrossTarget.zig" |
| 512 | "${CMAKE_SOURCE_DIR}/lib/std/zig/c_builtins.zig" | 513 | "${CMAKE_SOURCE_DIR}/lib/std/zig/c_builtins.zig" |
| 513 | "${CMAKE_SOURCE_DIR}/lib/std/zig/Parse.zig" | 514 | "${CMAKE_SOURCE_DIR}/lib/std/zig/Parse.zig" |
| ... | @@ -521,7 +522,6 @@ set(ZIG_STAGE2_SOURCES | ... | @@ -521,7 +522,6 @@ set(ZIG_STAGE2_SOURCES |
| 521 | "${CMAKE_SOURCE_DIR}/lib/std/zig/tokenizer.zig" | 522 | "${CMAKE_SOURCE_DIR}/lib/std/zig/tokenizer.zig" |
| 522 | "${CMAKE_SOURCE_DIR}/src/Air.zig" | 523 | "${CMAKE_SOURCE_DIR}/src/Air.zig" |
| 523 | "${CMAKE_SOURCE_DIR}/src/AstGen.zig" | 524 | "${CMAKE_SOURCE_DIR}/src/AstGen.zig" |
| 524 | "${CMAKE_SOURCE_DIR}/src/AstRlAnnotate.zig" | ||
| 525 | "${CMAKE_SOURCE_DIR}/src/Compilation.zig" | 525 | "${CMAKE_SOURCE_DIR}/src/Compilation.zig" |
| 526 | "${CMAKE_SOURCE_DIR}/src/Liveness.zig" | 526 | "${CMAKE_SOURCE_DIR}/src/Liveness.zig" |
| 527 | "${CMAKE_SOURCE_DIR}/src/Module.zig" | 527 | "${CMAKE_SOURCE_DIR}/src/Module.zig" |
lib/std/zig.zig+2| ... | @@ -17,6 +17,8 @@ pub const primitives = @import("zig/primitives.zig"); | ... | @@ -17,6 +17,8 @@ pub const primitives = @import("zig/primitives.zig"); |
| 17 | pub const Ast = @import("zig/Ast.zig"); | 17 | pub const Ast = @import("zig/Ast.zig"); |
| 18 | pub const system = @import("zig/system.zig"); | 18 | pub const system = @import("zig/system.zig"); |
| 19 | pub const CrossTarget = @import("zig/CrossTarget.zig"); | 19 | pub const CrossTarget = @import("zig/CrossTarget.zig"); |
| 20 | pub const BuiltinFn = @import("zig/BuiltinFn.zig"); | ||
| 21 | pub const AstRlAnnotate = @import("zig/AstRlAnnotate.zig"); | ||
| 20 | 22 | ||
| 21 | // Character literal parsing | 23 | // Character literal parsing |
| 22 | pub const ParsedCharLiteral = string_literal.ParsedCharLiteral; | 24 | pub const ParsedCharLiteral = string_literal.ParsedCharLiteral; |
lib/std/zig/AstRlAnnotate.zig created+1105| ... | @@ -0,0 +1,1105 @@ | ||
| 1 | //! AstRlAnnotate is a simple pass which runs over the AST before AstGen to | ||
| 2 | //! determine which expressions require result locations. | ||
| 3 | //! | ||
| 4 | //! In some cases, AstGen can choose whether to provide a result pointer or to | ||
| 5 | //! just use standard `break` instructions from a block. The latter choice can | ||
| 6 | //! result in more efficient ZIR and runtime code, but does not allow for RLS to | ||
| 7 | //! occur. Thus, we want to provide a real result pointer (from an alloc) only | ||
| 8 | //! when necessary. | ||
| 9 | //! | ||
| 10 | //! To achive this, we need to determine which expressions require a result | ||
| 11 | //! pointer. This pass is reponsible for analyzing all syntax forms which may | ||
| 12 | //! provide a result location and, if sub-expressions consume this result | ||
| 13 | //! pointer non-trivially (e.g. writing through field pointers), marking the | ||
| 14 | //! node as requiring a result location. | ||
| 15 | |||
| 16 | const std = @import("std"); | ||
| 17 | const AstRlAnnotate = @This(); | ||
| 18 | const Ast = std.zig.Ast; | ||
| 19 | const Allocator = std.mem.Allocator; | ||
| 20 | const AutoHashMapUnmanaged = std.AutoHashMapUnmanaged; | ||
| 21 | const BuiltinFn = std.zig.BuiltinFn; | ||
| 22 | const assert = std.debug.assert; | ||
| 23 | |||
| 24 | gpa: Allocator, | ||
| 25 | arena: Allocator, | ||
| 26 | tree: *const Ast, | ||
| 27 | |||
| 28 | /// Certain nodes are placed in this set under the following conditions: | ||
| 29 | /// * if-else: either branch consumes the result location | ||
| 30 | /// * labeled block: any break consumes the result location | ||
| 31 | /// * switch: any prong consumes the result location | ||
| 32 | /// * orelse/catch: the RHS expression consumes the result location | ||
| 33 | /// * while/for: any break consumes the result location | ||
| 34 | /// * @as: the second operand consumes the result location | ||
| 35 | /// * const: the init expression consumes the result location | ||
| 36 | /// * return: the return expression consumes the result location | ||
| 37 | nodes_need_rl: RlNeededSet = .{}, | ||
| 38 | |||
| 39 | pub const RlNeededSet = AutoHashMapUnmanaged(Ast.Node.Index, void); | ||
| 40 | |||
| 41 | const ResultInfo = packed struct { | ||
| 42 | /// Do we have a known result type? | ||
| 43 | have_type: bool, | ||
| 44 | /// Do we (potentially) have a result pointer? Note that this pointer's type | ||
| 45 | /// may not be known due to it being an inferred alloc. | ||
| 46 | have_ptr: bool, | ||
| 47 | |||
| 48 | const none: ResultInfo = .{ .have_type = false, .have_ptr = false }; | ||
| 49 | const typed_ptr: ResultInfo = .{ .have_type = true, .have_ptr = true }; | ||
| 50 | const inferred_ptr: ResultInfo = .{ .have_type = false, .have_ptr = true }; | ||
| 51 | const type_only: ResultInfo = .{ .have_type = true, .have_ptr = false }; | ||
| 52 | }; | ||
| 53 | |||
| 54 | /// A labeled block or a loop. When this block is broken from, `consumes_res_ptr` | ||
| 55 | /// should be set if the break expression consumed the result pointer. | ||
| 56 | const Block = struct { | ||
| 57 | parent: ?*Block, | ||
| 58 | label: ?[]const u8, | ||
| 59 | is_loop: bool, | ||
| 60 | ri: ResultInfo, | ||
| 61 | consumes_res_ptr: bool, | ||
| 62 | }; | ||
| 63 | |||
| 64 | pub fn annotate(gpa: Allocator, arena: Allocator, tree: Ast) Allocator.Error!RlNeededSet { | ||
| 65 | var astrl: AstRlAnnotate = .{ | ||
| 66 | .gpa = gpa, | ||
| 67 | .arena = arena, | ||
| 68 | .tree = &tree, | ||
| 69 | }; | ||
| 70 | defer astrl.deinit(gpa); | ||
| 71 | |||
| 72 | if (tree.errors.len != 0) { | ||
| 73 | // We can't perform analysis on a broken AST. AstGen will not run in | ||
| 74 | // this case. | ||
| 75 | return .{}; | ||
| 76 | } | ||
| 77 | |||
| 78 | for (tree.containerDeclRoot().ast.members) |member_node| { | ||
| 79 | _ = try astrl.expr(member_node, null, ResultInfo.none); | ||
| 80 | } | ||
| 81 | |||
| 82 | return astrl.nodes_need_rl.move(); | ||
| 83 | } | ||
| 84 | |||
| 85 | fn deinit(astrl: *AstRlAnnotate, gpa: Allocator) void { | ||
| 86 | astrl.nodes_need_rl.deinit(gpa); | ||
| 87 | } | ||
| 88 | |||
| 89 | fn containerDecl( | ||
| 90 | astrl: *AstRlAnnotate, | ||
| 91 | block: ?*Block, | ||
| 92 | full: Ast.full.ContainerDecl, | ||
| 93 | ) !void { | ||
| 94 | const tree = astrl.tree; | ||
| 95 | const token_tags = tree.tokens.items(.tag); | ||
| 96 | switch (token_tags[full.ast.main_token]) { | ||
| 97 | .keyword_struct => { | ||
| 98 | if (full.ast.arg != 0) { | ||
| 99 | _ = try astrl.expr(full.ast.arg, block, ResultInfo.type_only); | ||
| 100 | } | ||
| 101 | for (full.ast.members) |member_node| { | ||
| 102 | _ = try astrl.expr(member_node, block, ResultInfo.none); | ||
| 103 | } | ||
| 104 | }, | ||
| 105 | .keyword_union => { | ||
| 106 | if (full.ast.arg != 0) { | ||
| 107 | _ = try astrl.expr(full.ast.arg, block, ResultInfo.type_only); | ||
| 108 | } | ||
| 109 | for (full.ast.members) |member_node| { | ||
| 110 | _ = try astrl.expr(member_node, block, ResultInfo.none); | ||
| 111 | } | ||
| 112 | }, | ||
| 113 | .keyword_enum => { | ||
| 114 | if (full.ast.arg != 0) { | ||
| 115 | _ = try astrl.expr(full.ast.arg, block, ResultInfo.type_only); | ||
| 116 | } | ||
| 117 | for (full.ast.members) |member_node| { | ||
| 118 | _ = try astrl.expr(member_node, block, ResultInfo.none); | ||
| 119 | } | ||
| 120 | }, | ||
| 121 | .keyword_opaque => { | ||
| 122 | for (full.ast.members) |member_node| { | ||
| 123 | _ = try astrl.expr(member_node, block, ResultInfo.none); | ||
| 124 | } | ||
| 125 | }, | ||
| 126 | else => unreachable, | ||
| 127 | } | ||
| 128 | } | ||
| 129 | |||
| 130 | /// Returns true if `rl` provides a result pointer and the expression consumes it. | ||
| 131 | fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultInfo) Allocator.Error!bool { | ||
| 132 | const tree = astrl.tree; | ||
| 133 | const token_tags = tree.tokens.items(.tag); | ||
| 134 | const node_datas = tree.nodes.items(.data); | ||
| 135 | const node_tags = tree.nodes.items(.tag); | ||
| 136 | switch (node_tags[node]) { | ||
| 137 | .root, | ||
| 138 | .switch_case_one, | ||
| 139 | .switch_case_inline_one, | ||
| 140 | .switch_case, | ||
| 141 | .switch_case_inline, | ||
| 142 | .switch_range, | ||
| 143 | .for_range, | ||
| 144 | .asm_output, | ||
| 145 | .asm_input, | ||
| 146 | => unreachable, | ||
| 147 | |||
| 148 | .@"errdefer", .@"defer" => { | ||
| 149 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.none); | ||
| 150 | return false; | ||
| 151 | }, | ||
| 152 | |||
| 153 | .container_field_init, | ||
| 154 | .container_field_align, | ||
| 155 | .container_field, | ||
| 156 | => { | ||
| 157 | const full = tree.fullContainerField(node).?; | ||
| 158 | _ = try astrl.expr(full.ast.type_expr, block, ResultInfo.type_only); | ||
| 159 | if (full.ast.align_expr != 0) { | ||
| 160 | _ = try astrl.expr(full.ast.align_expr, block, ResultInfo.type_only); | ||
| 161 | } | ||
| 162 | if (full.ast.value_expr != 0) { | ||
| 163 | _ = try astrl.expr(full.ast.value_expr, block, ResultInfo.type_only); | ||
| 164 | } | ||
| 165 | return false; | ||
| 166 | }, | ||
| 167 | .@"usingnamespace" => { | ||
| 168 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.type_only); | ||
| 169 | return false; | ||
| 170 | }, | ||
| 171 | .test_decl => { | ||
| 172 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.none); | ||
| 173 | return false; | ||
| 174 | }, | ||
| 175 | .global_var_decl, | ||
| 176 | .local_var_decl, | ||
| 177 | .simple_var_decl, | ||
| 178 | .aligned_var_decl, | ||
| 179 | => { | ||
| 180 | const full = tree.fullVarDecl(node).?; | ||
| 181 | const init_ri = if (full.ast.type_node != 0) init_ri: { | ||
| 182 | _ = try astrl.expr(full.ast.type_node, block, ResultInfo.type_only); | ||
| 183 | break :init_ri ResultInfo.typed_ptr; | ||
| 184 | } else ResultInfo.inferred_ptr; | ||
| 185 | if (full.ast.init_node == 0) { | ||
| 186 | // No init node, so we're done. | ||
| 187 | return false; | ||
| 188 | } | ||
| 189 | switch (token_tags[full.ast.mut_token]) { | ||
| 190 | .keyword_const => { | ||
| 191 | const init_consumes_rl = try astrl.expr(full.ast.init_node, block, init_ri); | ||
| 192 | if (init_consumes_rl) { | ||
| 193 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | ||
| 194 | } | ||
| 195 | return false; | ||
| 196 | }, | ||
| 197 | .keyword_var => { | ||
| 198 | // We'll create an alloc either way, so don't care if the | ||
| 199 | // result pointer is consumed. | ||
| 200 | _ = try astrl.expr(full.ast.init_node, block, init_ri); | ||
| 201 | return false; | ||
| 202 | }, | ||
| 203 | else => unreachable, | ||
| 204 | } | ||
| 205 | }, | ||
| 206 | .assign_destructure => { | ||
| 207 | const lhs_count = tree.extra_data[node_datas[node].lhs]; | ||
| 208 | const all_lhs = tree.extra_data[node_datas[node].lhs + 1 ..][0..lhs_count]; | ||
| 209 | for (all_lhs) |lhs| { | ||
| 210 | _ = try astrl.expr(lhs, block, ResultInfo.none); | ||
| 211 | } | ||
| 212 | // We don't need to gather any meaningful data here, because destructures always use RLS | ||
| 213 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.none); | ||
| 214 | return false; | ||
| 215 | }, | ||
| 216 | .assign => { | ||
| 217 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 218 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.typed_ptr); | ||
| 219 | return false; | ||
| 220 | }, | ||
| 221 | .assign_shl, | ||
| 222 | .assign_shl_sat, | ||
| 223 | .assign_shr, | ||
| 224 | .assign_bit_and, | ||
| 225 | .assign_bit_or, | ||
| 226 | .assign_bit_xor, | ||
| 227 | .assign_div, | ||
| 228 | .assign_sub, | ||
| 229 | .assign_sub_wrap, | ||
| 230 | .assign_sub_sat, | ||
| 231 | .assign_mod, | ||
| 232 | .assign_add, | ||
| 233 | .assign_add_wrap, | ||
| 234 | .assign_add_sat, | ||
| 235 | .assign_mul, | ||
| 236 | .assign_mul_wrap, | ||
| 237 | .assign_mul_sat, | ||
| 238 | => { | ||
| 239 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 240 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.none); | ||
| 241 | return false; | ||
| 242 | }, | ||
| 243 | .shl, .shr => { | ||
| 244 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 245 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.type_only); | ||
| 246 | return false; | ||
| 247 | }, | ||
| 248 | .add, | ||
| 249 | .add_wrap, | ||
| 250 | .add_sat, | ||
| 251 | .sub, | ||
| 252 | .sub_wrap, | ||
| 253 | .sub_sat, | ||
| 254 | .mul, | ||
| 255 | .mul_wrap, | ||
| 256 | .mul_sat, | ||
| 257 | .div, | ||
| 258 | .mod, | ||
| 259 | .shl_sat, | ||
| 260 | .bit_and, | ||
| 261 | .bit_or, | ||
| 262 | .bit_xor, | ||
| 263 | .bang_equal, | ||
| 264 | .equal_equal, | ||
| 265 | .greater_than, | ||
| 266 | .greater_or_equal, | ||
| 267 | .less_than, | ||
| 268 | .less_or_equal, | ||
| 269 | .array_cat, | ||
| 270 | => { | ||
| 271 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 272 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.none); | ||
| 273 | return false; | ||
| 274 | }, | ||
| 275 | .array_mult => { | ||
| 276 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 277 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.type_only); | ||
| 278 | return false; | ||
| 279 | }, | ||
| 280 | .error_union, .merge_error_sets => { | ||
| 281 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 282 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.none); | ||
| 283 | return false; | ||
| 284 | }, | ||
| 285 | .bool_and, | ||
| 286 | .bool_or, | ||
| 287 | => { | ||
| 288 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.type_only); | ||
| 289 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.type_only); | ||
| 290 | return false; | ||
| 291 | }, | ||
| 292 | .bool_not => { | ||
| 293 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.type_only); | ||
| 294 | return false; | ||
| 295 | }, | ||
| 296 | .bit_not, .negation, .negation_wrap => { | ||
| 297 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 298 | return false; | ||
| 299 | }, | ||
| 300 | |||
| 301 | // These nodes are leaves and never consume a result location. | ||
| 302 | .identifier, | ||
| 303 | .string_literal, | ||
| 304 | .multiline_string_literal, | ||
| 305 | .number_literal, | ||
| 306 | .unreachable_literal, | ||
| 307 | .asm_simple, | ||
| 308 | .@"asm", | ||
| 309 | .enum_literal, | ||
| 310 | .error_value, | ||
| 311 | .anyframe_literal, | ||
| 312 | .@"continue", | ||
| 313 | .char_literal, | ||
| 314 | .error_set_decl, | ||
| 315 | => return false, | ||
| 316 | |||
| 317 | .builtin_call_two, .builtin_call_two_comma => { | ||
| 318 | if (node_datas[node].lhs == 0) { | ||
| 319 | return astrl.builtinCall(block, ri, node, &.{}); | ||
| 320 | } else if (node_datas[node].rhs == 0) { | ||
| 321 | return astrl.builtinCall(block, ri, node, &.{node_datas[node].lhs}); | ||
| 322 | } else { | ||
| 323 | return astrl.builtinCall(block, ri, node, &.{ node_datas[node].lhs, node_datas[node].rhs }); | ||
| 324 | } | ||
| 325 | }, | ||
| 326 | .builtin_call, .builtin_call_comma => { | ||
| 327 | const params = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs]; | ||
| 328 | return astrl.builtinCall(block, ri, node, params); | ||
| 329 | }, | ||
| 330 | |||
| 331 | .call_one, | ||
| 332 | .call_one_comma, | ||
| 333 | .async_call_one, | ||
| 334 | .async_call_one_comma, | ||
| 335 | .call, | ||
| 336 | .call_comma, | ||
| 337 | .async_call, | ||
| 338 | .async_call_comma, | ||
| 339 | => { | ||
| 340 | var buf: [1]Ast.Node.Index = undefined; | ||
| 341 | const full = tree.fullCall(&buf, node).?; | ||
| 342 | _ = try astrl.expr(full.ast.fn_expr, block, ResultInfo.none); | ||
| 343 | for (full.ast.params) |param_node| { | ||
| 344 | _ = try astrl.expr(param_node, block, ResultInfo.type_only); | ||
| 345 | } | ||
| 346 | return switch (node_tags[node]) { | ||
| 347 | .call_one, | ||
| 348 | .call_one_comma, | ||
| 349 | .call, | ||
| 350 | .call_comma, | ||
| 351 | => false, // TODO: once function calls are passed result locations this will change | ||
| 352 | .async_call_one, | ||
| 353 | .async_call_one_comma, | ||
| 354 | .async_call, | ||
| 355 | .async_call_comma, | ||
| 356 | => ri.have_ptr, // always use result ptr for frames | ||
| 357 | else => unreachable, | ||
| 358 | }; | ||
| 359 | }, | ||
| 360 | |||
| 361 | .@"return" => { | ||
| 362 | if (node_datas[node].lhs != 0) { | ||
| 363 | const ret_val_consumes_rl = try astrl.expr(node_datas[node].lhs, block, ResultInfo.typed_ptr); | ||
| 364 | if (ret_val_consumes_rl) { | ||
| 365 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | ||
| 366 | } | ||
| 367 | } | ||
| 368 | return false; | ||
| 369 | }, | ||
| 370 | |||
| 371 | .field_access => { | ||
| 372 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 373 | return false; | ||
| 374 | }, | ||
| 375 | |||
| 376 | .if_simple, .@"if" => { | ||
| 377 | const full = tree.fullIf(node).?; | ||
| 378 | if (full.error_token != null or full.payload_token != null) { | ||
| 379 | _ = try astrl.expr(full.ast.cond_expr, block, ResultInfo.none); | ||
| 380 | } else { | ||
| 381 | _ = try astrl.expr(full.ast.cond_expr, block, ResultInfo.type_only); // bool | ||
| 382 | } | ||
| 383 | |||
| 384 | if (full.ast.else_expr == 0) { | ||
| 385 | _ = try astrl.expr(full.ast.then_expr, block, ResultInfo.none); | ||
| 386 | return false; | ||
| 387 | } else { | ||
| 388 | const then_uses_rl = try astrl.expr(full.ast.then_expr, block, ri); | ||
| 389 | const else_uses_rl = try astrl.expr(full.ast.else_expr, block, ri); | ||
| 390 | const uses_rl = then_uses_rl or else_uses_rl; | ||
| 391 | if (uses_rl) try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | ||
| 392 | return uses_rl; | ||
| 393 | } | ||
| 394 | }, | ||
| 395 | |||
| 396 | .while_simple, .while_cont, .@"while" => { | ||
| 397 | const full = tree.fullWhile(node).?; | ||
| 398 | const label: ?[]const u8 = if (full.label_token) |label_token| label: { | ||
| 399 | break :label try astrl.identString(label_token); | ||
| 400 | } else null; | ||
| 401 | if (full.error_token != null or full.payload_token != null) { | ||
| 402 | _ = try astrl.expr(full.ast.cond_expr, block, ResultInfo.none); | ||
| 403 | } else { | ||
| 404 | _ = try astrl.expr(full.ast.cond_expr, block, ResultInfo.type_only); // bool | ||
| 405 | } | ||
| 406 | var new_block: Block = .{ | ||
| 407 | .parent = block, | ||
| 408 | .label = label, | ||
| 409 | .is_loop = true, | ||
| 410 | .ri = ri, | ||
| 411 | .consumes_res_ptr = false, | ||
| 412 | }; | ||
| 413 | if (full.ast.cont_expr != 0) { | ||
| 414 | _ = try astrl.expr(full.ast.cont_expr, &new_block, ResultInfo.none); | ||
| 415 | } | ||
| 416 | _ = try astrl.expr(full.ast.then_expr, &new_block, ResultInfo.none); | ||
| 417 | const else_consumes_rl = if (full.ast.else_expr != 0) else_rl: { | ||
| 418 | break :else_rl try astrl.expr(full.ast.else_expr, block, ri); | ||
| 419 | } else false; | ||
| 420 | if (new_block.consumes_res_ptr or else_consumes_rl) { | ||
| 421 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | ||
| 422 | return true; | ||
| 423 | } else { | ||
| 424 | return false; | ||
| 425 | } | ||
| 426 | }, | ||
| 427 | |||
| 428 | .for_simple, .@"for" => { | ||
| 429 | const full = tree.fullFor(node).?; | ||
| 430 | const label: ?[]const u8 = if (full.label_token) |label_token| label: { | ||
| 431 | break :label try astrl.identString(label_token); | ||
| 432 | } else null; | ||
| 433 | for (full.ast.inputs) |input| { | ||
| 434 | if (node_tags[input] == .for_range) { | ||
| 435 | _ = try astrl.expr(node_datas[input].lhs, block, ResultInfo.type_only); | ||
| 436 | if (node_datas[input].rhs != 0) { | ||
| 437 | _ = try astrl.expr(node_datas[input].rhs, block, ResultInfo.type_only); | ||
| 438 | } | ||
| 439 | } else { | ||
| 440 | _ = try astrl.expr(input, block, ResultInfo.none); | ||
| 441 | } | ||
| 442 | } | ||
| 443 | var new_block: Block = .{ | ||
| 444 | .parent = block, | ||
| 445 | .label = label, | ||
| 446 | .is_loop = true, | ||
| 447 | .ri = ri, | ||
| 448 | .consumes_res_ptr = false, | ||
| 449 | }; | ||
| 450 | _ = try astrl.expr(full.ast.then_expr, &new_block, ResultInfo.none); | ||
| 451 | const else_consumes_rl = if (full.ast.else_expr != 0) else_rl: { | ||
| 452 | break :else_rl try astrl.expr(full.ast.else_expr, block, ri); | ||
| 453 | } else false; | ||
| 454 | if (new_block.consumes_res_ptr or else_consumes_rl) { | ||
| 455 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | ||
| 456 | return true; | ||
| 457 | } else { | ||
| 458 | return false; | ||
| 459 | } | ||
| 460 | }, | ||
| 461 | |||
| 462 | .slice_open => { | ||
| 463 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 464 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.type_only); | ||
| 465 | return false; | ||
| 466 | }, | ||
| 467 | .slice => { | ||
| 468 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.Slice); | ||
| 469 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 470 | _ = try astrl.expr(extra.start, block, ResultInfo.type_only); | ||
| 471 | _ = try astrl.expr(extra.end, block, ResultInfo.type_only); | ||
| 472 | return false; | ||
| 473 | }, | ||
| 474 | .slice_sentinel => { | ||
| 475 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.SliceSentinel); | ||
| 476 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 477 | _ = try astrl.expr(extra.start, block, ResultInfo.type_only); | ||
| 478 | if (extra.end != 0) { | ||
| 479 | _ = try astrl.expr(extra.end, block, ResultInfo.type_only); | ||
| 480 | } | ||
| 481 | _ = try astrl.expr(extra.sentinel, block, ResultInfo.none); | ||
| 482 | return false; | ||
| 483 | }, | ||
| 484 | .deref => { | ||
| 485 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 486 | return false; | ||
| 487 | }, | ||
| 488 | .address_of => { | ||
| 489 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 490 | return false; | ||
| 491 | }, | ||
| 492 | .optional_type => { | ||
| 493 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.type_only); | ||
| 494 | return false; | ||
| 495 | }, | ||
| 496 | .grouped_expression, | ||
| 497 | .@"try", | ||
| 498 | .@"await", | ||
| 499 | .@"nosuspend", | ||
| 500 | .unwrap_optional, | ||
| 501 | => return astrl.expr(node_datas[node].lhs, block, ri), | ||
| 502 | |||
| 503 | .block_two, .block_two_semicolon => { | ||
| 504 | if (node_datas[node].lhs == 0) { | ||
| 505 | return astrl.blockExpr(block, ri, node, &.{}); | ||
| 506 | } else if (node_datas[node].rhs == 0) { | ||
| 507 | return astrl.blockExpr(block, ri, node, &.{node_datas[node].lhs}); | ||
| 508 | } else { | ||
| 509 | return astrl.blockExpr(block, ri, node, &.{ node_datas[node].lhs, node_datas[node].rhs }); | ||
| 510 | } | ||
| 511 | }, | ||
| 512 | .block, .block_semicolon => { | ||
| 513 | const statements = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs]; | ||
| 514 | return astrl.blockExpr(block, ri, node, statements); | ||
| 515 | }, | ||
| 516 | .anyframe_type => { | ||
| 517 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.type_only); | ||
| 518 | return false; | ||
| 519 | }, | ||
| 520 | .@"catch", .@"orelse" => { | ||
| 521 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 522 | const rhs_consumes_rl = try astrl.expr(node_datas[node].rhs, block, ri); | ||
| 523 | if (rhs_consumes_rl) { | ||
| 524 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | ||
| 525 | } | ||
| 526 | return rhs_consumes_rl; | ||
| 527 | }, | ||
| 528 | |||
| 529 | .ptr_type_aligned, | ||
| 530 | .ptr_type_sentinel, | ||
| 531 | .ptr_type, | ||
| 532 | .ptr_type_bit_range, | ||
| 533 | => { | ||
| 534 | const full = tree.fullPtrType(node).?; | ||
| 535 | _ = try astrl.expr(full.ast.child_type, block, ResultInfo.type_only); | ||
| 536 | if (full.ast.sentinel != 0) { | ||
| 537 | _ = try astrl.expr(full.ast.sentinel, block, ResultInfo.type_only); | ||
| 538 | } | ||
| 539 | if (full.ast.addrspace_node != 0) { | ||
| 540 | _ = try astrl.expr(full.ast.addrspace_node, block, ResultInfo.type_only); | ||
| 541 | } | ||
| 542 | if (full.ast.align_node != 0) { | ||
| 543 | _ = try astrl.expr(full.ast.align_node, block, ResultInfo.type_only); | ||
| 544 | } | ||
| 545 | if (full.ast.bit_range_start != 0) { | ||
| 546 | assert(full.ast.bit_range_end != 0); | ||
| 547 | _ = try astrl.expr(full.ast.bit_range_start, block, ResultInfo.type_only); | ||
| 548 | _ = try astrl.expr(full.ast.bit_range_end, block, ResultInfo.type_only); | ||
| 549 | } | ||
| 550 | return false; | ||
| 551 | }, | ||
| 552 | |||
| 553 | .container_decl, | ||
| 554 | .container_decl_trailing, | ||
| 555 | .container_decl_arg, | ||
| 556 | .container_decl_arg_trailing, | ||
| 557 | .container_decl_two, | ||
| 558 | .container_decl_two_trailing, | ||
| 559 | .tagged_union, | ||
| 560 | .tagged_union_trailing, | ||
| 561 | .tagged_union_enum_tag, | ||
| 562 | .tagged_union_enum_tag_trailing, | ||
| 563 | .tagged_union_two, | ||
| 564 | .tagged_union_two_trailing, | ||
| 565 | => { | ||
| 566 | var buf: [2]Ast.Node.Index = undefined; | ||
| 567 | try astrl.containerDecl(block, tree.fullContainerDecl(&buf, node).?); | ||
| 568 | return false; | ||
| 569 | }, | ||
| 570 | |||
| 571 | .@"break" => { | ||
| 572 | if (node_datas[node].rhs == 0) { | ||
| 573 | // Breaks with void are not interesting | ||
| 574 | return false; | ||
| 575 | } | ||
| 576 | |||
| 577 | var opt_cur_block = block; | ||
| 578 | if (node_datas[node].lhs == 0) { | ||
| 579 | // No label - we're breaking from a loop. | ||
| 580 | while (opt_cur_block) |cur_block| : (opt_cur_block = cur_block.parent) { | ||
| 581 | if (cur_block.is_loop) break; | ||
| 582 | } | ||
| 583 | } else { | ||
| 584 | const break_label = try astrl.identString(node_datas[node].lhs); | ||
| 585 | while (opt_cur_block) |cur_block| : (opt_cur_block = cur_block.parent) { | ||
| 586 | const block_label = cur_block.label orelse continue; | ||
| 587 | if (std.mem.eql(u8, block_label, break_label)) break; | ||
| 588 | } | ||
| 589 | } | ||
| 590 | |||
| 591 | if (opt_cur_block) |target_block| { | ||
| 592 | const consumes_break_rl = try astrl.expr(node_datas[node].rhs, block, target_block.ri); | ||
| 593 | if (consumes_break_rl) target_block.consumes_res_ptr = true; | ||
| 594 | } else { | ||
| 595 | // No corresponding scope to break from - AstGen will emit an error. | ||
| 596 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.none); | ||
| 597 | } | ||
| 598 | |||
| 599 | return false; | ||
| 600 | }, | ||
| 601 | |||
| 602 | .array_type => { | ||
| 603 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.type_only); | ||
| 604 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.type_only); | ||
| 605 | return false; | ||
| 606 | }, | ||
| 607 | .array_type_sentinel => { | ||
| 608 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.ArrayTypeSentinel); | ||
| 609 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.type_only); | ||
| 610 | _ = try astrl.expr(extra.elem_type, block, ResultInfo.type_only); | ||
| 611 | _ = try astrl.expr(extra.sentinel, block, ResultInfo.type_only); | ||
| 612 | return false; | ||
| 613 | }, | ||
| 614 | .array_access => { | ||
| 615 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 616 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.type_only); | ||
| 617 | return false; | ||
| 618 | }, | ||
| 619 | .@"comptime" => { | ||
| 620 | // AstGen will emit an error if the scope is already comptime, so we can assume it is | ||
| 621 | // not. This means the result location is not forwarded. | ||
| 622 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 623 | return false; | ||
| 624 | }, | ||
| 625 | .@"switch", .switch_comma => { | ||
| 626 | const operand_node = node_datas[node].lhs; | ||
| 627 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.SubRange); | ||
| 628 | const case_nodes = tree.extra_data[extra.start..extra.end]; | ||
| 629 | |||
| 630 | _ = try astrl.expr(operand_node, block, ResultInfo.none); | ||
| 631 | |||
| 632 | var any_prong_consumed_rl = false; | ||
| 633 | for (case_nodes) |case_node| { | ||
| 634 | const case = tree.fullSwitchCase(case_node).?; | ||
| 635 | for (case.ast.values) |item_node| { | ||
| 636 | if (node_tags[item_node] == .switch_range) { | ||
| 637 | _ = try astrl.expr(node_datas[item_node].lhs, block, ResultInfo.none); | ||
| 638 | _ = try astrl.expr(node_datas[item_node].rhs, block, ResultInfo.none); | ||
| 639 | } else { | ||
| 640 | _ = try astrl.expr(item_node, block, ResultInfo.none); | ||
| 641 | } | ||
| 642 | } | ||
| 643 | if (try astrl.expr(case.ast.target_expr, block, ri)) { | ||
| 644 | any_prong_consumed_rl = true; | ||
| 645 | } | ||
| 646 | } | ||
| 647 | if (any_prong_consumed_rl) { | ||
| 648 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | ||
| 649 | } | ||
| 650 | return any_prong_consumed_rl; | ||
| 651 | }, | ||
| 652 | .@"suspend" => { | ||
| 653 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 654 | return false; | ||
| 655 | }, | ||
| 656 | .@"resume" => { | ||
| 657 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 658 | return false; | ||
| 659 | }, | ||
| 660 | |||
| 661 | .array_init_one, | ||
| 662 | .array_init_one_comma, | ||
| 663 | .array_init_dot_two, | ||
| 664 | .array_init_dot_two_comma, | ||
| 665 | .array_init_dot, | ||
| 666 | .array_init_dot_comma, | ||
| 667 | .array_init, | ||
| 668 | .array_init_comma, | ||
| 669 | => { | ||
| 670 | var buf: [2]Ast.Node.Index = undefined; | ||
| 671 | const full = tree.fullArrayInit(&buf, node).?; | ||
| 672 | |||
| 673 | if (full.ast.type_expr != 0) { | ||
| 674 | // Explicitly typed init does not participate in RLS | ||
| 675 | _ = try astrl.expr(full.ast.type_expr, block, ResultInfo.none); | ||
| 676 | for (full.ast.elements) |elem_init| { | ||
| 677 | _ = try astrl.expr(elem_init, block, ResultInfo.type_only); | ||
| 678 | } | ||
| 679 | return false; | ||
| 680 | } | ||
| 681 | |||
| 682 | if (ri.have_type) { | ||
| 683 | // Always forward type information | ||
| 684 | // If we have a result pointer, we use and forward it | ||
| 685 | for (full.ast.elements) |elem_init| { | ||
| 686 | _ = try astrl.expr(elem_init, block, ri); | ||
| 687 | } | ||
| 688 | return ri.have_ptr; | ||
| 689 | } else { | ||
| 690 | // Untyped init does not consume result location | ||
| 691 | for (full.ast.elements) |elem_init| { | ||
| 692 | _ = try astrl.expr(elem_init, block, ResultInfo.none); | ||
| 693 | } | ||
| 694 | return false; | ||
| 695 | } | ||
| 696 | }, | ||
| 697 | |||
| 698 | .struct_init_one, | ||
| 699 | .struct_init_one_comma, | ||
| 700 | .struct_init_dot_two, | ||
| 701 | .struct_init_dot_two_comma, | ||
| 702 | .struct_init_dot, | ||
| 703 | .struct_init_dot_comma, | ||
| 704 | .struct_init, | ||
| 705 | .struct_init_comma, | ||
| 706 | => { | ||
| 707 | var buf: [2]Ast.Node.Index = undefined; | ||
| 708 | const full = tree.fullStructInit(&buf, node).?; | ||
| 709 | |||
| 710 | if (full.ast.type_expr != 0) { | ||
| 711 | // Explicitly typed init does not participate in RLS | ||
| 712 | _ = try astrl.expr(full.ast.type_expr, block, ResultInfo.none); | ||
| 713 | for (full.ast.fields) |field_init| { | ||
| 714 | _ = try astrl.expr(field_init, block, ResultInfo.type_only); | ||
| 715 | } | ||
| 716 | return false; | ||
| 717 | } | ||
| 718 | |||
| 719 | if (ri.have_type) { | ||
| 720 | // Always forward type information | ||
| 721 | // If we have a result pointer, we use and forward it | ||
| 722 | for (full.ast.fields) |field_init| { | ||
| 723 | _ = try astrl.expr(field_init, block, ri); | ||
| 724 | } | ||
| 725 | return ri.have_ptr; | ||
| 726 | } else { | ||
| 727 | // Untyped init does not consume result location | ||
| 728 | for (full.ast.fields) |field_init| { | ||
| 729 | _ = try astrl.expr(field_init, block, ResultInfo.none); | ||
| 730 | } | ||
| 731 | return false; | ||
| 732 | } | ||
| 733 | }, | ||
| 734 | |||
| 735 | .fn_proto_simple, | ||
| 736 | .fn_proto_multi, | ||
| 737 | .fn_proto_one, | ||
| 738 | .fn_proto, | ||
| 739 | .fn_decl, | ||
| 740 | => { | ||
| 741 | var buf: [1]Ast.Node.Index = undefined; | ||
| 742 | const full = tree.fullFnProto(&buf, node).?; | ||
| 743 | const body_node = if (node_tags[node] == .fn_decl) node_datas[node].rhs else 0; | ||
| 744 | { | ||
| 745 | var it = full.iterate(tree); | ||
| 746 | while (it.next()) |param| { | ||
| 747 | if (param.anytype_ellipsis3 == null) { | ||
| 748 | _ = try astrl.expr(param.type_expr, block, ResultInfo.type_only); | ||
| 749 | } | ||
| 750 | } | ||
| 751 | } | ||
| 752 | if (full.ast.align_expr != 0) { | ||
| 753 | _ = try astrl.expr(full.ast.align_expr, block, ResultInfo.type_only); | ||
| 754 | } | ||
| 755 | if (full.ast.addrspace_expr != 0) { | ||
| 756 | _ = try astrl.expr(full.ast.addrspace_expr, block, ResultInfo.type_only); | ||
| 757 | } | ||
| 758 | if (full.ast.section_expr != 0) { | ||
| 759 | _ = try astrl.expr(full.ast.section_expr, block, ResultInfo.type_only); | ||
| 760 | } | ||
| 761 | if (full.ast.callconv_expr != 0) { | ||
| 762 | _ = try astrl.expr(full.ast.callconv_expr, block, ResultInfo.type_only); | ||
| 763 | } | ||
| 764 | _ = try astrl.expr(full.ast.return_type, block, ResultInfo.type_only); | ||
| 765 | if (body_node != 0) { | ||
| 766 | _ = try astrl.expr(body_node, block, ResultInfo.none); | ||
| 767 | } | ||
| 768 | return false; | ||
| 769 | }, | ||
| 770 | } | ||
| 771 | } | ||
| 772 | |||
| 773 | fn identString(astrl: *AstRlAnnotate, token: Ast.TokenIndex) ![]const u8 { | ||
| 774 | const tree = astrl.tree; | ||
| 775 | const token_tags = tree.tokens.items(.tag); | ||
| 776 | assert(token_tags[token] == .identifier); | ||
| 777 | const ident_name = tree.tokenSlice(token); | ||
| 778 | if (!std.mem.startsWith(u8, ident_name, "@")) { | ||
| 779 | return ident_name; | ||
| 780 | } | ||
| 781 | return std.zig.string_literal.parseAlloc(astrl.arena, ident_name[1..]) catch |err| switch (err) { | ||
| 782 | error.OutOfMemory => error.OutOfMemory, | ||
| 783 | error.InvalidLiteral => "", // This pass can safely return garbage on invalid AST | ||
| 784 | }; | ||
| 785 | } | ||
| 786 | |||
| 787 | fn blockExpr(astrl: *AstRlAnnotate, parent_block: ?*Block, ri: ResultInfo, node: Ast.Node.Index, statements: []const Ast.Node.Index) !bool { | ||
| 788 | const tree = astrl.tree; | ||
| 789 | const token_tags = tree.tokens.items(.tag); | ||
| 790 | const main_tokens = tree.nodes.items(.main_token); | ||
| 791 | |||
| 792 | const lbrace = main_tokens[node]; | ||
| 793 | if (token_tags[lbrace - 1] == .colon and | ||
| 794 | token_tags[lbrace - 2] == .identifier) | ||
| 795 | { | ||
| 796 | // Labeled block | ||
| 797 | var new_block: Block = .{ | ||
| 798 | .parent = parent_block, | ||
| 799 | .label = try astrl.identString(lbrace - 2), | ||
| 800 | .is_loop = false, | ||
| 801 | .ri = ri, | ||
| 802 | .consumes_res_ptr = false, | ||
| 803 | }; | ||
| 804 | for (statements) |statement| { | ||
| 805 | _ = try astrl.expr(statement, &new_block, ResultInfo.none); | ||
| 806 | } | ||
| 807 | if (new_block.consumes_res_ptr) { | ||
| 808 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | ||
| 809 | } | ||
| 810 | return new_block.consumes_res_ptr; | ||
| 811 | } else { | ||
| 812 | // Unlabeled block | ||
| 813 | for (statements) |statement| { | ||
| 814 | _ = try astrl.expr(statement, parent_block, ResultInfo.none); | ||
| 815 | } | ||
| 816 | return false; | ||
| 817 | } | ||
| 818 | } | ||
| 819 | |||
| 820 | fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast.Node.Index, args: []const Ast.Node.Index) !bool { | ||
| 821 | _ = ri; // Currently, no builtin consumes its result location. | ||
| 822 | |||
| 823 | const tree = astrl.tree; | ||
| 824 | const main_tokens = tree.nodes.items(.main_token); | ||
| 825 | const builtin_token = main_tokens[node]; | ||
| 826 | const builtin_name = tree.tokenSlice(builtin_token); | ||
| 827 | const info = BuiltinFn.list.get(builtin_name) orelse return false; | ||
| 828 | if (info.param_count) |expected| { | ||
| 829 | if (expected != args.len) return false; | ||
| 830 | } | ||
| 831 | switch (info.tag) { | ||
| 832 | .import => return false, | ||
| 833 | .compile_log, .TypeOf => { | ||
| 834 | for (args) |arg_node| { | ||
| 835 | _ = try astrl.expr(arg_node, block, ResultInfo.none); | ||
| 836 | } | ||
| 837 | return false; | ||
| 838 | }, | ||
| 839 | .as => { | ||
| 840 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 841 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 842 | return false; | ||
| 843 | }, | ||
| 844 | .bit_cast => { | ||
| 845 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 846 | return false; | ||
| 847 | }, | ||
| 848 | .union_init => { | ||
| 849 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 850 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 851 | _ = try astrl.expr(args[2], block, ResultInfo.type_only); | ||
| 852 | return false; | ||
| 853 | }, | ||
| 854 | .c_import => { | ||
| 855 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 856 | return false; | ||
| 857 | }, | ||
| 858 | .min, .max => { | ||
| 859 | for (args) |arg_node| { | ||
| 860 | _ = try astrl.expr(arg_node, block, ResultInfo.none); | ||
| 861 | } | ||
| 862 | return false; | ||
| 863 | }, | ||
| 864 | .@"export" => { | ||
| 865 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 866 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 867 | return false; | ||
| 868 | }, | ||
| 869 | .@"extern" => { | ||
| 870 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 871 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 872 | return false; | ||
| 873 | }, | ||
| 874 | // These builtins take no args and do not consume the result pointer. | ||
| 875 | .src, | ||
| 876 | .This, | ||
| 877 | .return_address, | ||
| 878 | .error_return_trace, | ||
| 879 | .frame, | ||
| 880 | .breakpoint, | ||
| 881 | .in_comptime, | ||
| 882 | .panic, | ||
| 883 | .trap, | ||
| 884 | .c_va_start, | ||
| 885 | => return false, | ||
| 886 | // TODO: this is a workaround for llvm/llvm-project#68409 | ||
| 887 | // Zig tracking issue: #16876 | ||
| 888 | .frame_address => return true, | ||
| 889 | // These builtins take a single argument with a known result type, but do not consume their | ||
| 890 | // result pointer. | ||
| 891 | .size_of, | ||
| 892 | .bit_size_of, | ||
| 893 | .align_of, | ||
| 894 | .compile_error, | ||
| 895 | .set_eval_branch_quota, | ||
| 896 | .int_from_bool, | ||
| 897 | .int_from_error, | ||
| 898 | .error_from_int, | ||
| 899 | .embed_file, | ||
| 900 | .error_name, | ||
| 901 | .set_runtime_safety, | ||
| 902 | .Type, | ||
| 903 | .c_undef, | ||
| 904 | .c_include, | ||
| 905 | .wasm_memory_size, | ||
| 906 | .splat, | ||
| 907 | .fence, | ||
| 908 | .set_float_mode, | ||
| 909 | .set_align_stack, | ||
| 910 | .set_cold, | ||
| 911 | .type_info, | ||
| 912 | .work_item_id, | ||
| 913 | .work_group_size, | ||
| 914 | .work_group_id, | ||
| 915 | => { | ||
| 916 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 917 | return false; | ||
| 918 | }, | ||
| 919 | // These builtins take a single argument with no result information and do not consume their | ||
| 920 | // result pointer. | ||
| 921 | .int_from_ptr, | ||
| 922 | .int_from_enum, | ||
| 923 | .sqrt, | ||
| 924 | .sin, | ||
| 925 | .cos, | ||
| 926 | .tan, | ||
| 927 | .exp, | ||
| 928 | .exp2, | ||
| 929 | .log, | ||
| 930 | .log2, | ||
| 931 | .log10, | ||
| 932 | .abs, | ||
| 933 | .floor, | ||
| 934 | .ceil, | ||
| 935 | .trunc, | ||
| 936 | .round, | ||
| 937 | .tag_name, | ||
| 938 | .type_name, | ||
| 939 | .Frame, | ||
| 940 | .frame_size, | ||
| 941 | .int_from_float, | ||
| 942 | .float_from_int, | ||
| 943 | .ptr_from_int, | ||
| 944 | .enum_from_int, | ||
| 945 | .float_cast, | ||
| 946 | .int_cast, | ||
| 947 | .truncate, | ||
| 948 | .error_cast, | ||
| 949 | .ptr_cast, | ||
| 950 | .align_cast, | ||
| 951 | .addrspace_cast, | ||
| 952 | .const_cast, | ||
| 953 | .volatile_cast, | ||
| 954 | .clz, | ||
| 955 | .ctz, | ||
| 956 | .pop_count, | ||
| 957 | .byte_swap, | ||
| 958 | .bit_reverse, | ||
| 959 | => { | ||
| 960 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 961 | return false; | ||
| 962 | }, | ||
| 963 | .div_exact, | ||
| 964 | .div_floor, | ||
| 965 | .div_trunc, | ||
| 966 | .mod, | ||
| 967 | .rem, | ||
| 968 | => { | ||
| 969 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 970 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 971 | return false; | ||
| 972 | }, | ||
| 973 | .shl_exact, .shr_exact => { | ||
| 974 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 975 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 976 | return false; | ||
| 977 | }, | ||
| 978 | .bit_offset_of, | ||
| 979 | .offset_of, | ||
| 980 | .field_parent_ptr, | ||
| 981 | .has_decl, | ||
| 982 | .has_field, | ||
| 983 | .field, | ||
| 984 | => { | ||
| 985 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 986 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 987 | return false; | ||
| 988 | }, | ||
| 989 | .wasm_memory_grow => { | ||
| 990 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 991 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 992 | return false; | ||
| 993 | }, | ||
| 994 | .c_define => { | ||
| 995 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 996 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 997 | return false; | ||
| 998 | }, | ||
| 999 | .reduce => { | ||
| 1000 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 1001 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 1002 | return false; | ||
| 1003 | }, | ||
| 1004 | .add_with_overflow, .sub_with_overflow, .mul_with_overflow, .shl_with_overflow => { | ||
| 1005 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 1006 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 1007 | return false; | ||
| 1008 | }, | ||
| 1009 | .atomic_load => { | ||
| 1010 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 1011 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 1012 | _ = try astrl.expr(args[2], block, ResultInfo.type_only); | ||
| 1013 | return false; | ||
| 1014 | }, | ||
| 1015 | .atomic_rmw => { | ||
| 1016 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 1017 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 1018 | _ = try astrl.expr(args[2], block, ResultInfo.type_only); | ||
| 1019 | _ = try astrl.expr(args[3], block, ResultInfo.type_only); | ||
| 1020 | _ = try astrl.expr(args[4], block, ResultInfo.type_only); | ||
| 1021 | return false; | ||
| 1022 | }, | ||
| 1023 | .atomic_store => { | ||
| 1024 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 1025 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 1026 | _ = try astrl.expr(args[2], block, ResultInfo.type_only); | ||
| 1027 | _ = try astrl.expr(args[3], block, ResultInfo.type_only); | ||
| 1028 | return false; | ||
| 1029 | }, | ||
| 1030 | .mul_add => { | ||
| 1031 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 1032 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 1033 | _ = try astrl.expr(args[2], block, ResultInfo.type_only); | ||
| 1034 | return false; | ||
| 1035 | }, | ||
| 1036 | .call => { | ||
| 1037 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 1038 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 1039 | _ = try astrl.expr(args[2], block, ResultInfo.none); | ||
| 1040 | return false; | ||
| 1041 | }, | ||
| 1042 | .memcpy => { | ||
| 1043 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 1044 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 1045 | return false; | ||
| 1046 | }, | ||
| 1047 | .memset => { | ||
| 1048 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 1049 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 1050 | return false; | ||
| 1051 | }, | ||
| 1052 | .shuffle => { | ||
| 1053 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 1054 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 1055 | _ = try astrl.expr(args[2], block, ResultInfo.none); | ||
| 1056 | _ = try astrl.expr(args[3], block, ResultInfo.none); | ||
| 1057 | return false; | ||
| 1058 | }, | ||
| 1059 | .select => { | ||
| 1060 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 1061 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 1062 | _ = try astrl.expr(args[2], block, ResultInfo.none); | ||
| 1063 | _ = try astrl.expr(args[3], block, ResultInfo.none); | ||
| 1064 | return false; | ||
| 1065 | }, | ||
| 1066 | .async_call => { | ||
| 1067 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 1068 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 1069 | _ = try astrl.expr(args[2], block, ResultInfo.none); | ||
| 1070 | _ = try astrl.expr(args[3], block, ResultInfo.none); | ||
| 1071 | return false; // buffer passed as arg for frame data | ||
| 1072 | }, | ||
| 1073 | .Vector => { | ||
| 1074 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 1075 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 1076 | return false; | ||
| 1077 | }, | ||
| 1078 | .prefetch => { | ||
| 1079 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 1080 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 1081 | return false; | ||
| 1082 | }, | ||
| 1083 | .c_va_arg => { | ||
| 1084 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 1085 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 1086 | return false; | ||
| 1087 | }, | ||
| 1088 | .c_va_copy => { | ||
| 1089 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 1090 | return false; | ||
| 1091 | }, | ||
| 1092 | .c_va_end => { | ||
| 1093 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 1094 | return false; | ||
| 1095 | }, | ||
| 1096 | .cmpxchg_strong, .cmpxchg_weak => { | ||
| 1097 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 1098 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 1099 | _ = try astrl.expr(args[2], block, ResultInfo.type_only); | ||
| 1100 | _ = try astrl.expr(args[3], block, ResultInfo.type_only); | ||
| 1101 | _ = try astrl.expr(args[4], block, ResultInfo.type_only); | ||
| 1102 | return false; | ||
| 1103 | }, | ||
| 1104 | } | ||
| 1105 | } | ||
lib/std/zig/BuiltinFn.zig created+1017| ... | @@ -0,0 +1,1017 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | pub const Tag = enum { | ||
| 4 | add_with_overflow, | ||
| 5 | addrspace_cast, | ||
| 6 | align_cast, | ||
| 7 | align_of, | ||
| 8 | as, | ||
| 9 | async_call, | ||
| 10 | atomic_load, | ||
| 11 | atomic_rmw, | ||
| 12 | atomic_store, | ||
| 13 | bit_cast, | ||
| 14 | bit_offset_of, | ||
| 15 | int_from_bool, | ||
| 16 | bit_size_of, | ||
| 17 | breakpoint, | ||
| 18 | mul_add, | ||
| 19 | byte_swap, | ||
| 20 | bit_reverse, | ||
| 21 | offset_of, | ||
| 22 | call, | ||
| 23 | c_define, | ||
| 24 | c_import, | ||
| 25 | c_include, | ||
| 26 | clz, | ||
| 27 | cmpxchg_strong, | ||
| 28 | cmpxchg_weak, | ||
| 29 | compile_error, | ||
| 30 | compile_log, | ||
| 31 | const_cast, | ||
| 32 | ctz, | ||
| 33 | c_undef, | ||
| 34 | c_va_arg, | ||
| 35 | c_va_copy, | ||
| 36 | c_va_end, | ||
| 37 | c_va_start, | ||
| 38 | div_exact, | ||
| 39 | div_floor, | ||
| 40 | div_trunc, | ||
| 41 | embed_file, | ||
| 42 | int_from_enum, | ||
| 43 | error_name, | ||
| 44 | error_return_trace, | ||
| 45 | int_from_error, | ||
| 46 | error_cast, | ||
| 47 | @"export", | ||
| 48 | @"extern", | ||
| 49 | fence, | ||
| 50 | field, | ||
| 51 | field_parent_ptr, | ||
| 52 | float_cast, | ||
| 53 | int_from_float, | ||
| 54 | frame, | ||
| 55 | Frame, | ||
| 56 | frame_address, | ||
| 57 | frame_size, | ||
| 58 | has_decl, | ||
| 59 | has_field, | ||
| 60 | import, | ||
| 61 | in_comptime, | ||
| 62 | int_cast, | ||
| 63 | enum_from_int, | ||
| 64 | error_from_int, | ||
| 65 | float_from_int, | ||
| 66 | ptr_from_int, | ||
| 67 | max, | ||
| 68 | memcpy, | ||
| 69 | memset, | ||
| 70 | min, | ||
| 71 | wasm_memory_size, | ||
| 72 | wasm_memory_grow, | ||
| 73 | mod, | ||
| 74 | mul_with_overflow, | ||
| 75 | panic, | ||
| 76 | pop_count, | ||
| 77 | prefetch, | ||
| 78 | ptr_cast, | ||
| 79 | int_from_ptr, | ||
| 80 | rem, | ||
| 81 | return_address, | ||
| 82 | select, | ||
| 83 | set_align_stack, | ||
| 84 | set_cold, | ||
| 85 | set_eval_branch_quota, | ||
| 86 | set_float_mode, | ||
| 87 | set_runtime_safety, | ||
| 88 | shl_exact, | ||
| 89 | shl_with_overflow, | ||
| 90 | shr_exact, | ||
| 91 | shuffle, | ||
| 92 | size_of, | ||
| 93 | splat, | ||
| 94 | reduce, | ||
| 95 | src, | ||
| 96 | sqrt, | ||
| 97 | sin, | ||
| 98 | cos, | ||
| 99 | tan, | ||
| 100 | exp, | ||
| 101 | exp2, | ||
| 102 | log, | ||
| 103 | log2, | ||
| 104 | log10, | ||
| 105 | abs, | ||
| 106 | floor, | ||
| 107 | ceil, | ||
| 108 | trunc, | ||
| 109 | round, | ||
| 110 | sub_with_overflow, | ||
| 111 | tag_name, | ||
| 112 | This, | ||
| 113 | trap, | ||
| 114 | truncate, | ||
| 115 | Type, | ||
| 116 | type_info, | ||
| 117 | type_name, | ||
| 118 | TypeOf, | ||
| 119 | union_init, | ||
| 120 | Vector, | ||
| 121 | volatile_cast, | ||
| 122 | work_item_id, | ||
| 123 | work_group_size, | ||
| 124 | work_group_id, | ||
| 125 | }; | ||
| 126 | |||
| 127 | pub const MemLocRequirement = enum { | ||
| 128 | /// The builtin never needs a memory location. | ||
| 129 | never, | ||
| 130 | /// The builtin always needs a memory location. | ||
| 131 | always, | ||
| 132 | /// The builtin forwards the question to argument at index 0. | ||
| 133 | forward0, | ||
| 134 | /// The builtin forwards the question to argument at index 1. | ||
| 135 | forward1, | ||
| 136 | }; | ||
| 137 | |||
| 138 | pub const EvalToError = enum { | ||
| 139 | /// The builtin cannot possibly evaluate to an error. | ||
| 140 | never, | ||
| 141 | /// The builtin will always evaluate to an error. | ||
| 142 | always, | ||
| 143 | /// The builtin may or may not evaluate to an error depending on the parameters. | ||
| 144 | maybe, | ||
| 145 | }; | ||
| 146 | |||
| 147 | tag: Tag, | ||
| 148 | |||
| 149 | /// Info about the builtin call's ability to take advantage of a result location pointer. | ||
| 150 | needs_mem_loc: MemLocRequirement = .never, | ||
| 151 | /// Info about the builtin call's possibility of returning an error. | ||
| 152 | eval_to_error: EvalToError = .never, | ||
| 153 | /// `true` if the builtin call can be the left-hand side of an expression (assigned to). | ||
| 154 | allows_lvalue: bool = false, | ||
| 155 | /// The number of parameters to this builtin function. `null` means variable number | ||
| 156 | /// of parameters. | ||
| 157 | param_count: ?u8, | ||
| 158 | |||
| 159 | pub const list = list: { | ||
| 160 | @setEvalBranchQuota(3000); | ||
| 161 | break :list std.ComptimeStringMap(@This(), .{ | ||
| 162 | .{ | ||
| 163 | "@addWithOverflow", | ||
| 164 | .{ | ||
| 165 | .tag = .add_with_overflow, | ||
| 166 | .param_count = 2, | ||
| 167 | }, | ||
| 168 | }, | ||
| 169 | .{ | ||
| 170 | "@addrSpaceCast", | ||
| 171 | .{ | ||
| 172 | .tag = .addrspace_cast, | ||
| 173 | .param_count = 1, | ||
| 174 | }, | ||
| 175 | }, | ||
| 176 | .{ | ||
| 177 | "@alignCast", | ||
| 178 | .{ | ||
| 179 | .tag = .align_cast, | ||
| 180 | .param_count = 1, | ||
| 181 | }, | ||
| 182 | }, | ||
| 183 | .{ | ||
| 184 | "@alignOf", | ||
| 185 | .{ | ||
| 186 | .tag = .align_of, | ||
| 187 | .param_count = 1, | ||
| 188 | }, | ||
| 189 | }, | ||
| 190 | .{ | ||
| 191 | "@as", | ||
| 192 | .{ | ||
| 193 | .tag = .as, | ||
| 194 | .needs_mem_loc = .forward1, | ||
| 195 | .eval_to_error = .maybe, | ||
| 196 | .param_count = 2, | ||
| 197 | }, | ||
| 198 | }, | ||
| 199 | .{ | ||
| 200 | "@asyncCall", | ||
| 201 | .{ | ||
| 202 | .tag = .async_call, | ||
| 203 | .param_count = 4, | ||
| 204 | }, | ||
| 205 | }, | ||
| 206 | .{ | ||
| 207 | "@atomicLoad", | ||
| 208 | .{ | ||
| 209 | .tag = .atomic_load, | ||
| 210 | .param_count = 3, | ||
| 211 | }, | ||
| 212 | }, | ||
| 213 | .{ | ||
| 214 | "@atomicRmw", | ||
| 215 | .{ | ||
| 216 | .tag = .atomic_rmw, | ||
| 217 | .param_count = 5, | ||
| 218 | }, | ||
| 219 | }, | ||
| 220 | .{ | ||
| 221 | "@atomicStore", | ||
| 222 | .{ | ||
| 223 | .tag = .atomic_store, | ||
| 224 | .param_count = 4, | ||
| 225 | }, | ||
| 226 | }, | ||
| 227 | .{ | ||
| 228 | "@bitCast", | ||
| 229 | .{ | ||
| 230 | .tag = .bit_cast, | ||
| 231 | .needs_mem_loc = .forward0, | ||
| 232 | .param_count = 1, | ||
| 233 | }, | ||
| 234 | }, | ||
| 235 | .{ | ||
| 236 | "@bitOffsetOf", | ||
| 237 | .{ | ||
| 238 | .tag = .bit_offset_of, | ||
| 239 | .param_count = 2, | ||
| 240 | }, | ||
| 241 | }, | ||
| 242 | .{ | ||
| 243 | "@intFromBool", | ||
| 244 | .{ | ||
| 245 | .tag = .int_from_bool, | ||
| 246 | .param_count = 1, | ||
| 247 | }, | ||
| 248 | }, | ||
| 249 | .{ | ||
| 250 | "@bitSizeOf", | ||
| 251 | .{ | ||
| 252 | .tag = .bit_size_of, | ||
| 253 | .param_count = 1, | ||
| 254 | }, | ||
| 255 | }, | ||
| 256 | .{ | ||
| 257 | "@breakpoint", | ||
| 258 | .{ | ||
| 259 | .tag = .breakpoint, | ||
| 260 | .param_count = 0, | ||
| 261 | }, | ||
| 262 | }, | ||
| 263 | .{ | ||
| 264 | "@mulAdd", | ||
| 265 | .{ | ||
| 266 | .tag = .mul_add, | ||
| 267 | .param_count = 4, | ||
| 268 | }, | ||
| 269 | }, | ||
| 270 | .{ | ||
| 271 | "@byteSwap", | ||
| 272 | .{ | ||
| 273 | .tag = .byte_swap, | ||
| 274 | .param_count = 1, | ||
| 275 | }, | ||
| 276 | }, | ||
| 277 | .{ | ||
| 278 | "@bitReverse", | ||
| 279 | .{ | ||
| 280 | .tag = .bit_reverse, | ||
| 281 | .param_count = 1, | ||
| 282 | }, | ||
| 283 | }, | ||
| 284 | .{ | ||
| 285 | "@offsetOf", | ||
| 286 | .{ | ||
| 287 | .tag = .offset_of, | ||
| 288 | .param_count = 2, | ||
| 289 | }, | ||
| 290 | }, | ||
| 291 | .{ | ||
| 292 | "@call", | ||
| 293 | .{ | ||
| 294 | .tag = .call, | ||
| 295 | .needs_mem_loc = .always, | ||
| 296 | .eval_to_error = .maybe, | ||
| 297 | .param_count = 3, | ||
| 298 | }, | ||
| 299 | }, | ||
| 300 | .{ | ||
| 301 | "@cDefine", | ||
| 302 | .{ | ||
| 303 | .tag = .c_define, | ||
| 304 | .param_count = 2, | ||
| 305 | }, | ||
| 306 | }, | ||
| 307 | .{ | ||
| 308 | "@cImport", | ||
| 309 | .{ | ||
| 310 | .tag = .c_import, | ||
| 311 | .param_count = 1, | ||
| 312 | }, | ||
| 313 | }, | ||
| 314 | .{ | ||
| 315 | "@cInclude", | ||
| 316 | .{ | ||
| 317 | .tag = .c_include, | ||
| 318 | .param_count = 1, | ||
| 319 | }, | ||
| 320 | }, | ||
| 321 | .{ | ||
| 322 | "@clz", | ||
| 323 | .{ | ||
| 324 | .tag = .clz, | ||
| 325 | .param_count = 1, | ||
| 326 | }, | ||
| 327 | }, | ||
| 328 | .{ | ||
| 329 | "@cmpxchgStrong", | ||
| 330 | .{ | ||
| 331 | .tag = .cmpxchg_strong, | ||
| 332 | .param_count = 6, | ||
| 333 | }, | ||
| 334 | }, | ||
| 335 | .{ | ||
| 336 | "@cmpxchgWeak", | ||
| 337 | .{ | ||
| 338 | .tag = .cmpxchg_weak, | ||
| 339 | .param_count = 6, | ||
| 340 | }, | ||
| 341 | }, | ||
| 342 | .{ | ||
| 343 | "@compileError", | ||
| 344 | .{ | ||
| 345 | .tag = .compile_error, | ||
| 346 | .param_count = 1, | ||
| 347 | }, | ||
| 348 | }, | ||
| 349 | .{ | ||
| 350 | "@compileLog", | ||
| 351 | .{ | ||
| 352 | .tag = .compile_log, | ||
| 353 | .param_count = null, | ||
| 354 | }, | ||
| 355 | }, | ||
| 356 | .{ | ||
| 357 | "@constCast", | ||
| 358 | .{ | ||
| 359 | .tag = .const_cast, | ||
| 360 | .param_count = 1, | ||
| 361 | }, | ||
| 362 | }, | ||
| 363 | .{ | ||
| 364 | "@ctz", | ||
| 365 | .{ | ||
| 366 | .tag = .ctz, | ||
| 367 | .param_count = 1, | ||
| 368 | }, | ||
| 369 | }, | ||
| 370 | .{ | ||
| 371 | "@cUndef", | ||
| 372 | .{ | ||
| 373 | .tag = .c_undef, | ||
| 374 | .param_count = 1, | ||
| 375 | }, | ||
| 376 | }, | ||
| 377 | .{ | ||
| 378 | "@cVaArg", .{ | ||
| 379 | .tag = .c_va_arg, | ||
| 380 | .param_count = 2, | ||
| 381 | }, | ||
| 382 | }, | ||
| 383 | .{ | ||
| 384 | "@cVaCopy", .{ | ||
| 385 | .tag = .c_va_copy, | ||
| 386 | .param_count = 1, | ||
| 387 | }, | ||
| 388 | }, | ||
| 389 | .{ | ||
| 390 | "@cVaEnd", .{ | ||
| 391 | .tag = .c_va_end, | ||
| 392 | .param_count = 1, | ||
| 393 | }, | ||
| 394 | }, | ||
| 395 | .{ | ||
| 396 | "@cVaStart", .{ | ||
| 397 | .tag = .c_va_start, | ||
| 398 | .param_count = 0, | ||
| 399 | }, | ||
| 400 | }, | ||
| 401 | .{ | ||
| 402 | "@divExact", | ||
| 403 | .{ | ||
| 404 | .tag = .div_exact, | ||
| 405 | .param_count = 2, | ||
| 406 | }, | ||
| 407 | }, | ||
| 408 | .{ | ||
| 409 | "@divFloor", | ||
| 410 | .{ | ||
| 411 | .tag = .div_floor, | ||
| 412 | .param_count = 2, | ||
| 413 | }, | ||
| 414 | }, | ||
| 415 | .{ | ||
| 416 | "@divTrunc", | ||
| 417 | .{ | ||
| 418 | .tag = .div_trunc, | ||
| 419 | .param_count = 2, | ||
| 420 | }, | ||
| 421 | }, | ||
| 422 | .{ | ||
| 423 | "@embedFile", | ||
| 424 | .{ | ||
| 425 | .tag = .embed_file, | ||
| 426 | .param_count = 1, | ||
| 427 | }, | ||
| 428 | }, | ||
| 429 | .{ | ||
| 430 | "@intFromEnum", | ||
| 431 | .{ | ||
| 432 | .tag = .int_from_enum, | ||
| 433 | .param_count = 1, | ||
| 434 | }, | ||
| 435 | }, | ||
| 436 | .{ | ||
| 437 | "@errorName", | ||
| 438 | .{ | ||
| 439 | .tag = .error_name, | ||
| 440 | .param_count = 1, | ||
| 441 | }, | ||
| 442 | }, | ||
| 443 | .{ | ||
| 444 | "@errorReturnTrace", | ||
| 445 | .{ | ||
| 446 | .tag = .error_return_trace, | ||
| 447 | .param_count = 0, | ||
| 448 | }, | ||
| 449 | }, | ||
| 450 | .{ | ||
| 451 | "@intFromError", | ||
| 452 | .{ | ||
| 453 | .tag = .int_from_error, | ||
| 454 | .param_count = 1, | ||
| 455 | }, | ||
| 456 | }, | ||
| 457 | .{ | ||
| 458 | "@errorCast", | ||
| 459 | .{ | ||
| 460 | .tag = .error_cast, | ||
| 461 | .eval_to_error = .always, | ||
| 462 | .param_count = 1, | ||
| 463 | }, | ||
| 464 | }, | ||
| 465 | .{ | ||
| 466 | "@export", | ||
| 467 | .{ | ||
| 468 | .tag = .@"export", | ||
| 469 | .param_count = 2, | ||
| 470 | }, | ||
| 471 | }, | ||
| 472 | .{ | ||
| 473 | "@extern", | ||
| 474 | .{ | ||
| 475 | .tag = .@"extern", | ||
| 476 | .param_count = 2, | ||
| 477 | }, | ||
| 478 | }, | ||
| 479 | .{ | ||
| 480 | "@fence", | ||
| 481 | .{ | ||
| 482 | .tag = .fence, | ||
| 483 | .param_count = 1, | ||
| 484 | }, | ||
| 485 | }, | ||
| 486 | .{ | ||
| 487 | "@field", | ||
| 488 | .{ | ||
| 489 | .tag = .field, | ||
| 490 | .needs_mem_loc = .always, | ||
| 491 | .eval_to_error = .maybe, | ||
| 492 | .param_count = 2, | ||
| 493 | .allows_lvalue = true, | ||
| 494 | }, | ||
| 495 | }, | ||
| 496 | .{ | ||
| 497 | "@fieldParentPtr", | ||
| 498 | .{ | ||
| 499 | .tag = .field_parent_ptr, | ||
| 500 | .param_count = 3, | ||
| 501 | }, | ||
| 502 | }, | ||
| 503 | .{ | ||
| 504 | "@floatCast", | ||
| 505 | .{ | ||
| 506 | .tag = .float_cast, | ||
| 507 | .param_count = 1, | ||
| 508 | }, | ||
| 509 | }, | ||
| 510 | .{ | ||
| 511 | "@intFromFloat", | ||
| 512 | .{ | ||
| 513 | .tag = .int_from_float, | ||
| 514 | .param_count = 1, | ||
| 515 | }, | ||
| 516 | }, | ||
| 517 | .{ | ||
| 518 | "@frame", | ||
| 519 | .{ | ||
| 520 | .tag = .frame, | ||
| 521 | .param_count = 0, | ||
| 522 | }, | ||
| 523 | }, | ||
| 524 | .{ | ||
| 525 | "@Frame", | ||
| 526 | .{ | ||
| 527 | .tag = .Frame, | ||
| 528 | .param_count = 1, | ||
| 529 | }, | ||
| 530 | }, | ||
| 531 | .{ | ||
| 532 | "@frameAddress", | ||
| 533 | .{ | ||
| 534 | .tag = .frame_address, | ||
| 535 | .param_count = 0, | ||
| 536 | }, | ||
| 537 | }, | ||
| 538 | .{ | ||
| 539 | "@frameSize", | ||
| 540 | .{ | ||
| 541 | .tag = .frame_size, | ||
| 542 | .param_count = 1, | ||
| 543 | }, | ||
| 544 | }, | ||
| 545 | .{ | ||
| 546 | "@hasDecl", | ||
| 547 | .{ | ||
| 548 | .tag = .has_decl, | ||
| 549 | .param_count = 2, | ||
| 550 | }, | ||
| 551 | }, | ||
| 552 | .{ | ||
| 553 | "@hasField", | ||
| 554 | .{ | ||
| 555 | .tag = .has_field, | ||
| 556 | .param_count = 2, | ||
| 557 | }, | ||
| 558 | }, | ||
| 559 | .{ | ||
| 560 | "@import", | ||
| 561 | .{ | ||
| 562 | .tag = .import, | ||
| 563 | .param_count = 1, | ||
| 564 | }, | ||
| 565 | }, | ||
| 566 | .{ | ||
| 567 | "@inComptime", | ||
| 568 | .{ | ||
| 569 | .tag = .in_comptime, | ||
| 570 | .param_count = 0, | ||
| 571 | }, | ||
| 572 | }, | ||
| 573 | .{ | ||
| 574 | "@intCast", | ||
| 575 | .{ | ||
| 576 | .tag = .int_cast, | ||
| 577 | .param_count = 1, | ||
| 578 | }, | ||
| 579 | }, | ||
| 580 | .{ | ||
| 581 | "@enumFromInt", | ||
| 582 | .{ | ||
| 583 | .tag = .enum_from_int, | ||
| 584 | .param_count = 1, | ||
| 585 | }, | ||
| 586 | }, | ||
| 587 | .{ | ||
| 588 | "@errorFromInt", | ||
| 589 | .{ | ||
| 590 | .tag = .error_from_int, | ||
| 591 | .eval_to_error = .always, | ||
| 592 | .param_count = 1, | ||
| 593 | }, | ||
| 594 | }, | ||
| 595 | .{ | ||
| 596 | "@floatFromInt", | ||
| 597 | .{ | ||
| 598 | .tag = .float_from_int, | ||
| 599 | .param_count = 1, | ||
| 600 | }, | ||
| 601 | }, | ||
| 602 | .{ | ||
| 603 | "@ptrFromInt", | ||
| 604 | .{ | ||
| 605 | .tag = .ptr_from_int, | ||
| 606 | .param_count = 1, | ||
| 607 | }, | ||
| 608 | }, | ||
| 609 | .{ | ||
| 610 | "@max", | ||
| 611 | .{ | ||
| 612 | .tag = .max, | ||
| 613 | .param_count = null, | ||
| 614 | }, | ||
| 615 | }, | ||
| 616 | .{ | ||
| 617 | "@memcpy", | ||
| 618 | .{ | ||
| 619 | .tag = .memcpy, | ||
| 620 | .param_count = 2, | ||
| 621 | }, | ||
| 622 | }, | ||
| 623 | .{ | ||
| 624 | "@memset", | ||
| 625 | .{ | ||
| 626 | .tag = .memset, | ||
| 627 | .param_count = 2, | ||
| 628 | }, | ||
| 629 | }, | ||
| 630 | .{ | ||
| 631 | "@min", | ||
| 632 | .{ | ||
| 633 | .tag = .min, | ||
| 634 | .param_count = null, | ||
| 635 | }, | ||
| 636 | }, | ||
| 637 | .{ | ||
| 638 | "@wasmMemorySize", | ||
| 639 | .{ | ||
| 640 | .tag = .wasm_memory_size, | ||
| 641 | .param_count = 1, | ||
| 642 | }, | ||
| 643 | }, | ||
| 644 | .{ | ||
| 645 | "@wasmMemoryGrow", | ||
| 646 | .{ | ||
| 647 | .tag = .wasm_memory_grow, | ||
| 648 | .param_count = 2, | ||
| 649 | }, | ||
| 650 | }, | ||
| 651 | .{ | ||
| 652 | "@mod", | ||
| 653 | .{ | ||
| 654 | .tag = .mod, | ||
| 655 | .param_count = 2, | ||
| 656 | }, | ||
| 657 | }, | ||
| 658 | .{ | ||
| 659 | "@mulWithOverflow", | ||
| 660 | .{ | ||
| 661 | .tag = .mul_with_overflow, | ||
| 662 | .param_count = 2, | ||
| 663 | }, | ||
| 664 | }, | ||
| 665 | .{ | ||
| 666 | "@panic", | ||
| 667 | .{ | ||
| 668 | .tag = .panic, | ||
| 669 | .param_count = 1, | ||
| 670 | }, | ||
| 671 | }, | ||
| 672 | .{ | ||
| 673 | "@popCount", | ||
| 674 | .{ | ||
| 675 | .tag = .pop_count, | ||
| 676 | .param_count = 1, | ||
| 677 | }, | ||
| 678 | }, | ||
| 679 | .{ | ||
| 680 | "@prefetch", | ||
| 681 | .{ | ||
| 682 | .tag = .prefetch, | ||
| 683 | .param_count = 2, | ||
| 684 | }, | ||
| 685 | }, | ||
| 686 | .{ | ||
| 687 | "@ptrCast", | ||
| 688 | .{ | ||
| 689 | .tag = .ptr_cast, | ||
| 690 | .param_count = 1, | ||
| 691 | }, | ||
| 692 | }, | ||
| 693 | .{ | ||
| 694 | "@intFromPtr", | ||
| 695 | .{ | ||
| 696 | .tag = .int_from_ptr, | ||
| 697 | .param_count = 1, | ||
| 698 | }, | ||
| 699 | }, | ||
| 700 | .{ | ||
| 701 | "@rem", | ||
| 702 | .{ | ||
| 703 | .tag = .rem, | ||
| 704 | .param_count = 2, | ||
| 705 | }, | ||
| 706 | }, | ||
| 707 | .{ | ||
| 708 | "@returnAddress", | ||
| 709 | .{ | ||
| 710 | .tag = .return_address, | ||
| 711 | .param_count = 0, | ||
| 712 | }, | ||
| 713 | }, | ||
| 714 | .{ | ||
| 715 | "@select", | ||
| 716 | .{ | ||
| 717 | .tag = .select, | ||
| 718 | .param_count = 4, | ||
| 719 | }, | ||
| 720 | }, | ||
| 721 | .{ | ||
| 722 | "@setAlignStack", | ||
| 723 | .{ | ||
| 724 | .tag = .set_align_stack, | ||
| 725 | .param_count = 1, | ||
| 726 | }, | ||
| 727 | }, | ||
| 728 | .{ | ||
| 729 | "@setCold", | ||
| 730 | .{ | ||
| 731 | .tag = .set_cold, | ||
| 732 | .param_count = 1, | ||
| 733 | }, | ||
| 734 | }, | ||
| 735 | .{ | ||
| 736 | "@setEvalBranchQuota", | ||
| 737 | .{ | ||
| 738 | .tag = .set_eval_branch_quota, | ||
| 739 | .param_count = 1, | ||
| 740 | }, | ||
| 741 | }, | ||
| 742 | .{ | ||
| 743 | "@setFloatMode", | ||
| 744 | .{ | ||
| 745 | .tag = .set_float_mode, | ||
| 746 | .param_count = 1, | ||
| 747 | }, | ||
| 748 | }, | ||
| 749 | .{ | ||
| 750 | "@setRuntimeSafety", | ||
| 751 | .{ | ||
| 752 | .tag = .set_runtime_safety, | ||
| 753 | .param_count = 1, | ||
| 754 | }, | ||
| 755 | }, | ||
| 756 | .{ | ||
| 757 | "@shlExact", | ||
| 758 | .{ | ||
| 759 | .tag = .shl_exact, | ||
| 760 | .param_count = 2, | ||
| 761 | }, | ||
| 762 | }, | ||
| 763 | .{ | ||
| 764 | "@shlWithOverflow", | ||
| 765 | .{ | ||
| 766 | .tag = .shl_with_overflow, | ||
| 767 | .param_count = 2, | ||
| 768 | }, | ||
| 769 | }, | ||
| 770 | .{ | ||
| 771 | "@shrExact", | ||
| 772 | .{ | ||
| 773 | .tag = .shr_exact, | ||
| 774 | .param_count = 2, | ||
| 775 | }, | ||
| 776 | }, | ||
| 777 | .{ | ||
| 778 | "@shuffle", | ||
| 779 | .{ | ||
| 780 | .tag = .shuffle, | ||
| 781 | .param_count = 4, | ||
| 782 | }, | ||
| 783 | }, | ||
| 784 | .{ | ||
| 785 | "@sizeOf", | ||
| 786 | .{ | ||
| 787 | .tag = .size_of, | ||
| 788 | .param_count = 1, | ||
| 789 | }, | ||
| 790 | }, | ||
| 791 | .{ | ||
| 792 | "@splat", | ||
| 793 | .{ | ||
| 794 | .tag = .splat, | ||
| 795 | .param_count = 1, | ||
| 796 | }, | ||
| 797 | }, | ||
| 798 | .{ | ||
| 799 | "@reduce", | ||
| 800 | .{ | ||
| 801 | .tag = .reduce, | ||
| 802 | .param_count = 2, | ||
| 803 | }, | ||
| 804 | }, | ||
| 805 | .{ | ||
| 806 | "@src", | ||
| 807 | .{ | ||
| 808 | .tag = .src, | ||
| 809 | .needs_mem_loc = .always, | ||
| 810 | .param_count = 0, | ||
| 811 | }, | ||
| 812 | }, | ||
| 813 | .{ | ||
| 814 | "@sqrt", | ||
| 815 | .{ | ||
| 816 | .tag = .sqrt, | ||
| 817 | .param_count = 1, | ||
| 818 | }, | ||
| 819 | }, | ||
| 820 | .{ | ||
| 821 | "@sin", | ||
| 822 | .{ | ||
| 823 | .tag = .sin, | ||
| 824 | .param_count = 1, | ||
| 825 | }, | ||
| 826 | }, | ||
| 827 | .{ | ||
| 828 | "@cos", | ||
| 829 | .{ | ||
| 830 | .tag = .cos, | ||
| 831 | .param_count = 1, | ||
| 832 | }, | ||
| 833 | }, | ||
| 834 | .{ | ||
| 835 | "@tan", | ||
| 836 | .{ | ||
| 837 | .tag = .tan, | ||
| 838 | .param_count = 1, | ||
| 839 | }, | ||
| 840 | }, | ||
| 841 | .{ | ||
| 842 | "@exp", | ||
| 843 | .{ | ||
| 844 | .tag = .exp, | ||
| 845 | .param_count = 1, | ||
| 846 | }, | ||
| 847 | }, | ||
| 848 | .{ | ||
| 849 | "@exp2", | ||
| 850 | .{ | ||
| 851 | .tag = .exp2, | ||
| 852 | .param_count = 1, | ||
| 853 | }, | ||
| 854 | }, | ||
| 855 | .{ | ||
| 856 | "@log", | ||
| 857 | .{ | ||
| 858 | .tag = .log, | ||
| 859 | .param_count = 1, | ||
| 860 | }, | ||
| 861 | }, | ||
| 862 | .{ | ||
| 863 | "@log2", | ||
| 864 | .{ | ||
| 865 | .tag = .log2, | ||
| 866 | .param_count = 1, | ||
| 867 | }, | ||
| 868 | }, | ||
| 869 | .{ | ||
| 870 | "@log10", | ||
| 871 | .{ | ||
| 872 | .tag = .log10, | ||
| 873 | .param_count = 1, | ||
| 874 | }, | ||
| 875 | }, | ||
| 876 | .{ | ||
| 877 | "@abs", | ||
| 878 | .{ | ||
| 879 | .tag = .abs, | ||
| 880 | .param_count = 1, | ||
| 881 | }, | ||
| 882 | }, | ||
| 883 | .{ | ||
| 884 | "@floor", | ||
| 885 | .{ | ||
| 886 | .tag = .floor, | ||
| 887 | .param_count = 1, | ||
| 888 | }, | ||
| 889 | }, | ||
| 890 | .{ | ||
| 891 | "@ceil", | ||
| 892 | .{ | ||
| 893 | .tag = .ceil, | ||
| 894 | .param_count = 1, | ||
| 895 | }, | ||
| 896 | }, | ||
| 897 | .{ | ||
| 898 | "@trunc", | ||
| 899 | .{ | ||
| 900 | .tag = .trunc, | ||
| 901 | .param_count = 1, | ||
| 902 | }, | ||
| 903 | }, | ||
| 904 | .{ | ||
| 905 | "@round", | ||
| 906 | .{ | ||
| 907 | .tag = .round, | ||
| 908 | .param_count = 1, | ||
| 909 | }, | ||
| 910 | }, | ||
| 911 | .{ | ||
| 912 | "@subWithOverflow", | ||
| 913 | .{ | ||
| 914 | .tag = .sub_with_overflow, | ||
| 915 | .param_count = 2, | ||
| 916 | }, | ||
| 917 | }, | ||
| 918 | .{ | ||
| 919 | "@tagName", | ||
| 920 | .{ | ||
| 921 | .tag = .tag_name, | ||
| 922 | .param_count = 1, | ||
| 923 | }, | ||
| 924 | }, | ||
| 925 | .{ | ||
| 926 | "@This", | ||
| 927 | .{ | ||
| 928 | .tag = .This, | ||
| 929 | .param_count = 0, | ||
| 930 | }, | ||
| 931 | }, | ||
| 932 | .{ | ||
| 933 | "@trap", | ||
| 934 | .{ | ||
| 935 | .tag = .trap, | ||
| 936 | .param_count = 0, | ||
| 937 | }, | ||
| 938 | }, | ||
| 939 | .{ | ||
| 940 | "@truncate", | ||
| 941 | .{ | ||
| 942 | .tag = .truncate, | ||
| 943 | .param_count = 1, | ||
| 944 | }, | ||
| 945 | }, | ||
| 946 | .{ | ||
| 947 | "@Type", | ||
| 948 | .{ | ||
| 949 | .tag = .Type, | ||
| 950 | .param_count = 1, | ||
| 951 | }, | ||
| 952 | }, | ||
| 953 | .{ | ||
| 954 | "@typeInfo", | ||
| 955 | .{ | ||
| 956 | .tag = .type_info, | ||
| 957 | .param_count = 1, | ||
| 958 | }, | ||
| 959 | }, | ||
| 960 | .{ | ||
| 961 | "@typeName", | ||
| 962 | .{ | ||
| 963 | .tag = .type_name, | ||
| 964 | .param_count = 1, | ||
| 965 | }, | ||
| 966 | }, | ||
| 967 | .{ | ||
| 968 | "@TypeOf", | ||
| 969 | .{ | ||
| 970 | .tag = .TypeOf, | ||
| 971 | .param_count = null, | ||
| 972 | }, | ||
| 973 | }, | ||
| 974 | .{ | ||
| 975 | "@unionInit", | ||
| 976 | .{ | ||
| 977 | .tag = .union_init, | ||
| 978 | .needs_mem_loc = .always, | ||
| 979 | .param_count = 3, | ||
| 980 | }, | ||
| 981 | }, | ||
| 982 | .{ | ||
| 983 | "@Vector", | ||
| 984 | .{ | ||
| 985 | .tag = .Vector, | ||
| 986 | .param_count = 2, | ||
| 987 | }, | ||
| 988 | }, | ||
| 989 | .{ | ||
| 990 | "@volatileCast", | ||
| 991 | .{ | ||
| 992 | .tag = .volatile_cast, | ||
| 993 | .param_count = 1, | ||
| 994 | }, | ||
| 995 | }, | ||
| 996 | .{ | ||
| 997 | "@workItemId", .{ | ||
| 998 | .tag = .work_item_id, | ||
| 999 | .param_count = 1, | ||
| 1000 | }, | ||
| 1001 | }, | ||
| 1002 | .{ | ||
| 1003 | "@workGroupSize", | ||
| 1004 | .{ | ||
| 1005 | .tag = .work_group_size, | ||
| 1006 | .param_count = 1, | ||
| 1007 | }, | ||
| 1008 | }, | ||
| 1009 | .{ | ||
| 1010 | "@workGroupId", | ||
| 1011 | .{ | ||
| 1012 | .tag = .work_group_id, | ||
| 1013 | .param_count = 1, | ||
| 1014 | }, | ||
| 1015 | }, | ||
| 1016 | }); | ||
| 1017 | }; | ||
src/AstGen.zig+2-12| ... | @@ -13,9 +13,8 @@ const StringIndexContext = std.hash_map.StringIndexContext; | ... | @@ -13,9 +13,8 @@ const StringIndexContext = std.hash_map.StringIndexContext; |
| 13 | const isPrimitive = std.zig.primitives.isPrimitive; | 13 | const isPrimitive = std.zig.primitives.isPrimitive; |
| 14 | 14 | ||
| 15 | const Zir = @import("Zir.zig"); | 15 | const Zir = @import("Zir.zig"); |
| 16 | const trace = @import("tracy.zig").trace; | 16 | const BuiltinFn = std.zig.BuiltinFn; |
| 17 | const BuiltinFn = @import("BuiltinFn.zig"); | 17 | const AstRlAnnotate = std.zig.AstRlAnnotate; |
| 18 | const AstRlAnnotate = @import("AstRlAnnotate.zig"); | ||
| 19 | 18 | ||
| 20 | gpa: Allocator, | 19 | gpa: Allocator, |
| 21 | tree: *const Ast, | 20 | tree: *const Ast, |
| ... | @@ -2265,9 +2264,6 @@ fn blockExpr( | ... | @@ -2265,9 +2264,6 @@ fn blockExpr( |
| 2265 | block_node: Ast.Node.Index, | 2264 | block_node: Ast.Node.Index, |
| 2266 | statements: []const Ast.Node.Index, | 2265 | statements: []const Ast.Node.Index, |
| 2267 | ) InnerError!Zir.Inst.Ref { | 2266 | ) InnerError!Zir.Inst.Ref { |
| 2268 | const tracy = trace(@src()); | ||
| 2269 | defer tracy.end(); | ||
| 2270 | |||
| 2271 | const astgen = gz.astgen; | 2267 | const astgen = gz.astgen; |
| 2272 | const tree = astgen.tree; | 2268 | const tree = astgen.tree; |
| 2273 | const main_tokens = tree.nodes.items(.main_token); | 2269 | const main_tokens = tree.nodes.items(.main_token); |
| ... | @@ -2349,9 +2345,6 @@ fn labeledBlockExpr( | ... | @@ -2349,9 +2345,6 @@ fn labeledBlockExpr( |
| 2349 | statements: []const Ast.Node.Index, | 2345 | statements: []const Ast.Node.Index, |
| 2350 | force_comptime: bool, | 2346 | force_comptime: bool, |
| 2351 | ) InnerError!Zir.Inst.Ref { | 2347 | ) InnerError!Zir.Inst.Ref { |
| 2352 | const tracy = trace(@src()); | ||
| 2353 | defer tracy.end(); | ||
| 2354 | |||
| 2355 | const astgen = gz.astgen; | 2348 | const astgen = gz.astgen; |
| 2356 | const tree = astgen.tree; | 2349 | const tree = astgen.tree; |
| 2357 | const main_tokens = tree.nodes.items(.main_token); | 2350 | const main_tokens = tree.nodes.items(.main_token); |
| ... | @@ -7473,9 +7466,6 @@ fn identifier( | ... | @@ -7473,9 +7466,6 @@ fn identifier( |
| 7473 | ri: ResultInfo, | 7466 | ri: ResultInfo, |
| 7474 | ident: Ast.Node.Index, | 7467 | ident: Ast.Node.Index, |
| 7475 | ) InnerError!Zir.Inst.Ref { | 7468 | ) InnerError!Zir.Inst.Ref { |
| 7476 | const tracy = trace(@src()); | ||
| 7477 | defer tracy.end(); | ||
| 7478 | |||
| 7479 | const astgen = gz.astgen; | 7469 | const astgen = gz.astgen; |
| 7480 | const tree = astgen.tree; | 7470 | const tree = astgen.tree; |
| 7481 | const main_tokens = tree.nodes.items(.main_token); | 7471 | const main_tokens = tree.nodes.items(.main_token); |
src/AstRlAnnotate.zig deleted-1105| ... | @@ -1,1105 +0,0 @@ | ||
| 1 | //! AstRlAnnotate is a simple pass which runs over the AST before AstGen to | ||
| 2 | //! determine which expressions require result locations. | ||
| 3 | //! | ||
| 4 | //! In some cases, AstGen can choose whether to provide a result pointer or to | ||
| 5 | //! just use standard `break` instructions from a block. The latter choice can | ||
| 6 | //! result in more efficient ZIR and runtime code, but does not allow for RLS to | ||
| 7 | //! occur. Thus, we want to provide a real result pointer (from an alloc) only | ||
| 8 | //! when necessary. | ||
| 9 | //! | ||
| 10 | //! To achive this, we need to determine which expressions require a result | ||
| 11 | //! pointer. This pass is reponsible for analyzing all syntax forms which may | ||
| 12 | //! provide a result location and, if sub-expressions consume this result | ||
| 13 | //! pointer non-trivially (e.g. writing through field pointers), marking the | ||
| 14 | //! node as requiring a result location. | ||
| 15 | |||
| 16 | const std = @import("std"); | ||
| 17 | const AstRlAnnotate = @This(); | ||
| 18 | const Ast = std.zig.Ast; | ||
| 19 | const Allocator = std.mem.Allocator; | ||
| 20 | const AutoHashMapUnmanaged = std.AutoHashMapUnmanaged; | ||
| 21 | const BuiltinFn = @import("BuiltinFn.zig"); | ||
| 22 | const assert = std.debug.assert; | ||
| 23 | |||
| 24 | gpa: Allocator, | ||
| 25 | arena: Allocator, | ||
| 26 | tree: *const Ast, | ||
| 27 | |||
| 28 | /// Certain nodes are placed in this set under the following conditions: | ||
| 29 | /// * if-else: either branch consumes the result location | ||
| 30 | /// * labeled block: any break consumes the result location | ||
| 31 | /// * switch: any prong consumes the result location | ||
| 32 | /// * orelse/catch: the RHS expression consumes the result location | ||
| 33 | /// * while/for: any break consumes the result location | ||
| 34 | /// * @as: the second operand consumes the result location | ||
| 35 | /// * const: the init expression consumes the result location | ||
| 36 | /// * return: the return expression consumes the result location | ||
| 37 | nodes_need_rl: RlNeededSet = .{}, | ||
| 38 | |||
| 39 | pub const RlNeededSet = AutoHashMapUnmanaged(Ast.Node.Index, void); | ||
| 40 | |||
| 41 | const ResultInfo = packed struct { | ||
| 42 | /// Do we have a known result type? | ||
| 43 | have_type: bool, | ||
| 44 | /// Do we (potentially) have a result pointer? Note that this pointer's type | ||
| 45 | /// may not be known due to it being an inferred alloc. | ||
| 46 | have_ptr: bool, | ||
| 47 | |||
| 48 | const none: ResultInfo = .{ .have_type = false, .have_ptr = false }; | ||
| 49 | const typed_ptr: ResultInfo = .{ .have_type = true, .have_ptr = true }; | ||
| 50 | const inferred_ptr: ResultInfo = .{ .have_type = false, .have_ptr = true }; | ||
| 51 | const type_only: ResultInfo = .{ .have_type = true, .have_ptr = false }; | ||
| 52 | }; | ||
| 53 | |||
| 54 | /// A labeled block or a loop. When this block is broken from, `consumes_res_ptr` | ||
| 55 | /// should be set if the break expression consumed the result pointer. | ||
| 56 | const Block = struct { | ||
| 57 | parent: ?*Block, | ||
| 58 | label: ?[]const u8, | ||
| 59 | is_loop: bool, | ||
| 60 | ri: ResultInfo, | ||
| 61 | consumes_res_ptr: bool, | ||
| 62 | }; | ||
| 63 | |||
| 64 | pub fn annotate(gpa: Allocator, arena: Allocator, tree: Ast) Allocator.Error!RlNeededSet { | ||
| 65 | var astrl: AstRlAnnotate = .{ | ||
| 66 | .gpa = gpa, | ||
| 67 | .arena = arena, | ||
| 68 | .tree = &tree, | ||
| 69 | }; | ||
| 70 | defer astrl.deinit(gpa); | ||
| 71 | |||
| 72 | if (tree.errors.len != 0) { | ||
| 73 | // We can't perform analysis on a broken AST. AstGen will not run in | ||
| 74 | // this case. | ||
| 75 | return .{}; | ||
| 76 | } | ||
| 77 | |||
| 78 | for (tree.containerDeclRoot().ast.members) |member_node| { | ||
| 79 | _ = try astrl.expr(member_node, null, ResultInfo.none); | ||
| 80 | } | ||
| 81 | |||
| 82 | return astrl.nodes_need_rl.move(); | ||
| 83 | } | ||
| 84 | |||
| 85 | fn deinit(astrl: *AstRlAnnotate, gpa: Allocator) void { | ||
| 86 | astrl.nodes_need_rl.deinit(gpa); | ||
| 87 | } | ||
| 88 | |||
| 89 | fn containerDecl( | ||
| 90 | astrl: *AstRlAnnotate, | ||
| 91 | block: ?*Block, | ||
| 92 | full: Ast.full.ContainerDecl, | ||
| 93 | ) !void { | ||
| 94 | const tree = astrl.tree; | ||
| 95 | const token_tags = tree.tokens.items(.tag); | ||
| 96 | switch (token_tags[full.ast.main_token]) { | ||
| 97 | .keyword_struct => { | ||
| 98 | if (full.ast.arg != 0) { | ||
| 99 | _ = try astrl.expr(full.ast.arg, block, ResultInfo.type_only); | ||
| 100 | } | ||
| 101 | for (full.ast.members) |member_node| { | ||
| 102 | _ = try astrl.expr(member_node, block, ResultInfo.none); | ||
| 103 | } | ||
| 104 | }, | ||
| 105 | .keyword_union => { | ||
| 106 | if (full.ast.arg != 0) { | ||
| 107 | _ = try astrl.expr(full.ast.arg, block, ResultInfo.type_only); | ||
| 108 | } | ||
| 109 | for (full.ast.members) |member_node| { | ||
| 110 | _ = try astrl.expr(member_node, block, ResultInfo.none); | ||
| 111 | } | ||
| 112 | }, | ||
| 113 | .keyword_enum => { | ||
| 114 | if (full.ast.arg != 0) { | ||
| 115 | _ = try astrl.expr(full.ast.arg, block, ResultInfo.type_only); | ||
| 116 | } | ||
| 117 | for (full.ast.members) |member_node| { | ||
| 118 | _ = try astrl.expr(member_node, block, ResultInfo.none); | ||
| 119 | } | ||
| 120 | }, | ||
| 121 | .keyword_opaque => { | ||
| 122 | for (full.ast.members) |member_node| { | ||
| 123 | _ = try astrl.expr(member_node, block, ResultInfo.none); | ||
| 124 | } | ||
| 125 | }, | ||
| 126 | else => unreachable, | ||
| 127 | } | ||
| 128 | } | ||
| 129 | |||
| 130 | /// Returns true if `rl` provides a result pointer and the expression consumes it. | ||
| 131 | fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultInfo) Allocator.Error!bool { | ||
| 132 | const tree = astrl.tree; | ||
| 133 | const token_tags = tree.tokens.items(.tag); | ||
| 134 | const node_datas = tree.nodes.items(.data); | ||
| 135 | const node_tags = tree.nodes.items(.tag); | ||
| 136 | switch (node_tags[node]) { | ||
| 137 | .root, | ||
| 138 | .switch_case_one, | ||
| 139 | .switch_case_inline_one, | ||
| 140 | .switch_case, | ||
| 141 | .switch_case_inline, | ||
| 142 | .switch_range, | ||
| 143 | .for_range, | ||
| 144 | .asm_output, | ||
| 145 | .asm_input, | ||
| 146 | => unreachable, | ||
| 147 | |||
| 148 | .@"errdefer", .@"defer" => { | ||
| 149 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.none); | ||
| 150 | return false; | ||
| 151 | }, | ||
| 152 | |||
| 153 | .container_field_init, | ||
| 154 | .container_field_align, | ||
| 155 | .container_field, | ||
| 156 | => { | ||
| 157 | const full = tree.fullContainerField(node).?; | ||
| 158 | _ = try astrl.expr(full.ast.type_expr, block, ResultInfo.type_only); | ||
| 159 | if (full.ast.align_expr != 0) { | ||
| 160 | _ = try astrl.expr(full.ast.align_expr, block, ResultInfo.type_only); | ||
| 161 | } | ||
| 162 | if (full.ast.value_expr != 0) { | ||
| 163 | _ = try astrl.expr(full.ast.value_expr, block, ResultInfo.type_only); | ||
| 164 | } | ||
| 165 | return false; | ||
| 166 | }, | ||
| 167 | .@"usingnamespace" => { | ||
| 168 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.type_only); | ||
| 169 | return false; | ||
| 170 | }, | ||
| 171 | .test_decl => { | ||
| 172 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.none); | ||
| 173 | return false; | ||
| 174 | }, | ||
| 175 | .global_var_decl, | ||
| 176 | .local_var_decl, | ||
| 177 | .simple_var_decl, | ||
| 178 | .aligned_var_decl, | ||
| 179 | => { | ||
| 180 | const full = tree.fullVarDecl(node).?; | ||
| 181 | const init_ri = if (full.ast.type_node != 0) init_ri: { | ||
| 182 | _ = try astrl.expr(full.ast.type_node, block, ResultInfo.type_only); | ||
| 183 | break :init_ri ResultInfo.typed_ptr; | ||
| 184 | } else ResultInfo.inferred_ptr; | ||
| 185 | if (full.ast.init_node == 0) { | ||
| 186 | // No init node, so we're done. | ||
| 187 | return false; | ||
| 188 | } | ||
| 189 | switch (token_tags[full.ast.mut_token]) { | ||
| 190 | .keyword_const => { | ||
| 191 | const init_consumes_rl = try astrl.expr(full.ast.init_node, block, init_ri); | ||
| 192 | if (init_consumes_rl) { | ||
| 193 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | ||
| 194 | } | ||
| 195 | return false; | ||
| 196 | }, | ||
| 197 | .keyword_var => { | ||
| 198 | // We'll create an alloc either way, so don't care if the | ||
| 199 | // result pointer is consumed. | ||
| 200 | _ = try astrl.expr(full.ast.init_node, block, init_ri); | ||
| 201 | return false; | ||
| 202 | }, | ||
| 203 | else => unreachable, | ||
| 204 | } | ||
| 205 | }, | ||
| 206 | .assign_destructure => { | ||
| 207 | const lhs_count = tree.extra_data[node_datas[node].lhs]; | ||
| 208 | const all_lhs = tree.extra_data[node_datas[node].lhs + 1 ..][0..lhs_count]; | ||
| 209 | for (all_lhs) |lhs| { | ||
| 210 | _ = try astrl.expr(lhs, block, ResultInfo.none); | ||
| 211 | } | ||
| 212 | // We don't need to gather any meaningful data here, because destructures always use RLS | ||
| 213 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.none); | ||
| 214 | return false; | ||
| 215 | }, | ||
| 216 | .assign => { | ||
| 217 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 218 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.typed_ptr); | ||
| 219 | return false; | ||
| 220 | }, | ||
| 221 | .assign_shl, | ||
| 222 | .assign_shl_sat, | ||
| 223 | .assign_shr, | ||
| 224 | .assign_bit_and, | ||
| 225 | .assign_bit_or, | ||
| 226 | .assign_bit_xor, | ||
| 227 | .assign_div, | ||
| 228 | .assign_sub, | ||
| 229 | .assign_sub_wrap, | ||
| 230 | .assign_sub_sat, | ||
| 231 | .assign_mod, | ||
| 232 | .assign_add, | ||
| 233 | .assign_add_wrap, | ||
| 234 | .assign_add_sat, | ||
| 235 | .assign_mul, | ||
| 236 | .assign_mul_wrap, | ||
| 237 | .assign_mul_sat, | ||
| 238 | => { | ||
| 239 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 240 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.none); | ||
| 241 | return false; | ||
| 242 | }, | ||
| 243 | .shl, .shr => { | ||
| 244 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 245 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.type_only); | ||
| 246 | return false; | ||
| 247 | }, | ||
| 248 | .add, | ||
| 249 | .add_wrap, | ||
| 250 | .add_sat, | ||
| 251 | .sub, | ||
| 252 | .sub_wrap, | ||
| 253 | .sub_sat, | ||
| 254 | .mul, | ||
| 255 | .mul_wrap, | ||
| 256 | .mul_sat, | ||
| 257 | .div, | ||
| 258 | .mod, | ||
| 259 | .shl_sat, | ||
| 260 | .bit_and, | ||
| 261 | .bit_or, | ||
| 262 | .bit_xor, | ||
| 263 | .bang_equal, | ||
| 264 | .equal_equal, | ||
| 265 | .greater_than, | ||
| 266 | .greater_or_equal, | ||
| 267 | .less_than, | ||
| 268 | .less_or_equal, | ||
| 269 | .array_cat, | ||
| 270 | => { | ||
| 271 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 272 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.none); | ||
| 273 | return false; | ||
| 274 | }, | ||
| 275 | .array_mult => { | ||
| 276 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 277 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.type_only); | ||
| 278 | return false; | ||
| 279 | }, | ||
| 280 | .error_union, .merge_error_sets => { | ||
| 281 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 282 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.none); | ||
| 283 | return false; | ||
| 284 | }, | ||
| 285 | .bool_and, | ||
| 286 | .bool_or, | ||
| 287 | => { | ||
| 288 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.type_only); | ||
| 289 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.type_only); | ||
| 290 | return false; | ||
| 291 | }, | ||
| 292 | .bool_not => { | ||
| 293 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.type_only); | ||
| 294 | return false; | ||
| 295 | }, | ||
| 296 | .bit_not, .negation, .negation_wrap => { | ||
| 297 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 298 | return false; | ||
| 299 | }, | ||
| 300 | |||
| 301 | // These nodes are leaves and never consume a result location. | ||
| 302 | .identifier, | ||
| 303 | .string_literal, | ||
| 304 | .multiline_string_literal, | ||
| 305 | .number_literal, | ||
| 306 | .unreachable_literal, | ||
| 307 | .asm_simple, | ||
| 308 | .@"asm", | ||
| 309 | .enum_literal, | ||
| 310 | .error_value, | ||
| 311 | .anyframe_literal, | ||
| 312 | .@"continue", | ||
| 313 | .char_literal, | ||
| 314 | .error_set_decl, | ||
| 315 | => return false, | ||
| 316 | |||
| 317 | .builtin_call_two, .builtin_call_two_comma => { | ||
| 318 | if (node_datas[node].lhs == 0) { | ||
| 319 | return astrl.builtinCall(block, ri, node, &.{}); | ||
| 320 | } else if (node_datas[node].rhs == 0) { | ||
| 321 | return astrl.builtinCall(block, ri, node, &.{node_datas[node].lhs}); | ||
| 322 | } else { | ||
| 323 | return astrl.builtinCall(block, ri, node, &.{ node_datas[node].lhs, node_datas[node].rhs }); | ||
| 324 | } | ||
| 325 | }, | ||
| 326 | .builtin_call, .builtin_call_comma => { | ||
| 327 | const params = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs]; | ||
| 328 | return astrl.builtinCall(block, ri, node, params); | ||
| 329 | }, | ||
| 330 | |||
| 331 | .call_one, | ||
| 332 | .call_one_comma, | ||
| 333 | .async_call_one, | ||
| 334 | .async_call_one_comma, | ||
| 335 | .call, | ||
| 336 | .call_comma, | ||
| 337 | .async_call, | ||
| 338 | .async_call_comma, | ||
| 339 | => { | ||
| 340 | var buf: [1]Ast.Node.Index = undefined; | ||
| 341 | const full = tree.fullCall(&buf, node).?; | ||
| 342 | _ = try astrl.expr(full.ast.fn_expr, block, ResultInfo.none); | ||
| 343 | for (full.ast.params) |param_node| { | ||
| 344 | _ = try astrl.expr(param_node, block, ResultInfo.type_only); | ||
| 345 | } | ||
| 346 | return switch (node_tags[node]) { | ||
| 347 | .call_one, | ||
| 348 | .call_one_comma, | ||
| 349 | .call, | ||
| 350 | .call_comma, | ||
| 351 | => false, // TODO: once function calls are passed result locations this will change | ||
| 352 | .async_call_one, | ||
| 353 | .async_call_one_comma, | ||
| 354 | .async_call, | ||
| 355 | .async_call_comma, | ||
| 356 | => ri.have_ptr, // always use result ptr for frames | ||
| 357 | else => unreachable, | ||
| 358 | }; | ||
| 359 | }, | ||
| 360 | |||
| 361 | .@"return" => { | ||
| 362 | if (node_datas[node].lhs != 0) { | ||
| 363 | const ret_val_consumes_rl = try astrl.expr(node_datas[node].lhs, block, ResultInfo.typed_ptr); | ||
| 364 | if (ret_val_consumes_rl) { | ||
| 365 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | ||
| 366 | } | ||
| 367 | } | ||
| 368 | return false; | ||
| 369 | }, | ||
| 370 | |||
| 371 | .field_access => { | ||
| 372 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 373 | return false; | ||
| 374 | }, | ||
| 375 | |||
| 376 | .if_simple, .@"if" => { | ||
| 377 | const full = tree.fullIf(node).?; | ||
| 378 | if (full.error_token != null or full.payload_token != null) { | ||
| 379 | _ = try astrl.expr(full.ast.cond_expr, block, ResultInfo.none); | ||
| 380 | } else { | ||
| 381 | _ = try astrl.expr(full.ast.cond_expr, block, ResultInfo.type_only); // bool | ||
| 382 | } | ||
| 383 | |||
| 384 | if (full.ast.else_expr == 0) { | ||
| 385 | _ = try astrl.expr(full.ast.then_expr, block, ResultInfo.none); | ||
| 386 | return false; | ||
| 387 | } else { | ||
| 388 | const then_uses_rl = try astrl.expr(full.ast.then_expr, block, ri); | ||
| 389 | const else_uses_rl = try astrl.expr(full.ast.else_expr, block, ri); | ||
| 390 | const uses_rl = then_uses_rl or else_uses_rl; | ||
| 391 | if (uses_rl) try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | ||
| 392 | return uses_rl; | ||
| 393 | } | ||
| 394 | }, | ||
| 395 | |||
| 396 | .while_simple, .while_cont, .@"while" => { | ||
| 397 | const full = tree.fullWhile(node).?; | ||
| 398 | const label: ?[]const u8 = if (full.label_token) |label_token| label: { | ||
| 399 | break :label try astrl.identString(label_token); | ||
| 400 | } else null; | ||
| 401 | if (full.error_token != null or full.payload_token != null) { | ||
| 402 | _ = try astrl.expr(full.ast.cond_expr, block, ResultInfo.none); | ||
| 403 | } else { | ||
| 404 | _ = try astrl.expr(full.ast.cond_expr, block, ResultInfo.type_only); // bool | ||
| 405 | } | ||
| 406 | var new_block: Block = .{ | ||
| 407 | .parent = block, | ||
| 408 | .label = label, | ||
| 409 | .is_loop = true, | ||
| 410 | .ri = ri, | ||
| 411 | .consumes_res_ptr = false, | ||
| 412 | }; | ||
| 413 | if (full.ast.cont_expr != 0) { | ||
| 414 | _ = try astrl.expr(full.ast.cont_expr, &new_block, ResultInfo.none); | ||
| 415 | } | ||
| 416 | _ = try astrl.expr(full.ast.then_expr, &new_block, ResultInfo.none); | ||
| 417 | const else_consumes_rl = if (full.ast.else_expr != 0) else_rl: { | ||
| 418 | break :else_rl try astrl.expr(full.ast.else_expr, block, ri); | ||
| 419 | } else false; | ||
| 420 | if (new_block.consumes_res_ptr or else_consumes_rl) { | ||
| 421 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | ||
| 422 | return true; | ||
| 423 | } else { | ||
| 424 | return false; | ||
| 425 | } | ||
| 426 | }, | ||
| 427 | |||
| 428 | .for_simple, .@"for" => { | ||
| 429 | const full = tree.fullFor(node).?; | ||
| 430 | const label: ?[]const u8 = if (full.label_token) |label_token| label: { | ||
| 431 | break :label try astrl.identString(label_token); | ||
| 432 | } else null; | ||
| 433 | for (full.ast.inputs) |input| { | ||
| 434 | if (node_tags[input] == .for_range) { | ||
| 435 | _ = try astrl.expr(node_datas[input].lhs, block, ResultInfo.type_only); | ||
| 436 | if (node_datas[input].rhs != 0) { | ||
| 437 | _ = try astrl.expr(node_datas[input].rhs, block, ResultInfo.type_only); | ||
| 438 | } | ||
| 439 | } else { | ||
| 440 | _ = try astrl.expr(input, block, ResultInfo.none); | ||
| 441 | } | ||
| 442 | } | ||
| 443 | var new_block: Block = .{ | ||
| 444 | .parent = block, | ||
| 445 | .label = label, | ||
| 446 | .is_loop = true, | ||
| 447 | .ri = ri, | ||
| 448 | .consumes_res_ptr = false, | ||
| 449 | }; | ||
| 450 | _ = try astrl.expr(full.ast.then_expr, &new_block, ResultInfo.none); | ||
| 451 | const else_consumes_rl = if (full.ast.else_expr != 0) else_rl: { | ||
| 452 | break :else_rl try astrl.expr(full.ast.else_expr, block, ri); | ||
| 453 | } else false; | ||
| 454 | if (new_block.consumes_res_ptr or else_consumes_rl) { | ||
| 455 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | ||
| 456 | return true; | ||
| 457 | } else { | ||
| 458 | return false; | ||
| 459 | } | ||
| 460 | }, | ||
| 461 | |||
| 462 | .slice_open => { | ||
| 463 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 464 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.type_only); | ||
| 465 | return false; | ||
| 466 | }, | ||
| 467 | .slice => { | ||
| 468 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.Slice); | ||
| 469 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 470 | _ = try astrl.expr(extra.start, block, ResultInfo.type_only); | ||
| 471 | _ = try astrl.expr(extra.end, block, ResultInfo.type_only); | ||
| 472 | return false; | ||
| 473 | }, | ||
| 474 | .slice_sentinel => { | ||
| 475 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.SliceSentinel); | ||
| 476 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 477 | _ = try astrl.expr(extra.start, block, ResultInfo.type_only); | ||
| 478 | if (extra.end != 0) { | ||
| 479 | _ = try astrl.expr(extra.end, block, ResultInfo.type_only); | ||
| 480 | } | ||
| 481 | _ = try astrl.expr(extra.sentinel, block, ResultInfo.none); | ||
| 482 | return false; | ||
| 483 | }, | ||
| 484 | .deref => { | ||
| 485 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 486 | return false; | ||
| 487 | }, | ||
| 488 | .address_of => { | ||
| 489 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 490 | return false; | ||
| 491 | }, | ||
| 492 | .optional_type => { | ||
| 493 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.type_only); | ||
| 494 | return false; | ||
| 495 | }, | ||
| 496 | .grouped_expression, | ||
| 497 | .@"try", | ||
| 498 | .@"await", | ||
| 499 | .@"nosuspend", | ||
| 500 | .unwrap_optional, | ||
| 501 | => return astrl.expr(node_datas[node].lhs, block, ri), | ||
| 502 | |||
| 503 | .block_two, .block_two_semicolon => { | ||
| 504 | if (node_datas[node].lhs == 0) { | ||
| 505 | return astrl.blockExpr(block, ri, node, &.{}); | ||
| 506 | } else if (node_datas[node].rhs == 0) { | ||
| 507 | return astrl.blockExpr(block, ri, node, &.{node_datas[node].lhs}); | ||
| 508 | } else { | ||
| 509 | return astrl.blockExpr(block, ri, node, &.{ node_datas[node].lhs, node_datas[node].rhs }); | ||
| 510 | } | ||
| 511 | }, | ||
| 512 | .block, .block_semicolon => { | ||
| 513 | const statements = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs]; | ||
| 514 | return astrl.blockExpr(block, ri, node, statements); | ||
| 515 | }, | ||
| 516 | .anyframe_type => { | ||
| 517 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.type_only); | ||
| 518 | return false; | ||
| 519 | }, | ||
| 520 | .@"catch", .@"orelse" => { | ||
| 521 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 522 | const rhs_consumes_rl = try astrl.expr(node_datas[node].rhs, block, ri); | ||
| 523 | if (rhs_consumes_rl) { | ||
| 524 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | ||
| 525 | } | ||
| 526 | return rhs_consumes_rl; | ||
| 527 | }, | ||
| 528 | |||
| 529 | .ptr_type_aligned, | ||
| 530 | .ptr_type_sentinel, | ||
| 531 | .ptr_type, | ||
| 532 | .ptr_type_bit_range, | ||
| 533 | => { | ||
| 534 | const full = tree.fullPtrType(node).?; | ||
| 535 | _ = try astrl.expr(full.ast.child_type, block, ResultInfo.type_only); | ||
| 536 | if (full.ast.sentinel != 0) { | ||
| 537 | _ = try astrl.expr(full.ast.sentinel, block, ResultInfo.type_only); | ||
| 538 | } | ||
| 539 | if (full.ast.addrspace_node != 0) { | ||
| 540 | _ = try astrl.expr(full.ast.addrspace_node, block, ResultInfo.type_only); | ||
| 541 | } | ||
| 542 | if (full.ast.align_node != 0) { | ||
| 543 | _ = try astrl.expr(full.ast.align_node, block, ResultInfo.type_only); | ||
| 544 | } | ||
| 545 | if (full.ast.bit_range_start != 0) { | ||
| 546 | assert(full.ast.bit_range_end != 0); | ||
| 547 | _ = try astrl.expr(full.ast.bit_range_start, block, ResultInfo.type_only); | ||
| 548 | _ = try astrl.expr(full.ast.bit_range_end, block, ResultInfo.type_only); | ||
| 549 | } | ||
| 550 | return false; | ||
| 551 | }, | ||
| 552 | |||
| 553 | .container_decl, | ||
| 554 | .container_decl_trailing, | ||
| 555 | .container_decl_arg, | ||
| 556 | .container_decl_arg_trailing, | ||
| 557 | .container_decl_two, | ||
| 558 | .container_decl_two_trailing, | ||
| 559 | .tagged_union, | ||
| 560 | .tagged_union_trailing, | ||
| 561 | .tagged_union_enum_tag, | ||
| 562 | .tagged_union_enum_tag_trailing, | ||
| 563 | .tagged_union_two, | ||
| 564 | .tagged_union_two_trailing, | ||
| 565 | => { | ||
| 566 | var buf: [2]Ast.Node.Index = undefined; | ||
| 567 | try astrl.containerDecl(block, tree.fullContainerDecl(&buf, node).?); | ||
| 568 | return false; | ||
| 569 | }, | ||
| 570 | |||
| 571 | .@"break" => { | ||
| 572 | if (node_datas[node].rhs == 0) { | ||
| 573 | // Breaks with void are not interesting | ||
| 574 | return false; | ||
| 575 | } | ||
| 576 | |||
| 577 | var opt_cur_block = block; | ||
| 578 | if (node_datas[node].lhs == 0) { | ||
| 579 | // No label - we're breaking from a loop. | ||
| 580 | while (opt_cur_block) |cur_block| : (opt_cur_block = cur_block.parent) { | ||
| 581 | if (cur_block.is_loop) break; | ||
| 582 | } | ||
| 583 | } else { | ||
| 584 | const break_label = try astrl.identString(node_datas[node].lhs); | ||
| 585 | while (opt_cur_block) |cur_block| : (opt_cur_block = cur_block.parent) { | ||
| 586 | const block_label = cur_block.label orelse continue; | ||
| 587 | if (std.mem.eql(u8, block_label, break_label)) break; | ||
| 588 | } | ||
| 589 | } | ||
| 590 | |||
| 591 | if (opt_cur_block) |target_block| { | ||
| 592 | const consumes_break_rl = try astrl.expr(node_datas[node].rhs, block, target_block.ri); | ||
| 593 | if (consumes_break_rl) target_block.consumes_res_ptr = true; | ||
| 594 | } else { | ||
| 595 | // No corresponding scope to break from - AstGen will emit an error. | ||
| 596 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.none); | ||
| 597 | } | ||
| 598 | |||
| 599 | return false; | ||
| 600 | }, | ||
| 601 | |||
| 602 | .array_type => { | ||
| 603 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.type_only); | ||
| 604 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.type_only); | ||
| 605 | return false; | ||
| 606 | }, | ||
| 607 | .array_type_sentinel => { | ||
| 608 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.ArrayTypeSentinel); | ||
| 609 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.type_only); | ||
| 610 | _ = try astrl.expr(extra.elem_type, block, ResultInfo.type_only); | ||
| 611 | _ = try astrl.expr(extra.sentinel, block, ResultInfo.type_only); | ||
| 612 | return false; | ||
| 613 | }, | ||
| 614 | .array_access => { | ||
| 615 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 616 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.type_only); | ||
| 617 | return false; | ||
| 618 | }, | ||
| 619 | .@"comptime" => { | ||
| 620 | // AstGen will emit an error if the scope is already comptime, so we can assume it is | ||
| 621 | // not. This means the result location is not forwarded. | ||
| 622 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 623 | return false; | ||
| 624 | }, | ||
| 625 | .@"switch", .switch_comma => { | ||
| 626 | const operand_node = node_datas[node].lhs; | ||
| 627 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.SubRange); | ||
| 628 | const case_nodes = tree.extra_data[extra.start..extra.end]; | ||
| 629 | |||
| 630 | _ = try astrl.expr(operand_node, block, ResultInfo.none); | ||
| 631 | |||
| 632 | var any_prong_consumed_rl = false; | ||
| 633 | for (case_nodes) |case_node| { | ||
| 634 | const case = tree.fullSwitchCase(case_node).?; | ||
| 635 | for (case.ast.values) |item_node| { | ||
| 636 | if (node_tags[item_node] == .switch_range) { | ||
| 637 | _ = try astrl.expr(node_datas[item_node].lhs, block, ResultInfo.none); | ||
| 638 | _ = try astrl.expr(node_datas[item_node].rhs, block, ResultInfo.none); | ||
| 639 | } else { | ||
| 640 | _ = try astrl.expr(item_node, block, ResultInfo.none); | ||
| 641 | } | ||
| 642 | } | ||
| 643 | if (try astrl.expr(case.ast.target_expr, block, ri)) { | ||
| 644 | any_prong_consumed_rl = true; | ||
| 645 | } | ||
| 646 | } | ||
| 647 | if (any_prong_consumed_rl) { | ||
| 648 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | ||
| 649 | } | ||
| 650 | return any_prong_consumed_rl; | ||
| 651 | }, | ||
| 652 | .@"suspend" => { | ||
| 653 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 654 | return false; | ||
| 655 | }, | ||
| 656 | .@"resume" => { | ||
| 657 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | ||
| 658 | return false; | ||
| 659 | }, | ||
| 660 | |||
| 661 | .array_init_one, | ||
| 662 | .array_init_one_comma, | ||
| 663 | .array_init_dot_two, | ||
| 664 | .array_init_dot_two_comma, | ||
| 665 | .array_init_dot, | ||
| 666 | .array_init_dot_comma, | ||
| 667 | .array_init, | ||
| 668 | .array_init_comma, | ||
| 669 | => { | ||
| 670 | var buf: [2]Ast.Node.Index = undefined; | ||
| 671 | const full = tree.fullArrayInit(&buf, node).?; | ||
| 672 | |||
| 673 | if (full.ast.type_expr != 0) { | ||
| 674 | // Explicitly typed init does not participate in RLS | ||
| 675 | _ = try astrl.expr(full.ast.type_expr, block, ResultInfo.none); | ||
| 676 | for (full.ast.elements) |elem_init| { | ||
| 677 | _ = try astrl.expr(elem_init, block, ResultInfo.type_only); | ||
| 678 | } | ||
| 679 | return false; | ||
| 680 | } | ||
| 681 | |||
| 682 | if (ri.have_type) { | ||
| 683 | // Always forward type information | ||
| 684 | // If we have a result pointer, we use and forward it | ||
| 685 | for (full.ast.elements) |elem_init| { | ||
| 686 | _ = try astrl.expr(elem_init, block, ri); | ||
| 687 | } | ||
| 688 | return ri.have_ptr; | ||
| 689 | } else { | ||
| 690 | // Untyped init does not consume result location | ||
| 691 | for (full.ast.elements) |elem_init| { | ||
| 692 | _ = try astrl.expr(elem_init, block, ResultInfo.none); | ||
| 693 | } | ||
| 694 | return false; | ||
| 695 | } | ||
| 696 | }, | ||
| 697 | |||
| 698 | .struct_init_one, | ||
| 699 | .struct_init_one_comma, | ||
| 700 | .struct_init_dot_two, | ||
| 701 | .struct_init_dot_two_comma, | ||
| 702 | .struct_init_dot, | ||
| 703 | .struct_init_dot_comma, | ||
| 704 | .struct_init, | ||
| 705 | .struct_init_comma, | ||
| 706 | => { | ||
| 707 | var buf: [2]Ast.Node.Index = undefined; | ||
| 708 | const full = tree.fullStructInit(&buf, node).?; | ||
| 709 | |||
| 710 | if (full.ast.type_expr != 0) { | ||
| 711 | // Explicitly typed init does not participate in RLS | ||
| 712 | _ = try astrl.expr(full.ast.type_expr, block, ResultInfo.none); | ||
| 713 | for (full.ast.fields) |field_init| { | ||
| 714 | _ = try astrl.expr(field_init, block, ResultInfo.type_only); | ||
| 715 | } | ||
| 716 | return false; | ||
| 717 | } | ||
| 718 | |||
| 719 | if (ri.have_type) { | ||
| 720 | // Always forward type information | ||
| 721 | // If we have a result pointer, we use and forward it | ||
| 722 | for (full.ast.fields) |field_init| { | ||
| 723 | _ = try astrl.expr(field_init, block, ri); | ||
| 724 | } | ||
| 725 | return ri.have_ptr; | ||
| 726 | } else { | ||
| 727 | // Untyped init does not consume result location | ||
| 728 | for (full.ast.fields) |field_init| { | ||
| 729 | _ = try astrl.expr(field_init, block, ResultInfo.none); | ||
| 730 | } | ||
| 731 | return false; | ||
| 732 | } | ||
| 733 | }, | ||
| 734 | |||
| 735 | .fn_proto_simple, | ||
| 736 | .fn_proto_multi, | ||
| 737 | .fn_proto_one, | ||
| 738 | .fn_proto, | ||
| 739 | .fn_decl, | ||
| 740 | => { | ||
| 741 | var buf: [1]Ast.Node.Index = undefined; | ||
| 742 | const full = tree.fullFnProto(&buf, node).?; | ||
| 743 | const body_node = if (node_tags[node] == .fn_decl) node_datas[node].rhs else 0; | ||
| 744 | { | ||
| 745 | var it = full.iterate(tree); | ||
| 746 | while (it.next()) |param| { | ||
| 747 | if (param.anytype_ellipsis3 == null) { | ||
| 748 | _ = try astrl.expr(param.type_expr, block, ResultInfo.type_only); | ||
| 749 | } | ||
| 750 | } | ||
| 751 | } | ||
| 752 | if (full.ast.align_expr != 0) { | ||
| 753 | _ = try astrl.expr(full.ast.align_expr, block, ResultInfo.type_only); | ||
| 754 | } | ||
| 755 | if (full.ast.addrspace_expr != 0) { | ||
| 756 | _ = try astrl.expr(full.ast.addrspace_expr, block, ResultInfo.type_only); | ||
| 757 | } | ||
| 758 | if (full.ast.section_expr != 0) { | ||
| 759 | _ = try astrl.expr(full.ast.section_expr, block, ResultInfo.type_only); | ||
| 760 | } | ||
| 761 | if (full.ast.callconv_expr != 0) { | ||
| 762 | _ = try astrl.expr(full.ast.callconv_expr, block, ResultInfo.type_only); | ||
| 763 | } | ||
| 764 | _ = try astrl.expr(full.ast.return_type, block, ResultInfo.type_only); | ||
| 765 | if (body_node != 0) { | ||
| 766 | _ = try astrl.expr(body_node, block, ResultInfo.none); | ||
| 767 | } | ||
| 768 | return false; | ||
| 769 | }, | ||
| 770 | } | ||
| 771 | } | ||
| 772 | |||
| 773 | fn identString(astrl: *AstRlAnnotate, token: Ast.TokenIndex) ![]const u8 { | ||
| 774 | const tree = astrl.tree; | ||
| 775 | const token_tags = tree.tokens.items(.tag); | ||
| 776 | assert(token_tags[token] == .identifier); | ||
| 777 | const ident_name = tree.tokenSlice(token); | ||
| 778 | if (!std.mem.startsWith(u8, ident_name, "@")) { | ||
| 779 | return ident_name; | ||
| 780 | } | ||
| 781 | return std.zig.string_literal.parseAlloc(astrl.arena, ident_name[1..]) catch |err| switch (err) { | ||
| 782 | error.OutOfMemory => error.OutOfMemory, | ||
| 783 | error.InvalidLiteral => "", // This pass can safely return garbage on invalid AST | ||
| 784 | }; | ||
| 785 | } | ||
| 786 | |||
| 787 | fn blockExpr(astrl: *AstRlAnnotate, parent_block: ?*Block, ri: ResultInfo, node: Ast.Node.Index, statements: []const Ast.Node.Index) !bool { | ||
| 788 | const tree = astrl.tree; | ||
| 789 | const token_tags = tree.tokens.items(.tag); | ||
| 790 | const main_tokens = tree.nodes.items(.main_token); | ||
| 791 | |||
| 792 | const lbrace = main_tokens[node]; | ||
| 793 | if (token_tags[lbrace - 1] == .colon and | ||
| 794 | token_tags[lbrace - 2] == .identifier) | ||
| 795 | { | ||
| 796 | // Labeled block | ||
| 797 | var new_block: Block = .{ | ||
| 798 | .parent = parent_block, | ||
| 799 | .label = try astrl.identString(lbrace - 2), | ||
| 800 | .is_loop = false, | ||
| 801 | .ri = ri, | ||
| 802 | .consumes_res_ptr = false, | ||
| 803 | }; | ||
| 804 | for (statements) |statement| { | ||
| 805 | _ = try astrl.expr(statement, &new_block, ResultInfo.none); | ||
| 806 | } | ||
| 807 | if (new_block.consumes_res_ptr) { | ||
| 808 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | ||
| 809 | } | ||
| 810 | return new_block.consumes_res_ptr; | ||
| 811 | } else { | ||
| 812 | // Unlabeled block | ||
| 813 | for (statements) |statement| { | ||
| 814 | _ = try astrl.expr(statement, parent_block, ResultInfo.none); | ||
| 815 | } | ||
| 816 | return false; | ||
| 817 | } | ||
| 818 | } | ||
| 819 | |||
| 820 | fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast.Node.Index, args: []const Ast.Node.Index) !bool { | ||
| 821 | _ = ri; // Currently, no builtin consumes its result location. | ||
| 822 | |||
| 823 | const tree = astrl.tree; | ||
| 824 | const main_tokens = tree.nodes.items(.main_token); | ||
| 825 | const builtin_token = main_tokens[node]; | ||
| 826 | const builtin_name = tree.tokenSlice(builtin_token); | ||
| 827 | const info = BuiltinFn.list.get(builtin_name) orelse return false; | ||
| 828 | if (info.param_count) |expected| { | ||
| 829 | if (expected != args.len) return false; | ||
| 830 | } | ||
| 831 | switch (info.tag) { | ||
| 832 | .import => return false, | ||
| 833 | .compile_log, .TypeOf => { | ||
| 834 | for (args) |arg_node| { | ||
| 835 | _ = try astrl.expr(arg_node, block, ResultInfo.none); | ||
| 836 | } | ||
| 837 | return false; | ||
| 838 | }, | ||
| 839 | .as => { | ||
| 840 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 841 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 842 | return false; | ||
| 843 | }, | ||
| 844 | .bit_cast => { | ||
| 845 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 846 | return false; | ||
| 847 | }, | ||
| 848 | .union_init => { | ||
| 849 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 850 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 851 | _ = try astrl.expr(args[2], block, ResultInfo.type_only); | ||
| 852 | return false; | ||
| 853 | }, | ||
| 854 | .c_import => { | ||
| 855 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 856 | return false; | ||
| 857 | }, | ||
| 858 | .min, .max => { | ||
| 859 | for (args) |arg_node| { | ||
| 860 | _ = try astrl.expr(arg_node, block, ResultInfo.none); | ||
| 861 | } | ||
| 862 | return false; | ||
| 863 | }, | ||
| 864 | .@"export" => { | ||
| 865 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 866 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 867 | return false; | ||
| 868 | }, | ||
| 869 | .@"extern" => { | ||
| 870 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 871 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 872 | return false; | ||
| 873 | }, | ||
| 874 | // These builtins take no args and do not consume the result pointer. | ||
| 875 | .src, | ||
| 876 | .This, | ||
| 877 | .return_address, | ||
| 878 | .error_return_trace, | ||
| 879 | .frame, | ||
| 880 | .breakpoint, | ||
| 881 | .in_comptime, | ||
| 882 | .panic, | ||
| 883 | .trap, | ||
| 884 | .c_va_start, | ||
| 885 | => return false, | ||
| 886 | // TODO: this is a workaround for llvm/llvm-project#68409 | ||
| 887 | // Zig tracking issue: #16876 | ||
| 888 | .frame_address => return true, | ||
| 889 | // These builtins take a single argument with a known result type, but do not consume their | ||
| 890 | // result pointer. | ||
| 891 | .size_of, | ||
| 892 | .bit_size_of, | ||
| 893 | .align_of, | ||
| 894 | .compile_error, | ||
| 895 | .set_eval_branch_quota, | ||
| 896 | .int_from_bool, | ||
| 897 | .int_from_error, | ||
| 898 | .error_from_int, | ||
| 899 | .embed_file, | ||
| 900 | .error_name, | ||
| 901 | .set_runtime_safety, | ||
| 902 | .Type, | ||
| 903 | .c_undef, | ||
| 904 | .c_include, | ||
| 905 | .wasm_memory_size, | ||
| 906 | .splat, | ||
| 907 | .fence, | ||
| 908 | .set_float_mode, | ||
| 909 | .set_align_stack, | ||
| 910 | .set_cold, | ||
| 911 | .type_info, | ||
| 912 | .work_item_id, | ||
| 913 | .work_group_size, | ||
| 914 | .work_group_id, | ||
| 915 | => { | ||
| 916 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 917 | return false; | ||
| 918 | }, | ||
| 919 | // These builtins take a single argument with no result information and do not consume their | ||
| 920 | // result pointer. | ||
| 921 | .int_from_ptr, | ||
| 922 | .int_from_enum, | ||
| 923 | .sqrt, | ||
| 924 | .sin, | ||
| 925 | .cos, | ||
| 926 | .tan, | ||
| 927 | .exp, | ||
| 928 | .exp2, | ||
| 929 | .log, | ||
| 930 | .log2, | ||
| 931 | .log10, | ||
| 932 | .abs, | ||
| 933 | .floor, | ||
| 934 | .ceil, | ||
| 935 | .trunc, | ||
| 936 | .round, | ||
| 937 | .tag_name, | ||
| 938 | .type_name, | ||
| 939 | .Frame, | ||
| 940 | .frame_size, | ||
| 941 | .int_from_float, | ||
| 942 | .float_from_int, | ||
| 943 | .ptr_from_int, | ||
| 944 | .enum_from_int, | ||
| 945 | .float_cast, | ||
| 946 | .int_cast, | ||
| 947 | .truncate, | ||
| 948 | .error_cast, | ||
| 949 | .ptr_cast, | ||
| 950 | .align_cast, | ||
| 951 | .addrspace_cast, | ||
| 952 | .const_cast, | ||
| 953 | .volatile_cast, | ||
| 954 | .clz, | ||
| 955 | .ctz, | ||
| 956 | .pop_count, | ||
| 957 | .byte_swap, | ||
| 958 | .bit_reverse, | ||
| 959 | => { | ||
| 960 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 961 | return false; | ||
| 962 | }, | ||
| 963 | .div_exact, | ||
| 964 | .div_floor, | ||
| 965 | .div_trunc, | ||
| 966 | .mod, | ||
| 967 | .rem, | ||
| 968 | => { | ||
| 969 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 970 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 971 | return false; | ||
| 972 | }, | ||
| 973 | .shl_exact, .shr_exact => { | ||
| 974 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 975 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 976 | return false; | ||
| 977 | }, | ||
| 978 | .bit_offset_of, | ||
| 979 | .offset_of, | ||
| 980 | .field_parent_ptr, | ||
| 981 | .has_decl, | ||
| 982 | .has_field, | ||
| 983 | .field, | ||
| 984 | => { | ||
| 985 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 986 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 987 | return false; | ||
| 988 | }, | ||
| 989 | .wasm_memory_grow => { | ||
| 990 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 991 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 992 | return false; | ||
| 993 | }, | ||
| 994 | .c_define => { | ||
| 995 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 996 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 997 | return false; | ||
| 998 | }, | ||
| 999 | .reduce => { | ||
| 1000 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 1001 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 1002 | return false; | ||
| 1003 | }, | ||
| 1004 | .add_with_overflow, .sub_with_overflow, .mul_with_overflow, .shl_with_overflow => { | ||
| 1005 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 1006 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 1007 | return false; | ||
| 1008 | }, | ||
| 1009 | .atomic_load => { | ||
| 1010 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 1011 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 1012 | _ = try astrl.expr(args[2], block, ResultInfo.type_only); | ||
| 1013 | return false; | ||
| 1014 | }, | ||
| 1015 | .atomic_rmw => { | ||
| 1016 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 1017 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 1018 | _ = try astrl.expr(args[2], block, ResultInfo.type_only); | ||
| 1019 | _ = try astrl.expr(args[3], block, ResultInfo.type_only); | ||
| 1020 | _ = try astrl.expr(args[4], block, ResultInfo.type_only); | ||
| 1021 | return false; | ||
| 1022 | }, | ||
| 1023 | .atomic_store => { | ||
| 1024 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 1025 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 1026 | _ = try astrl.expr(args[2], block, ResultInfo.type_only); | ||
| 1027 | _ = try astrl.expr(args[3], block, ResultInfo.type_only); | ||
| 1028 | return false; | ||
| 1029 | }, | ||
| 1030 | .mul_add => { | ||
| 1031 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 1032 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 1033 | _ = try astrl.expr(args[2], block, ResultInfo.type_only); | ||
| 1034 | return false; | ||
| 1035 | }, | ||
| 1036 | .call => { | ||
| 1037 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 1038 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 1039 | _ = try astrl.expr(args[2], block, ResultInfo.none); | ||
| 1040 | return false; | ||
| 1041 | }, | ||
| 1042 | .memcpy => { | ||
| 1043 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 1044 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 1045 | return false; | ||
| 1046 | }, | ||
| 1047 | .memset => { | ||
| 1048 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 1049 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 1050 | return false; | ||
| 1051 | }, | ||
| 1052 | .shuffle => { | ||
| 1053 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 1054 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 1055 | _ = try astrl.expr(args[2], block, ResultInfo.none); | ||
| 1056 | _ = try astrl.expr(args[3], block, ResultInfo.none); | ||
| 1057 | return false; | ||
| 1058 | }, | ||
| 1059 | .select => { | ||
| 1060 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 1061 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 1062 | _ = try astrl.expr(args[2], block, ResultInfo.none); | ||
| 1063 | _ = try astrl.expr(args[3], block, ResultInfo.none); | ||
| 1064 | return false; | ||
| 1065 | }, | ||
| 1066 | .async_call => { | ||
| 1067 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 1068 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 1069 | _ = try astrl.expr(args[2], block, ResultInfo.none); | ||
| 1070 | _ = try astrl.expr(args[3], block, ResultInfo.none); | ||
| 1071 | return false; // buffer passed as arg for frame data | ||
| 1072 | }, | ||
| 1073 | .Vector => { | ||
| 1074 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | ||
| 1075 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 1076 | return false; | ||
| 1077 | }, | ||
| 1078 | .prefetch => { | ||
| 1079 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 1080 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 1081 | return false; | ||
| 1082 | }, | ||
| 1083 | .c_va_arg => { | ||
| 1084 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 1085 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 1086 | return false; | ||
| 1087 | }, | ||
| 1088 | .c_va_copy => { | ||
| 1089 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 1090 | return false; | ||
| 1091 | }, | ||
| 1092 | .c_va_end => { | ||
| 1093 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 1094 | return false; | ||
| 1095 | }, | ||
| 1096 | .cmpxchg_strong, .cmpxchg_weak => { | ||
| 1097 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 1098 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); | ||
| 1099 | _ = try astrl.expr(args[2], block, ResultInfo.type_only); | ||
| 1100 | _ = try astrl.expr(args[3], block, ResultInfo.type_only); | ||
| 1101 | _ = try astrl.expr(args[4], block, ResultInfo.type_only); | ||
| 1102 | return false; | ||
| 1103 | }, | ||
| 1104 | } | ||
| 1105 | } | ||
src/BuiltinFn.zig deleted-1017| ... | @@ -1,1017 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | pub const Tag = enum { | ||
| 4 | add_with_overflow, | ||
| 5 | addrspace_cast, | ||
| 6 | align_cast, | ||
| 7 | align_of, | ||
| 8 | as, | ||
| 9 | async_call, | ||
| 10 | atomic_load, | ||
| 11 | atomic_rmw, | ||
| 12 | atomic_store, | ||
| 13 | bit_cast, | ||
| 14 | bit_offset_of, | ||
| 15 | int_from_bool, | ||
| 16 | bit_size_of, | ||
| 17 | breakpoint, | ||
| 18 | mul_add, | ||
| 19 | byte_swap, | ||
| 20 | bit_reverse, | ||
| 21 | offset_of, | ||
| 22 | call, | ||
| 23 | c_define, | ||
| 24 | c_import, | ||
| 25 | c_include, | ||
| 26 | clz, | ||
| 27 | cmpxchg_strong, | ||
| 28 | cmpxchg_weak, | ||
| 29 | compile_error, | ||
| 30 | compile_log, | ||
| 31 | const_cast, | ||
| 32 | ctz, | ||
| 33 | c_undef, | ||
| 34 | c_va_arg, | ||
| 35 | c_va_copy, | ||
| 36 | c_va_end, | ||
| 37 | c_va_start, | ||
| 38 | div_exact, | ||
| 39 | div_floor, | ||
| 40 | div_trunc, | ||
| 41 | embed_file, | ||
| 42 | int_from_enum, | ||
| 43 | error_name, | ||
| 44 | error_return_trace, | ||
| 45 | int_from_error, | ||
| 46 | error_cast, | ||
| 47 | @"export", | ||
| 48 | @"extern", | ||
| 49 | fence, | ||
| 50 | field, | ||
| 51 | field_parent_ptr, | ||
| 52 | float_cast, | ||
| 53 | int_from_float, | ||
| 54 | frame, | ||
| 55 | Frame, | ||
| 56 | frame_address, | ||
| 57 | frame_size, | ||
| 58 | has_decl, | ||
| 59 | has_field, | ||
| 60 | import, | ||
| 61 | in_comptime, | ||
| 62 | int_cast, | ||
| 63 | enum_from_int, | ||
| 64 | error_from_int, | ||
| 65 | float_from_int, | ||
| 66 | ptr_from_int, | ||
| 67 | max, | ||
| 68 | memcpy, | ||
| 69 | memset, | ||
| 70 | min, | ||
| 71 | wasm_memory_size, | ||
| 72 | wasm_memory_grow, | ||
| 73 | mod, | ||
| 74 | mul_with_overflow, | ||
| 75 | panic, | ||
| 76 | pop_count, | ||
| 77 | prefetch, | ||
| 78 | ptr_cast, | ||
| 79 | int_from_ptr, | ||
| 80 | rem, | ||
| 81 | return_address, | ||
| 82 | select, | ||
| 83 | set_align_stack, | ||
| 84 | set_cold, | ||
| 85 | set_eval_branch_quota, | ||
| 86 | set_float_mode, | ||
| 87 | set_runtime_safety, | ||
| 88 | shl_exact, | ||
| 89 | shl_with_overflow, | ||
| 90 | shr_exact, | ||
| 91 | shuffle, | ||
| 92 | size_of, | ||
| 93 | splat, | ||
| 94 | reduce, | ||
| 95 | src, | ||
| 96 | sqrt, | ||
| 97 | sin, | ||
| 98 | cos, | ||
| 99 | tan, | ||
| 100 | exp, | ||
| 101 | exp2, | ||
| 102 | log, | ||
| 103 | log2, | ||
| 104 | log10, | ||
| 105 | abs, | ||
| 106 | floor, | ||
| 107 | ceil, | ||
| 108 | trunc, | ||
| 109 | round, | ||
| 110 | sub_with_overflow, | ||
| 111 | tag_name, | ||
| 112 | This, | ||
| 113 | trap, | ||
| 114 | truncate, | ||
| 115 | Type, | ||
| 116 | type_info, | ||
| 117 | type_name, | ||
| 118 | TypeOf, | ||
| 119 | union_init, | ||
| 120 | Vector, | ||
| 121 | volatile_cast, | ||
| 122 | work_item_id, | ||
| 123 | work_group_size, | ||
| 124 | work_group_id, | ||
| 125 | }; | ||
| 126 | |||
| 127 | pub const MemLocRequirement = enum { | ||
| 128 | /// The builtin never needs a memory location. | ||
| 129 | never, | ||
| 130 | /// The builtin always needs a memory location. | ||
| 131 | always, | ||
| 132 | /// The builtin forwards the question to argument at index 0. | ||
| 133 | forward0, | ||
| 134 | /// The builtin forwards the question to argument at index 1. | ||
| 135 | forward1, | ||
| 136 | }; | ||
| 137 | |||
| 138 | pub const EvalToError = enum { | ||
| 139 | /// The builtin cannot possibly evaluate to an error. | ||
| 140 | never, | ||
| 141 | /// The builtin will always evaluate to an error. | ||
| 142 | always, | ||
| 143 | /// The builtin may or may not evaluate to an error depending on the parameters. | ||
| 144 | maybe, | ||
| 145 | }; | ||
| 146 | |||
| 147 | tag: Tag, | ||
| 148 | |||
| 149 | /// Info about the builtin call's ability to take advantage of a result location pointer. | ||
| 150 | needs_mem_loc: MemLocRequirement = .never, | ||
| 151 | /// Info about the builtin call's possibility of returning an error. | ||
| 152 | eval_to_error: EvalToError = .never, | ||
| 153 | /// `true` if the builtin call can be the left-hand side of an expression (assigned to). | ||
| 154 | allows_lvalue: bool = false, | ||
| 155 | /// The number of parameters to this builtin function. `null` means variable number | ||
| 156 | /// of parameters. | ||
| 157 | param_count: ?u8, | ||
| 158 | |||
| 159 | pub const list = list: { | ||
| 160 | @setEvalBranchQuota(3000); | ||
| 161 | break :list std.ComptimeStringMap(@This(), .{ | ||
| 162 | .{ | ||
| 163 | "@addWithOverflow", | ||
| 164 | .{ | ||
| 165 | .tag = .add_with_overflow, | ||
| 166 | .param_count = 2, | ||
| 167 | }, | ||
| 168 | }, | ||
| 169 | .{ | ||
| 170 | "@addrSpaceCast", | ||
| 171 | .{ | ||
| 172 | .tag = .addrspace_cast, | ||
| 173 | .param_count = 1, | ||
| 174 | }, | ||
| 175 | }, | ||
| 176 | .{ | ||
| 177 | "@alignCast", | ||
| 178 | .{ | ||
| 179 | .tag = .align_cast, | ||
| 180 | .param_count = 1, | ||
| 181 | }, | ||
| 182 | }, | ||
| 183 | .{ | ||
| 184 | "@alignOf", | ||
| 185 | .{ | ||
| 186 | .tag = .align_of, | ||
| 187 | .param_count = 1, | ||
| 188 | }, | ||
| 189 | }, | ||
| 190 | .{ | ||
| 191 | "@as", | ||
| 192 | .{ | ||
| 193 | .tag = .as, | ||
| 194 | .needs_mem_loc = .forward1, | ||
| 195 | .eval_to_error = .maybe, | ||
| 196 | .param_count = 2, | ||
| 197 | }, | ||
| 198 | }, | ||
| 199 | .{ | ||
| 200 | "@asyncCall", | ||
| 201 | .{ | ||
| 202 | .tag = .async_call, | ||
| 203 | .param_count = 4, | ||
| 204 | }, | ||
| 205 | }, | ||
| 206 | .{ | ||
| 207 | "@atomicLoad", | ||
| 208 | .{ | ||
| 209 | .tag = .atomic_load, | ||
| 210 | .param_count = 3, | ||
| 211 | }, | ||
| 212 | }, | ||
| 213 | .{ | ||
| 214 | "@atomicRmw", | ||
| 215 | .{ | ||
| 216 | .tag = .atomic_rmw, | ||
| 217 | .param_count = 5, | ||
| 218 | }, | ||
| 219 | }, | ||
| 220 | .{ | ||
| 221 | "@atomicStore", | ||
| 222 | .{ | ||
| 223 | .tag = .atomic_store, | ||
| 224 | .param_count = 4, | ||
| 225 | }, | ||
| 226 | }, | ||
| 227 | .{ | ||
| 228 | "@bitCast", | ||
| 229 | .{ | ||
| 230 | .tag = .bit_cast, | ||
| 231 | .needs_mem_loc = .forward0, | ||
| 232 | .param_count = 1, | ||
| 233 | }, | ||
| 234 | }, | ||
| 235 | .{ | ||
| 236 | "@bitOffsetOf", | ||
| 237 | .{ | ||
| 238 | .tag = .bit_offset_of, | ||
| 239 | .param_count = 2, | ||
| 240 | }, | ||
| 241 | }, | ||
| 242 | .{ | ||
| 243 | "@intFromBool", | ||
| 244 | .{ | ||
| 245 | .tag = .int_from_bool, | ||
| 246 | .param_count = 1, | ||
| 247 | }, | ||
| 248 | }, | ||
| 249 | .{ | ||
| 250 | "@bitSizeOf", | ||
| 251 | .{ | ||
| 252 | .tag = .bit_size_of, | ||
| 253 | .param_count = 1, | ||
| 254 | }, | ||
| 255 | }, | ||
| 256 | .{ | ||
| 257 | "@breakpoint", | ||
| 258 | .{ | ||
| 259 | .tag = .breakpoint, | ||
| 260 | .param_count = 0, | ||
| 261 | }, | ||
| 262 | }, | ||
| 263 | .{ | ||
| 264 | "@mulAdd", | ||
| 265 | .{ | ||
| 266 | .tag = .mul_add, | ||
| 267 | .param_count = 4, | ||
| 268 | }, | ||
| 269 | }, | ||
| 270 | .{ | ||
| 271 | "@byteSwap", | ||
| 272 | .{ | ||
| 273 | .tag = .byte_swap, | ||
| 274 | .param_count = 1, | ||
| 275 | }, | ||
| 276 | }, | ||
| 277 | .{ | ||
| 278 | "@bitReverse", | ||
| 279 | .{ | ||
| 280 | .tag = .bit_reverse, | ||
| 281 | .param_count = 1, | ||
| 282 | }, | ||
| 283 | }, | ||
| 284 | .{ | ||
| 285 | "@offsetOf", | ||
| 286 | .{ | ||
| 287 | .tag = .offset_of, | ||
| 288 | .param_count = 2, | ||
| 289 | }, | ||
| 290 | }, | ||
| 291 | .{ | ||
| 292 | "@call", | ||
| 293 | .{ | ||
| 294 | .tag = .call, | ||
| 295 | .needs_mem_loc = .always, | ||
| 296 | .eval_to_error = .maybe, | ||
| 297 | .param_count = 3, | ||
| 298 | }, | ||
| 299 | }, | ||
| 300 | .{ | ||
| 301 | "@cDefine", | ||
| 302 | .{ | ||
| 303 | .tag = .c_define, | ||
| 304 | .param_count = 2, | ||
| 305 | }, | ||
| 306 | }, | ||
| 307 | .{ | ||
| 308 | "@cImport", | ||
| 309 | .{ | ||
| 310 | .tag = .c_import, | ||
| 311 | .param_count = 1, | ||
| 312 | }, | ||
| 313 | }, | ||
| 314 | .{ | ||
| 315 | "@cInclude", | ||
| 316 | .{ | ||
| 317 | .tag = .c_include, | ||
| 318 | .param_count = 1, | ||
| 319 | }, | ||
| 320 | }, | ||
| 321 | .{ | ||
| 322 | "@clz", | ||
| 323 | .{ | ||
| 324 | .tag = .clz, | ||
| 325 | .param_count = 1, | ||
| 326 | }, | ||
| 327 | }, | ||
| 328 | .{ | ||
| 329 | "@cmpxchgStrong", | ||
| 330 | .{ | ||
| 331 | .tag = .cmpxchg_strong, | ||
| 332 | .param_count = 6, | ||
| 333 | }, | ||
| 334 | }, | ||
| 335 | .{ | ||
| 336 | "@cmpxchgWeak", | ||
| 337 | .{ | ||
| 338 | .tag = .cmpxchg_weak, | ||
| 339 | .param_count = 6, | ||
| 340 | }, | ||
| 341 | }, | ||
| 342 | .{ | ||
| 343 | "@compileError", | ||
| 344 | .{ | ||
| 345 | .tag = .compile_error, | ||
| 346 | .param_count = 1, | ||
| 347 | }, | ||
| 348 | }, | ||
| 349 | .{ | ||
| 350 | "@compileLog", | ||
| 351 | .{ | ||
| 352 | .tag = .compile_log, | ||
| 353 | .param_count = null, | ||
| 354 | }, | ||
| 355 | }, | ||
| 356 | .{ | ||
| 357 | "@constCast", | ||
| 358 | .{ | ||
| 359 | .tag = .const_cast, | ||
| 360 | .param_count = 1, | ||
| 361 | }, | ||
| 362 | }, | ||
| 363 | .{ | ||
| 364 | "@ctz", | ||
| 365 | .{ | ||
| 366 | .tag = .ctz, | ||
| 367 | .param_count = 1, | ||
| 368 | }, | ||
| 369 | }, | ||
| 370 | .{ | ||
| 371 | "@cUndef", | ||
| 372 | .{ | ||
| 373 | .tag = .c_undef, | ||
| 374 | .param_count = 1, | ||
| 375 | }, | ||
| 376 | }, | ||
| 377 | .{ | ||
| 378 | "@cVaArg", .{ | ||
| 379 | .tag = .c_va_arg, | ||
| 380 | .param_count = 2, | ||
| 381 | }, | ||
| 382 | }, | ||
| 383 | .{ | ||
| 384 | "@cVaCopy", .{ | ||
| 385 | .tag = .c_va_copy, | ||
| 386 | .param_count = 1, | ||
| 387 | }, | ||
| 388 | }, | ||
| 389 | .{ | ||
| 390 | "@cVaEnd", .{ | ||
| 391 | .tag = .c_va_end, | ||
| 392 | .param_count = 1, | ||
| 393 | }, | ||
| 394 | }, | ||
| 395 | .{ | ||
| 396 | "@cVaStart", .{ | ||
| 397 | .tag = .c_va_start, | ||
| 398 | .param_count = 0, | ||
| 399 | }, | ||
| 400 | }, | ||
| 401 | .{ | ||
| 402 | "@divExact", | ||
| 403 | .{ | ||
| 404 | .tag = .div_exact, | ||
| 405 | .param_count = 2, | ||
| 406 | }, | ||
| 407 | }, | ||
| 408 | .{ | ||
| 409 | "@divFloor", | ||
| 410 | .{ | ||
| 411 | .tag = .div_floor, | ||
| 412 | .param_count = 2, | ||
| 413 | }, | ||
| 414 | }, | ||
| 415 | .{ | ||
| 416 | "@divTrunc", | ||
| 417 | .{ | ||
| 418 | .tag = .div_trunc, | ||
| 419 | .param_count = 2, | ||
| 420 | }, | ||
| 421 | }, | ||
| 422 | .{ | ||
| 423 | "@embedFile", | ||
| 424 | .{ | ||
| 425 | .tag = .embed_file, | ||
| 426 | .param_count = 1, | ||
| 427 | }, | ||
| 428 | }, | ||
| 429 | .{ | ||
| 430 | "@intFromEnum", | ||
| 431 | .{ | ||
| 432 | .tag = .int_from_enum, | ||
| 433 | .param_count = 1, | ||
| 434 | }, | ||
| 435 | }, | ||
| 436 | .{ | ||
| 437 | "@errorName", | ||
| 438 | .{ | ||
| 439 | .tag = .error_name, | ||
| 440 | .param_count = 1, | ||
| 441 | }, | ||
| 442 | }, | ||
| 443 | .{ | ||
| 444 | "@errorReturnTrace", | ||
| 445 | .{ | ||
| 446 | .tag = .error_return_trace, | ||
| 447 | .param_count = 0, | ||
| 448 | }, | ||
| 449 | }, | ||
| 450 | .{ | ||
| 451 | "@intFromError", | ||
| 452 | .{ | ||
| 453 | .tag = .int_from_error, | ||
| 454 | .param_count = 1, | ||
| 455 | }, | ||
| 456 | }, | ||
| 457 | .{ | ||
| 458 | "@errorCast", | ||
| 459 | .{ | ||
| 460 | .tag = .error_cast, | ||
| 461 | .eval_to_error = .always, | ||
| 462 | .param_count = 1, | ||
| 463 | }, | ||
| 464 | }, | ||
| 465 | .{ | ||
| 466 | "@export", | ||
| 467 | .{ | ||
| 468 | .tag = .@"export", | ||
| 469 | .param_count = 2, | ||
| 470 | }, | ||
| 471 | }, | ||
| 472 | .{ | ||
| 473 | "@extern", | ||
| 474 | .{ | ||
| 475 | .tag = .@"extern", | ||
| 476 | .param_count = 2, | ||
| 477 | }, | ||
| 478 | }, | ||
| 479 | .{ | ||
| 480 | "@fence", | ||
| 481 | .{ | ||
| 482 | .tag = .fence, | ||
| 483 | .param_count = 1, | ||
| 484 | }, | ||
| 485 | }, | ||
| 486 | .{ | ||
| 487 | "@field", | ||
| 488 | .{ | ||
| 489 | .tag = .field, | ||
| 490 | .needs_mem_loc = .always, | ||
| 491 | .eval_to_error = .maybe, | ||
| 492 | .param_count = 2, | ||
| 493 | .allows_lvalue = true, | ||
| 494 | }, | ||
| 495 | }, | ||
| 496 | .{ | ||
| 497 | "@fieldParentPtr", | ||
| 498 | .{ | ||
| 499 | .tag = .field_parent_ptr, | ||
| 500 | .param_count = 3, | ||
| 501 | }, | ||
| 502 | }, | ||
| 503 | .{ | ||
| 504 | "@floatCast", | ||
| 505 | .{ | ||
| 506 | .tag = .float_cast, | ||
| 507 | .param_count = 1, | ||
| 508 | }, | ||
| 509 | }, | ||
| 510 | .{ | ||
| 511 | "@intFromFloat", | ||
| 512 | .{ | ||
| 513 | .tag = .int_from_float, | ||
| 514 | .param_count = 1, | ||
| 515 | }, | ||
| 516 | }, | ||
| 517 | .{ | ||
| 518 | "@frame", | ||
| 519 | .{ | ||
| 520 | .tag = .frame, | ||
| 521 | .param_count = 0, | ||
| 522 | }, | ||
| 523 | }, | ||
| 524 | .{ | ||
| 525 | "@Frame", | ||
| 526 | .{ | ||
| 527 | .tag = .Frame, | ||
| 528 | .param_count = 1, | ||
| 529 | }, | ||
| 530 | }, | ||
| 531 | .{ | ||
| 532 | "@frameAddress", | ||
| 533 | .{ | ||
| 534 | .tag = .frame_address, | ||
| 535 | .param_count = 0, | ||
| 536 | }, | ||
| 537 | }, | ||
| 538 | .{ | ||
| 539 | "@frameSize", | ||
| 540 | .{ | ||
| 541 | .tag = .frame_size, | ||
| 542 | .param_count = 1, | ||
| 543 | }, | ||
| 544 | }, | ||
| 545 | .{ | ||
| 546 | "@hasDecl", | ||
| 547 | .{ | ||
| 548 | .tag = .has_decl, | ||
| 549 | .param_count = 2, | ||
| 550 | }, | ||
| 551 | }, | ||
| 552 | .{ | ||
| 553 | "@hasField", | ||
| 554 | .{ | ||
| 555 | .tag = .has_field, | ||
| 556 | .param_count = 2, | ||
| 557 | }, | ||
| 558 | }, | ||
| 559 | .{ | ||
| 560 | "@import", | ||
| 561 | .{ | ||
| 562 | .tag = .import, | ||
| 563 | .param_count = 1, | ||
| 564 | }, | ||
| 565 | }, | ||
| 566 | .{ | ||
| 567 | "@inComptime", | ||
| 568 | .{ | ||
| 569 | .tag = .in_comptime, | ||
| 570 | .param_count = 0, | ||
| 571 | }, | ||
| 572 | }, | ||
| 573 | .{ | ||
| 574 | "@intCast", | ||
| 575 | .{ | ||
| 576 | .tag = .int_cast, | ||
| 577 | .param_count = 1, | ||
| 578 | }, | ||
| 579 | }, | ||
| 580 | .{ | ||
| 581 | "@enumFromInt", | ||
| 582 | .{ | ||
| 583 | .tag = .enum_from_int, | ||
| 584 | .param_count = 1, | ||
| 585 | }, | ||
| 586 | }, | ||
| 587 | .{ | ||
| 588 | "@errorFromInt", | ||
| 589 | .{ | ||
| 590 | .tag = .error_from_int, | ||
| 591 | .eval_to_error = .always, | ||
| 592 | .param_count = 1, | ||
| 593 | }, | ||
| 594 | }, | ||
| 595 | .{ | ||
| 596 | "@floatFromInt", | ||
| 597 | .{ | ||
| 598 | .tag = .float_from_int, | ||
| 599 | .param_count = 1, | ||
| 600 | }, | ||
| 601 | }, | ||
| 602 | .{ | ||
| 603 | "@ptrFromInt", | ||
| 604 | .{ | ||
| 605 | .tag = .ptr_from_int, | ||
| 606 | .param_count = 1, | ||
| 607 | }, | ||
| 608 | }, | ||
| 609 | .{ | ||
| 610 | "@max", | ||
| 611 | .{ | ||
| 612 | .tag = .max, | ||
| 613 | .param_count = null, | ||
| 614 | }, | ||
| 615 | }, | ||
| 616 | .{ | ||
| 617 | "@memcpy", | ||
| 618 | .{ | ||
| 619 | .tag = .memcpy, | ||
| 620 | .param_count = 2, | ||
| 621 | }, | ||
| 622 | }, | ||
| 623 | .{ | ||
| 624 | "@memset", | ||
| 625 | .{ | ||
| 626 | .tag = .memset, | ||
| 627 | .param_count = 2, | ||
| 628 | }, | ||
| 629 | }, | ||
| 630 | .{ | ||
| 631 | "@min", | ||
| 632 | .{ | ||
| 633 | .tag = .min, | ||
| 634 | .param_count = null, | ||
| 635 | }, | ||
| 636 | }, | ||
| 637 | .{ | ||
| 638 | "@wasmMemorySize", | ||
| 639 | .{ | ||
| 640 | .tag = .wasm_memory_size, | ||
| 641 | .param_count = 1, | ||
| 642 | }, | ||
| 643 | }, | ||
| 644 | .{ | ||
| 645 | "@wasmMemoryGrow", | ||
| 646 | .{ | ||
| 647 | .tag = .wasm_memory_grow, | ||
| 648 | .param_count = 2, | ||
| 649 | }, | ||
| 650 | }, | ||
| 651 | .{ | ||
| 652 | "@mod", | ||
| 653 | .{ | ||
| 654 | .tag = .mod, | ||
| 655 | .param_count = 2, | ||
| 656 | }, | ||
| 657 | }, | ||
| 658 | .{ | ||
| 659 | "@mulWithOverflow", | ||
| 660 | .{ | ||
| 661 | .tag = .mul_with_overflow, | ||
| 662 | .param_count = 2, | ||
| 663 | }, | ||
| 664 | }, | ||
| 665 | .{ | ||
| 666 | "@panic", | ||
| 667 | .{ | ||
| 668 | .tag = .panic, | ||
| 669 | .param_count = 1, | ||
| 670 | }, | ||
| 671 | }, | ||
| 672 | .{ | ||
| 673 | "@popCount", | ||
| 674 | .{ | ||
| 675 | .tag = .pop_count, | ||
| 676 | .param_count = 1, | ||
| 677 | }, | ||
| 678 | }, | ||
| 679 | .{ | ||
| 680 | "@prefetch", | ||
| 681 | .{ | ||
| 682 | .tag = .prefetch, | ||
| 683 | .param_count = 2, | ||
| 684 | }, | ||
| 685 | }, | ||
| 686 | .{ | ||
| 687 | "@ptrCast", | ||
| 688 | .{ | ||
| 689 | .tag = .ptr_cast, | ||
| 690 | .param_count = 1, | ||
| 691 | }, | ||
| 692 | }, | ||
| 693 | .{ | ||
| 694 | "@intFromPtr", | ||
| 695 | .{ | ||
| 696 | .tag = .int_from_ptr, | ||
| 697 | .param_count = 1, | ||
| 698 | }, | ||
| 699 | }, | ||
| 700 | .{ | ||
| 701 | "@rem", | ||
| 702 | .{ | ||
| 703 | .tag = .rem, | ||
| 704 | .param_count = 2, | ||
| 705 | }, | ||
| 706 | }, | ||
| 707 | .{ | ||
| 708 | "@returnAddress", | ||
| 709 | .{ | ||
| 710 | .tag = .return_address, | ||
| 711 | .param_count = 0, | ||
| 712 | }, | ||
| 713 | }, | ||
| 714 | .{ | ||
| 715 | "@select", | ||
| 716 | .{ | ||
| 717 | .tag = .select, | ||
| 718 | .param_count = 4, | ||
| 719 | }, | ||
| 720 | }, | ||
| 721 | .{ | ||
| 722 | "@setAlignStack", | ||
| 723 | .{ | ||
| 724 | .tag = .set_align_stack, | ||
| 725 | .param_count = 1, | ||
| 726 | }, | ||
| 727 | }, | ||
| 728 | .{ | ||
| 729 | "@setCold", | ||
| 730 | .{ | ||
| 731 | .tag = .set_cold, | ||
| 732 | .param_count = 1, | ||
| 733 | }, | ||
| 734 | }, | ||
| 735 | .{ | ||
| 736 | "@setEvalBranchQuota", | ||
| 737 | .{ | ||
| 738 | .tag = .set_eval_branch_quota, | ||
| 739 | .param_count = 1, | ||
| 740 | }, | ||
| 741 | }, | ||
| 742 | .{ | ||
| 743 | "@setFloatMode", | ||
| 744 | .{ | ||
| 745 | .tag = .set_float_mode, | ||
| 746 | .param_count = 1, | ||
| 747 | }, | ||
| 748 | }, | ||
| 749 | .{ | ||
| 750 | "@setRuntimeSafety", | ||
| 751 | .{ | ||
| 752 | .tag = .set_runtime_safety, | ||
| 753 | .param_count = 1, | ||
| 754 | }, | ||
| 755 | }, | ||
| 756 | .{ | ||
| 757 | "@shlExact", | ||
| 758 | .{ | ||
| 759 | .tag = .shl_exact, | ||
| 760 | .param_count = 2, | ||
| 761 | }, | ||
| 762 | }, | ||
| 763 | .{ | ||
| 764 | "@shlWithOverflow", | ||
| 765 | .{ | ||
| 766 | .tag = .shl_with_overflow, | ||
| 767 | .param_count = 2, | ||
| 768 | }, | ||
| 769 | }, | ||
| 770 | .{ | ||
| 771 | "@shrExact", | ||
| 772 | .{ | ||
| 773 | .tag = .shr_exact, | ||
| 774 | .param_count = 2, | ||
| 775 | }, | ||
| 776 | }, | ||
| 777 | .{ | ||
| 778 | "@shuffle", | ||
| 779 | .{ | ||
| 780 | .tag = .shuffle, | ||
| 781 | .param_count = 4, | ||
| 782 | }, | ||
| 783 | }, | ||
| 784 | .{ | ||
| 785 | "@sizeOf", | ||
| 786 | .{ | ||
| 787 | .tag = .size_of, | ||
| 788 | .param_count = 1, | ||
| 789 | }, | ||
| 790 | }, | ||
| 791 | .{ | ||
| 792 | "@splat", | ||
| 793 | .{ | ||
| 794 | .tag = .splat, | ||
| 795 | .param_count = 1, | ||
| 796 | }, | ||
| 797 | }, | ||
| 798 | .{ | ||
| 799 | "@reduce", | ||
| 800 | .{ | ||
| 801 | .tag = .reduce, | ||
| 802 | .param_count = 2, | ||
| 803 | }, | ||
| 804 | }, | ||
| 805 | .{ | ||
| 806 | "@src", | ||
| 807 | .{ | ||
| 808 | .tag = .src, | ||
| 809 | .needs_mem_loc = .always, | ||
| 810 | .param_count = 0, | ||
| 811 | }, | ||
| 812 | }, | ||
| 813 | .{ | ||
| 814 | "@sqrt", | ||
| 815 | .{ | ||
| 816 | .tag = .sqrt, | ||
| 817 | .param_count = 1, | ||
| 818 | }, | ||
| 819 | }, | ||
| 820 | .{ | ||
| 821 | "@sin", | ||
| 822 | .{ | ||
| 823 | .tag = .sin, | ||
| 824 | .param_count = 1, | ||
| 825 | }, | ||
| 826 | }, | ||
| 827 | .{ | ||
| 828 | "@cos", | ||
| 829 | .{ | ||
| 830 | .tag = .cos, | ||
| 831 | .param_count = 1, | ||
| 832 | }, | ||
| 833 | }, | ||
| 834 | .{ | ||
| 835 | "@tan", | ||
| 836 | .{ | ||
| 837 | .tag = .tan, | ||
| 838 | .param_count = 1, | ||
| 839 | }, | ||
| 840 | }, | ||
| 841 | .{ | ||
| 842 | "@exp", | ||
| 843 | .{ | ||
| 844 | .tag = .exp, | ||
| 845 | .param_count = 1, | ||
| 846 | }, | ||
| 847 | }, | ||
| 848 | .{ | ||
| 849 | "@exp2", | ||
| 850 | .{ | ||
| 851 | .tag = .exp2, | ||
| 852 | .param_count = 1, | ||
| 853 | }, | ||
| 854 | }, | ||
| 855 | .{ | ||
| 856 | "@log", | ||
| 857 | .{ | ||
| 858 | .tag = .log, | ||
| 859 | .param_count = 1, | ||
| 860 | }, | ||
| 861 | }, | ||
| 862 | .{ | ||
| 863 | "@log2", | ||
| 864 | .{ | ||
| 865 | .tag = .log2, | ||
| 866 | .param_count = 1, | ||
| 867 | }, | ||
| 868 | }, | ||
| 869 | .{ | ||
| 870 | "@log10", | ||
| 871 | .{ | ||
| 872 | .tag = .log10, | ||
| 873 | .param_count = 1, | ||
| 874 | }, | ||
| 875 | }, | ||
| 876 | .{ | ||
| 877 | "@abs", | ||
| 878 | .{ | ||
| 879 | .tag = .abs, | ||
| 880 | .param_count = 1, | ||
| 881 | }, | ||
| 882 | }, | ||
| 883 | .{ | ||
| 884 | "@floor", | ||
| 885 | .{ | ||
| 886 | .tag = .floor, | ||
| 887 | .param_count = 1, | ||
| 888 | }, | ||
| 889 | }, | ||
| 890 | .{ | ||
| 891 | "@ceil", | ||
| 892 | .{ | ||
| 893 | .tag = .ceil, | ||
| 894 | .param_count = 1, | ||
| 895 | }, | ||
| 896 | }, | ||
| 897 | .{ | ||
| 898 | "@trunc", | ||
| 899 | .{ | ||
| 900 | .tag = .trunc, | ||
| 901 | .param_count = 1, | ||
| 902 | }, | ||
| 903 | }, | ||
| 904 | .{ | ||
| 905 | "@round", | ||
| 906 | .{ | ||
| 907 | .tag = .round, | ||
| 908 | .param_count = 1, | ||
| 909 | }, | ||
| 910 | }, | ||
| 911 | .{ | ||
| 912 | "@subWithOverflow", | ||
| 913 | .{ | ||
| 914 | .tag = .sub_with_overflow, | ||
| 915 | .param_count = 2, | ||
| 916 | }, | ||
| 917 | }, | ||
| 918 | .{ | ||
| 919 | "@tagName", | ||
| 920 | .{ | ||
| 921 | .tag = .tag_name, | ||
| 922 | .param_count = 1, | ||
| 923 | }, | ||
| 924 | }, | ||
| 925 | .{ | ||
| 926 | "@This", | ||
| 927 | .{ | ||
| 928 | .tag = .This, | ||
| 929 | .param_count = 0, | ||
| 930 | }, | ||
| 931 | }, | ||
| 932 | .{ | ||
| 933 | "@trap", | ||
| 934 | .{ | ||
| 935 | .tag = .trap, | ||
| 936 | .param_count = 0, | ||
| 937 | }, | ||
| 938 | }, | ||
| 939 | .{ | ||
| 940 | "@truncate", | ||
| 941 | .{ | ||
| 942 | .tag = .truncate, | ||
| 943 | .param_count = 1, | ||
| 944 | }, | ||
| 945 | }, | ||
| 946 | .{ | ||
| 947 | "@Type", | ||
| 948 | .{ | ||
| 949 | .tag = .Type, | ||
| 950 | .param_count = 1, | ||
| 951 | }, | ||
| 952 | }, | ||
| 953 | .{ | ||
| 954 | "@typeInfo", | ||
| 955 | .{ | ||
| 956 | .tag = .type_info, | ||
| 957 | .param_count = 1, | ||
| 958 | }, | ||
| 959 | }, | ||
| 960 | .{ | ||
| 961 | "@typeName", | ||
| 962 | .{ | ||
| 963 | .tag = .type_name, | ||
| 964 | .param_count = 1, | ||
| 965 | }, | ||
| 966 | }, | ||
| 967 | .{ | ||
| 968 | "@TypeOf", | ||
| 969 | .{ | ||
| 970 | .tag = .TypeOf, | ||
| 971 | .param_count = null, | ||
| 972 | }, | ||
| 973 | }, | ||
| 974 | .{ | ||
| 975 | "@unionInit", | ||
| 976 | .{ | ||
| 977 | .tag = .union_init, | ||
| 978 | .needs_mem_loc = .always, | ||
| 979 | .param_count = 3, | ||
| 980 | }, | ||
| 981 | }, | ||
| 982 | .{ | ||
| 983 | "@Vector", | ||
| 984 | .{ | ||
| 985 | .tag = .Vector, | ||
| 986 | .param_count = 2, | ||
| 987 | }, | ||
| 988 | }, | ||
| 989 | .{ | ||
| 990 | "@volatileCast", | ||
| 991 | .{ | ||
| 992 | .tag = .volatile_cast, | ||
| 993 | .param_count = 1, | ||
| 994 | }, | ||
| 995 | }, | ||
| 996 | .{ | ||
| 997 | "@workItemId", .{ | ||
| 998 | .tag = .work_item_id, | ||
| 999 | .param_count = 1, | ||
| 1000 | }, | ||
| 1001 | }, | ||
| 1002 | .{ | ||
| 1003 | "@workGroupSize", | ||
| 1004 | .{ | ||
| 1005 | .tag = .work_group_size, | ||
| 1006 | .param_count = 1, | ||
| 1007 | }, | ||
| 1008 | }, | ||
| 1009 | .{ | ||
| 1010 | "@workGroupId", | ||
| 1011 | .{ | ||
| 1012 | .tag = .work_group_id, | ||
| 1013 | .param_count = 1, | ||
| 1014 | }, | ||
| 1015 | }, | ||
| 1016 | }); | ||
| 1017 | }; | ||
src/Module.zig+1-1| ... | @@ -34,7 +34,7 @@ const isUpDir = @import("introspect.zig").isUpDir; | ... | @@ -34,7 +34,7 @@ const isUpDir = @import("introspect.zig").isUpDir; |
| 34 | const clang = @import("clang.zig"); | 34 | const clang = @import("clang.zig"); |
| 35 | const InternPool = @import("InternPool.zig"); | 35 | const InternPool = @import("InternPool.zig"); |
| 36 | const Alignment = InternPool.Alignment; | 36 | const Alignment = InternPool.Alignment; |
| 37 | const BuiltinFn = @import("BuiltinFn.zig"); | 37 | const BuiltinFn = std.zig.BuiltinFn; |
| 38 | 38 | ||
| 39 | comptime { | 39 | comptime { |
| 40 | @setEvalBranchQuota(4000); | 40 | @setEvalBranchQuota(4000); |
src/reduce/Walk.zig+1-1| ... | @@ -2,7 +2,7 @@ const std = @import("std"); | ... | @@ -2,7 +2,7 @@ const std = @import("std"); |
| 2 | const Ast = std.zig.Ast; | 2 | const Ast = std.zig.Ast; |
| 3 | const Walk = @This(); | 3 | const Walk = @This(); |
| 4 | const assert = std.debug.assert; | 4 | const assert = std.debug.assert; |
| 5 | const BuiltinFn = @import("../BuiltinFn.zig"); | 5 | const BuiltinFn = std.zig.BuiltinFn; |
| 6 | 6 | ||
| 7 | ast: *const Ast, | 7 | ast: *const Ast, |
| 8 | transformations: *std.ArrayList(Transformation), | 8 | transformations: *std.ArrayList(Transformation), |