| author | |
| committer | |
| log | 7408679234ae84afaf0130fb21c49b031ef52e3c |
| tree | f23e7a95f68a764a6eabbb46ea53108db4c788c9 |
| parent | 242bb4469547c322081ad15a84019486aedbc74d |
| signature |
Resolves: #2226110 files changed, 327 insertions(+), 849 deletions(-)
lib/std/zig/AstGen.zig+161-260| ... | ... | @@ -1420,19 +1420,9 @@ fn fnProtoExpr( |
| 1420 | 1420 | |
| 1421 | 1421 | .cc_ref = cc, |
| 1422 | 1422 | .cc_gz = null, |
| 1423 | .align_ref = .none, | |
| 1424 | .align_gz = null, | |
| 1425 | 1423 | .ret_ref = ret_ty, |
| 1426 | 1424 | .ret_gz = null, |
| 1427 | .section_ref = .none, | |
| 1428 | .section_gz = null, | |
| 1429 | .addrspace_ref = .none, | |
| 1430 | .addrspace_gz = null, | |
| 1431 | ||
| 1432 | .align_param_refs = &.{}, | |
| 1433 | .addrspace_param_refs = &.{}, | |
| 1434 | .section_param_refs = &.{}, | |
| 1435 | .cc_param_refs = &.{}, | |
| 1425 | ||
| 1436 | 1426 | .ret_param_refs = &.{}, |
| 1437 | 1427 | .param_insts = &.{}, |
| 1438 | 1428 | |
| ... | ... | @@ -4129,6 +4119,8 @@ fn fnDecl( |
| 4129 | 4119 | const decl_inst = try gz.makeDeclaration(fn_proto.ast.proto_node); |
| 4130 | 4120 | astgen.advanceSourceCursorToNode(decl_node); |
| 4131 | 4121 | |
| 4122 | const saved_cursor = astgen.saveSourceCursor(); | |
| 4123 | ||
| 4132 | 4124 | var decl_gz: GenZir = .{ |
| 4133 | 4125 | .is_comptime = true, |
| 4134 | 4126 | .decl_node_index = fn_proto.ast.proto_node, |
| ... | ... | @@ -4140,17 +4132,6 @@ fn fnDecl( |
| 4140 | 4132 | }; |
| 4141 | 4133 | defer decl_gz.unstack(); |
| 4142 | 4134 | |
| 4143 | var fn_gz: GenZir = .{ | |
| 4144 | .is_comptime = false, | |
| 4145 | .decl_node_index = fn_proto.ast.proto_node, | |
| 4146 | .decl_line = decl_gz.decl_line, | |
| 4147 | .parent = &decl_gz.base, | |
| 4148 | .astgen = astgen, | |
| 4149 | .instructions = gz.instructions, | |
| 4150 | .instructions_top = GenZir.unstacked_top, | |
| 4151 | }; | |
| 4152 | defer fn_gz.unstack(); | |
| 4153 | ||
| 4154 | 4135 | const decl_column = astgen.source_column; |
| 4155 | 4136 | |
| 4156 | 4137 | // Set this now, since parameter types, return type, etc may be generic. |
| ... | ... | @@ -4182,7 +4163,7 @@ fn fnDecl( |
| 4182 | 4163 | var param_insts: std.ArrayListUnmanaged(Zir.Inst.Index) = try .initCapacity(astgen.arena, fn_proto.ast.params.len); |
| 4183 | 4164 | |
| 4184 | 4165 | var noalias_bits: u32 = 0; |
| 4185 | var params_scope = &fn_gz.base; | |
| 4166 | var params_scope = scope; | |
| 4186 | 4167 | const is_var_args = is_var_args: { |
| 4187 | 4168 | var param_type_i: usize = 0; |
| 4188 | 4169 | var it = fn_proto.iterate(tree); |
| ... | ... | @@ -4305,47 +4286,26 @@ fn fnDecl( |
| 4305 | 4286 | // instructions inside the expression blocks for align, addrspace, cc, and ret_ty |
| 4306 | 4287 | // to use the function instruction as the "block" to break from. |
| 4307 | 4288 | |
| 4308 | var align_gz = decl_gz.makeSubBlock(params_scope); | |
| 4309 | defer align_gz.unstack(); | |
| 4310 | const align_ref: Zir.Inst.Ref = if (fn_proto.ast.align_expr == 0) .none else inst: { | |
| 4311 | const inst = try expr(&decl_gz, params_scope, coerced_align_ri, fn_proto.ast.align_expr); | |
| 4312 | if (align_gz.instructionsSlice().len == 0) { | |
| 4313 | // In this case we will send a len=0 body which can be encoded more efficiently. | |
| 4314 | break :inst inst; | |
| 4315 | } | |
| 4316 | _ = try align_gz.addBreak(.break_inline, @enumFromInt(0), inst); | |
| 4317 | break :inst inst; | |
| 4318 | }; | |
| 4319 | const align_body_param_refs = try astgen.fetchRemoveRefEntries(param_insts.items); | |
| 4320 | ||
| 4321 | var addrspace_gz = decl_gz.makeSubBlock(params_scope); | |
| 4322 | defer addrspace_gz.unstack(); | |
| 4323 | const addrspace_ref: Zir.Inst.Ref = if (fn_proto.ast.addrspace_expr == 0) .none else inst: { | |
| 4324 | const addrspace_ty = try decl_gz.addBuiltinValue(fn_proto.ast.addrspace_expr, .address_space); | |
| 4325 | const inst = try expr(&decl_gz, params_scope, .{ .rl = .{ .coerced_ty = addrspace_ty } }, fn_proto.ast.addrspace_expr); | |
| 4326 | if (addrspace_gz.instructionsSlice().len == 0) { | |
| 4289 | var ret_gz = decl_gz.makeSubBlock(params_scope); | |
| 4290 | defer ret_gz.unstack(); | |
| 4291 | const ret_ref: Zir.Inst.Ref = inst: { | |
| 4292 | // Parameters are in scope for the return type, so we use `params_scope` here. | |
| 4293 | // The calling convention will not have parameters in scope, so we'll just use `scope`. | |
| 4294 | // See #22263 for a proposal to solve the inconsistency here. | |
| 4295 | const inst = try fullBodyExpr(&ret_gz, params_scope, coerced_type_ri, fn_proto.ast.return_type, .normal); | |
| 4296 | if (ret_gz.instructionsSlice().len == 0) { | |
| 4327 | 4297 | // In this case we will send a len=0 body which can be encoded more efficiently. |
| 4328 | 4298 | break :inst inst; |
| 4329 | 4299 | } |
| 4330 | _ = try addrspace_gz.addBreak(.break_inline, @enumFromInt(0), inst); | |
| 4300 | _ = try ret_gz.addBreak(.break_inline, @enumFromInt(0), inst); | |
| 4331 | 4301 | break :inst inst; |
| 4332 | 4302 | }; |
| 4333 | const addrspace_body_param_refs = try astgen.fetchRemoveRefEntries(param_insts.items); | |
| 4303 | const ret_body_param_refs = try astgen.fetchRemoveRefEntries(param_insts.items); | |
| 4334 | 4304 | |
| 4335 | var section_gz = decl_gz.makeSubBlock(params_scope); | |
| 4336 | defer section_gz.unstack(); | |
| 4337 | const section_ref: Zir.Inst.Ref = if (fn_proto.ast.section_expr == 0) .none else inst: { | |
| 4338 | const inst = try expr(&decl_gz, params_scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, fn_proto.ast.section_expr); | |
| 4339 | if (section_gz.instructionsSlice().len == 0) { | |
| 4340 | // In this case we will send a len=0 body which can be encoded more efficiently. | |
| 4341 | break :inst inst; | |
| 4342 | } | |
| 4343 | _ = try section_gz.addBreak(.break_inline, @enumFromInt(0), inst); | |
| 4344 | break :inst inst; | |
| 4345 | }; | |
| 4346 | const section_body_param_refs = try astgen.fetchRemoveRefEntries(param_insts.items); | |
| 4305 | // We're jumping back in source, so restore the cursor. | |
| 4306 | astgen.restoreSourceCursor(saved_cursor); | |
| 4347 | 4307 | |
| 4348 | var cc_gz = decl_gz.makeSubBlock(params_scope); | |
| 4308 | var cc_gz = decl_gz.makeSubBlock(scope); | |
| 4349 | 4309 | defer cc_gz.unstack(); |
| 4350 | 4310 | const cc_ref: Zir.Inst.Ref = blk: { |
| 4351 | 4311 | if (fn_proto.ast.callconv_expr != 0) { |
| ... | ... | @@ -4358,7 +4318,7 @@ fn fnDecl( |
| 4358 | 4318 | } |
| 4359 | 4319 | const inst = try expr( |
| 4360 | 4320 | &cc_gz, |
| 4361 | params_scope, | |
| 4321 | scope, | |
| 4362 | 4322 | .{ .rl = .{ .coerced_ty = try cc_gz.addBuiltinValue(fn_proto.ast.callconv_expr, .calling_convention) } }, |
| 4363 | 4323 | fn_proto.ast.callconv_expr, |
| 4364 | 4324 | ); |
| ... | ... | @@ -4380,20 +4340,6 @@ fn fnDecl( |
| 4380 | 4340 | break :blk .none; |
| 4381 | 4341 | } |
| 4382 | 4342 | }; |
| 4383 | const cc_body_param_refs = try astgen.fetchRemoveRefEntries(param_insts.items); | |
| 4384 | ||
| 4385 | var ret_gz = decl_gz.makeSubBlock(params_scope); | |
| 4386 | defer ret_gz.unstack(); | |
| 4387 | const ret_ref: Zir.Inst.Ref = inst: { | |
| 4388 | const inst = try fullBodyExpr(&ret_gz, params_scope, coerced_type_ri, fn_proto.ast.return_type, .normal); | |
| 4389 | if (ret_gz.instructionsSlice().len == 0) { | |
| 4390 | // In this case we will send a len=0 body which can be encoded more efficiently. | |
| 4391 | break :inst inst; | |
| 4392 | } | |
| 4393 | _ = try ret_gz.addBreak(.break_inline, @enumFromInt(0), inst); | |
| 4394 | break :inst inst; | |
| 4395 | }; | |
| 4396 | const ret_body_param_refs = try astgen.fetchRemoveRefEntries(param_insts.items); | |
| 4397 | 4343 | |
| 4398 | 4344 | const func_inst: Zir.Inst.Ref = if (body_node == 0) func: { |
| 4399 | 4345 | if (!is_extern) { |
| ... | ... | @@ -4406,19 +4352,9 @@ fn fnDecl( |
| 4406 | 4352 | .src_node = decl_node, |
| 4407 | 4353 | .cc_ref = cc_ref, |
| 4408 | 4354 | .cc_gz = &cc_gz, |
| 4409 | .cc_param_refs = cc_body_param_refs, | |
| 4410 | .align_ref = align_ref, | |
| 4411 | .align_gz = &align_gz, | |
| 4412 | .align_param_refs = align_body_param_refs, | |
| 4413 | 4355 | .ret_ref = ret_ref, |
| 4414 | 4356 | .ret_gz = &ret_gz, |
| 4415 | 4357 | .ret_param_refs = ret_body_param_refs, |
| 4416 | .section_ref = section_ref, | |
| 4417 | .section_gz = &section_gz, | |
| 4418 | .section_param_refs = section_body_param_refs, | |
| 4419 | .addrspace_ref = addrspace_ref, | |
| 4420 | .addrspace_gz = &addrspace_gz, | |
| 4421 | .addrspace_param_refs = addrspace_body_param_refs, | |
| 4422 | 4358 | .param_block = decl_inst, |
| 4423 | 4359 | .param_insts = param_insts.items, |
| 4424 | 4360 | .body_gz = null, |
| ... | ... | @@ -4432,8 +4368,23 @@ fn fnDecl( |
| 4432 | 4368 | .proto_hash = undefined, // ignored for `body_gz == null` |
| 4433 | 4369 | }); |
| 4434 | 4370 | } else func: { |
| 4435 | // as a scope, fn_gz encloses ret_gz, but for instruction list, fn_gz stacks on ret_gz | |
| 4436 | fn_gz.instructions_top = ret_gz.instructions.items.len; | |
| 4371 | var body_gz: GenZir = .{ | |
| 4372 | .is_comptime = false, | |
| 4373 | .decl_node_index = fn_proto.ast.proto_node, | |
| 4374 | .decl_line = decl_gz.decl_line, | |
| 4375 | .parent = params_scope, | |
| 4376 | .astgen = astgen, | |
| 4377 | .instructions = gz.instructions, | |
| 4378 | .instructions_top = gz.instructions.items.len, | |
| 4379 | }; | |
| 4380 | defer body_gz.unstack(); | |
| 4381 | ||
| 4382 | // We want `params_scope` to be stacked like this: | |
| 4383 | // body_gz (top) | |
| 4384 | // param2 | |
| 4385 | // param1 | |
| 4386 | // param0 | |
| 4387 | // decl_gz (bottom) | |
| 4437 | 4388 | |
| 4438 | 4389 | // Construct the prototype hash. |
| 4439 | 4390 | // Leave `astgen.src_hasher` unmodified; this will be used for hashing |
| ... | ... | @@ -4450,13 +4401,13 @@ fn fnDecl( |
| 4450 | 4401 | astgen.fn_block = prev_fn_block; |
| 4451 | 4402 | astgen.fn_ret_ty = prev_fn_ret_ty; |
| 4452 | 4403 | } |
| 4453 | astgen.fn_block = &fn_gz; | |
| 4404 | astgen.fn_block = &body_gz; | |
| 4454 | 4405 | astgen.fn_ret_ty = if (is_inferred_error or ret_ref.toIndex() != null) r: { |
| 4455 | 4406 | // We're essentially guaranteed to need the return type at some point, |
| 4456 | 4407 | // since the return type is likely not `void` or `noreturn` so there |
| 4457 | 4408 | // will probably be an explicit return requiring RLS. Fetch this |
| 4458 | 4409 | // return type now so the rest of the function can use it. |
| 4459 | break :r try fn_gz.addNode(.ret_type, decl_node); | |
| 4410 | break :r try body_gz.addNode(.ret_type, decl_node); | |
| 4460 | 4411 | } else ret_ref; |
| 4461 | 4412 | |
| 4462 | 4413 | const prev_var_args = astgen.fn_var_args; |
| ... | ... | @@ -4467,39 +4418,29 @@ fn fnDecl( |
| 4467 | 4418 | const lbrace_line = astgen.source_line - decl_gz.decl_line; |
| 4468 | 4419 | const lbrace_column = astgen.source_column; |
| 4469 | 4420 | |
| 4470 | _ = try fullBodyExpr(&fn_gz, params_scope, .{ .rl = .none }, body_node, .allow_branch_hint); | |
| 4471 | try checkUsed(gz, &fn_gz.base, params_scope); | |
| 4421 | _ = try fullBodyExpr(&body_gz, &body_gz.base, .{ .rl = .none }, body_node, .allow_branch_hint); | |
| 4422 | try checkUsed(gz, scope, params_scope); | |
| 4472 | 4423 | |
| 4473 | if (!fn_gz.endsWithNoReturn()) { | |
| 4424 | if (!body_gz.endsWithNoReturn()) { | |
| 4474 | 4425 | // As our last action before the return, "pop" the error trace if needed |
| 4475 | _ = try fn_gz.addRestoreErrRetIndex(.ret, .always, decl_node); | |
| 4426 | _ = try body_gz.addRestoreErrRetIndex(.ret, .always, decl_node); | |
| 4476 | 4427 | |
| 4477 | 4428 | // Add implicit return at end of function. |
| 4478 | _ = try fn_gz.addUnTok(.ret_implicit, .void_value, tree.lastToken(body_node)); | |
| 4429 | _ = try body_gz.addUnTok(.ret_implicit, .void_value, tree.lastToken(body_node)); | |
| 4479 | 4430 | } |
| 4480 | 4431 | |
| 4481 | 4432 | break :func try decl_gz.addFunc(.{ |
| 4482 | 4433 | .src_node = decl_node, |
| 4483 | 4434 | .cc_ref = cc_ref, |
| 4484 | 4435 | .cc_gz = &cc_gz, |
| 4485 | .cc_param_refs = cc_body_param_refs, | |
| 4486 | .align_ref = align_ref, | |
| 4487 | .align_gz = &align_gz, | |
| 4488 | .align_param_refs = align_body_param_refs, | |
| 4489 | 4436 | .ret_ref = ret_ref, |
| 4490 | 4437 | .ret_gz = &ret_gz, |
| 4491 | 4438 | .ret_param_refs = ret_body_param_refs, |
| 4492 | .section_ref = section_ref, | |
| 4493 | .section_gz = &section_gz, | |
| 4494 | .section_param_refs = section_body_param_refs, | |
| 4495 | .addrspace_ref = addrspace_ref, | |
| 4496 | .addrspace_gz = &addrspace_gz, | |
| 4497 | .addrspace_param_refs = addrspace_body_param_refs, | |
| 4498 | 4439 | .lbrace_line = lbrace_line, |
| 4499 | 4440 | .lbrace_column = lbrace_column, |
| 4500 | 4441 | .param_block = decl_inst, |
| 4501 | 4442 | .param_insts = param_insts.items, |
| 4502 | .body_gz = &fn_gz, | |
| 4443 | .body_gz = &body_gz, | |
| 4503 | 4444 | .lib_name = lib_name, |
| 4504 | 4445 | .is_var_args = is_var_args, |
| 4505 | 4446 | .is_inferred_error = is_inferred_error, |
| ... | ... | @@ -4511,13 +4452,39 @@ fn fnDecl( |
| 4511 | 4452 | }); |
| 4512 | 4453 | }; |
| 4513 | 4454 | |
| 4455 | // Before we stack more stuff onto `decl_gz`, add its final instruction. | |
| 4456 | _ = try decl_gz.addBreak(.break_inline, decl_inst, func_inst); | |
| 4457 | ||
| 4458 | // Now that `cc_gz,` `ret_gz`, and `body_gz` are unstacked, we evaluate align, addrspace, and linksection. | |
| 4459 | ||
| 4460 | // We're jumping back in source, so restore the cursor. | |
| 4461 | astgen.restoreSourceCursor(saved_cursor); | |
| 4462 | ||
| 4463 | var align_gz = decl_gz.makeSubBlock(scope); | |
| 4464 | defer align_gz.unstack(); | |
| 4465 | if (fn_proto.ast.align_expr != 0) { | |
| 4466 | const inst = try expr(&decl_gz, &decl_gz.base, coerced_align_ri, fn_proto.ast.align_expr); | |
| 4467 | _ = try align_gz.addBreak(.break_inline, decl_inst, inst); | |
| 4468 | } | |
| 4469 | ||
| 4470 | var section_gz = align_gz.makeSubBlock(scope); | |
| 4471 | defer section_gz.unstack(); | |
| 4472 | if (fn_proto.ast.section_expr != 0) { | |
| 4473 | const inst = try expr(&decl_gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, fn_proto.ast.section_expr); | |
| 4474 | _ = try section_gz.addBreak(.break_inline, decl_inst, inst); | |
| 4475 | } | |
| 4476 | ||
| 4477 | var addrspace_gz = section_gz.makeSubBlock(scope); | |
| 4478 | defer addrspace_gz.unstack(); | |
| 4479 | if (fn_proto.ast.addrspace_expr != 0) { | |
| 4480 | const addrspace_ty = try decl_gz.addBuiltinValue(fn_proto.ast.addrspace_expr, .address_space); | |
| 4481 | const inst = try expr(&decl_gz, scope, .{ .rl = .{ .coerced_ty = addrspace_ty } }, fn_proto.ast.addrspace_expr); | |
| 4482 | _ = try addrspace_gz.addBreak(.break_inline, decl_inst, inst); | |
| 4483 | } | |
| 4484 | ||
| 4514 | 4485 | // *Now* we can incorporate the full source code into the hasher. |
| 4515 | 4486 | astgen.src_hasher.update(tree.getNodeSource(decl_node)); |
| 4516 | 4487 | |
| 4517 | // We add this at the end so that its instruction index marks the end range | |
| 4518 | // of the top level declaration. addFunc already unstacked fn_gz and ret_gz. | |
| 4519 | _ = try decl_gz.addBreak(.break_inline, decl_inst, func_inst); | |
| 4520 | ||
| 4521 | 4488 | var hash: std.zig.SrcHash = undefined; |
| 4522 | 4489 | astgen.src_hasher.final(&hash); |
| 4523 | 4490 | try setDeclaration( |
| ... | ... | @@ -4529,9 +4496,11 @@ fn fnDecl( |
| 4529 | 4496 | is_pub, |
| 4530 | 4497 | is_export, |
| 4531 | 4498 | &decl_gz, |
| 4532 | // align, linksection, and addrspace are passed in the func instruction in this case. | |
| 4533 | // TODO: move them from the function instruction to the declaration instruction? | |
| 4534 | null, | |
| 4499 | .{ | |
| 4500 | .align_gz = &align_gz, | |
| 4501 | .linksection_gz = &section_gz, | |
| 4502 | .addrspace_gz = &addrspace_gz, | |
| 4503 | }, | |
| 4535 | 4504 | ); |
| 4536 | 4505 | } |
| 4537 | 4506 | |
| ... | ... | @@ -4986,19 +4955,9 @@ fn testDecl( |
| 4986 | 4955 | |
| 4987 | 4956 | .cc_ref = .none, |
| 4988 | 4957 | .cc_gz = null, |
| 4989 | .align_ref = .none, | |
| 4990 | .align_gz = null, | |
| 4991 | 4958 | .ret_ref = .anyerror_void_error_union_type, |
| 4992 | 4959 | .ret_gz = null, |
| 4993 | .section_ref = .none, | |
| 4994 | .section_gz = null, | |
| 4995 | .addrspace_ref = .none, | |
| 4996 | .addrspace_gz = null, | |
| 4997 | ||
| 4998 | .align_param_refs = &.{}, | |
| 4999 | .addrspace_param_refs = &.{}, | |
| 5000 | .section_param_refs = &.{}, | |
| 5001 | .cc_param_refs = &.{}, | |
| 4960 | ||
| 5002 | 4961 | .ret_param_refs = &.{}, |
| 5003 | 4962 | .param_insts = &.{}, |
| 5004 | 4963 | |
| ... | ... | @@ -11952,6 +11911,14 @@ const GenZir = struct { |
| 11952 | 11911 | self.instructions.items[self.instructions_top..]; |
| 11953 | 11912 | } |
| 11954 | 11913 | |
| 11914 | fn instructionsSliceUptoOpt(gz: *const GenZir, maybe_stacked_gz: ?*GenZir) []Zir.Inst.Index { | |
| 11915 | if (maybe_stacked_gz) |stacked_gz| { | |
| 11916 | return gz.instructionsSliceUpto(stacked_gz); | |
| 11917 | } else { | |
| 11918 | return gz.instructionsSlice(); | |
| 11919 | } | |
| 11920 | } | |
| 11921 | ||
| 11955 | 11922 | fn makeSubBlock(gz: *GenZir, scope: *Scope) GenZir { |
| 11956 | 11923 | return .{ |
| 11957 | 11924 | .is_comptime = gz.is_comptime, |
| ... | ... | @@ -12088,11 +12055,8 @@ const GenZir = struct { |
| 12088 | 12055 | |
| 12089 | 12056 | /// Must be called with the following stack set up: |
| 12090 | 12057 | /// * gz (bottom) |
| 12091 | /// * align_gz | |
| 12092 | /// * addrspace_gz | |
| 12093 | /// * section_gz | |
| 12094 | /// * cc_gz | |
| 12095 | 12058 | /// * ret_gz |
| 12059 | /// * cc_gz | |
| 12096 | 12060 | /// * body_gz (top) |
| 12097 | 12061 | /// Unstacks all of those except for `gz`. |
| 12098 | 12062 | fn addFunc( |
| ... | ... | @@ -12103,23 +12067,13 @@ const GenZir = struct { |
| 12103 | 12067 | lbrace_column: u32 = 0, |
| 12104 | 12068 | param_block: Zir.Inst.Index, |
| 12105 | 12069 | |
| 12106 | align_gz: ?*GenZir, | |
| 12107 | addrspace_gz: ?*GenZir, | |
| 12108 | section_gz: ?*GenZir, | |
| 12109 | cc_gz: ?*GenZir, | |
| 12110 | 12070 | ret_gz: ?*GenZir, |
| 12111 | 12071 | body_gz: ?*GenZir, |
| 12072 | cc_gz: ?*GenZir, | |
| 12112 | 12073 | |
| 12113 | align_param_refs: []Zir.Inst.Index, | |
| 12114 | addrspace_param_refs: []Zir.Inst.Index, | |
| 12115 | section_param_refs: []Zir.Inst.Index, | |
| 12116 | cc_param_refs: []Zir.Inst.Index, | |
| 12117 | 12074 | ret_param_refs: []Zir.Inst.Index, |
| 12118 | 12075 | param_insts: []Zir.Inst.Index, // refs to params in `body_gz` should still be in `astgen.ref_table` |
| 12119 | 12076 | |
| 12120 | align_ref: Zir.Inst.Ref, | |
| 12121 | addrspace_ref: Zir.Inst.Ref, | |
| 12122 | section_ref: Zir.Inst.Ref, | |
| 12123 | 12077 | cc_ref: Zir.Inst.Ref, |
| 12124 | 12078 | ret_ref: Zir.Inst.Ref, |
| 12125 | 12079 | |
| ... | ... | @@ -12141,13 +12095,31 @@ const GenZir = struct { |
| 12141 | 12095 | const ret_ref = if (args.ret_ref == .void_type) .none else args.ret_ref; |
| 12142 | 12096 | const new_index: Zir.Inst.Index = @enumFromInt(astgen.instructions.len); |
| 12143 | 12097 | |
| 12098 | try gz.instructions.ensureUnusedCapacity(gpa, 1); | |
| 12144 | 12099 | try astgen.instructions.ensureUnusedCapacity(gpa, 1); |
| 12145 | 12100 | |
| 12146 | var body: []Zir.Inst.Index = &[0]Zir.Inst.Index{}; | |
| 12147 | var ret_body: []Zir.Inst.Index = &[0]Zir.Inst.Index{}; | |
| 12101 | const body, const cc_body, const ret_body = bodies: { | |
| 12102 | var stacked_gz: ?*GenZir = null; | |
| 12103 | const body: []const Zir.Inst.Index = if (args.body_gz) |body_gz| body: { | |
| 12104 | const body = body_gz.instructionsSliceUptoOpt(stacked_gz); | |
| 12105 | stacked_gz = body_gz; | |
| 12106 | break :body body; | |
| 12107 | } else &.{}; | |
| 12108 | const cc_body: []const Zir.Inst.Index = if (args.cc_gz) |cc_gz| body: { | |
| 12109 | const cc_body = cc_gz.instructionsSliceUptoOpt(stacked_gz); | |
| 12110 | stacked_gz = cc_gz; | |
| 12111 | break :body cc_body; | |
| 12112 | } else &.{}; | |
| 12113 | const ret_body: []const Zir.Inst.Index = if (args.ret_gz) |ret_gz| body: { | |
| 12114 | const ret_body = ret_gz.instructionsSliceUptoOpt(stacked_gz); | |
| 12115 | stacked_gz = ret_gz; | |
| 12116 | break :body ret_body; | |
| 12117 | } else &.{}; | |
| 12118 | break :bodies .{ body, cc_body, ret_body }; | |
| 12119 | }; | |
| 12120 | ||
| 12148 | 12121 | var src_locs_and_hash_buffer: [7]u32 = undefined; |
| 12149 | var src_locs_and_hash: []u32 = src_locs_and_hash_buffer[0..0]; | |
| 12150 | if (args.body_gz) |body_gz| { | |
| 12122 | const src_locs_and_hash: []const u32 = if (args.body_gz != null) src_locs_and_hash: { | |
| 12151 | 12123 | const tree = astgen.tree; |
| 12152 | 12124 | const node_tags = tree.nodes.items(.tag); |
| 12153 | 12125 | const node_datas = tree.nodes.items(.data); |
| ... | ... | @@ -12173,39 +12145,19 @@ const GenZir = struct { |
| 12173 | 12145 | proto_hash_arr[2], |
| 12174 | 12146 | proto_hash_arr[3], |
| 12175 | 12147 | }; |
| 12176 | src_locs_and_hash = &src_locs_and_hash_buffer; | |
| 12148 | break :src_locs_and_hash &src_locs_and_hash_buffer; | |
| 12149 | } else &.{}; | |
| 12177 | 12150 | |
| 12178 | body = body_gz.instructionsSlice(); | |
| 12179 | if (args.ret_gz) |ret_gz| | |
| 12180 | ret_body = ret_gz.instructionsSliceUpto(body_gz); | |
| 12181 | } else { | |
| 12182 | if (args.ret_gz) |ret_gz| | |
| 12183 | ret_body = ret_gz.instructionsSlice(); | |
| 12184 | } | |
| 12185 | 12151 | const body_len = astgen.countBodyLenAfterFixupsExtraRefs(body, args.param_insts); |
| 12186 | 12152 | |
| 12187 | if (args.cc_ref != .none or args.lib_name != .empty or args.is_var_args or args.is_test or | |
| 12188 | args.is_extern or args.align_ref != .none or args.section_ref != .none or | |
| 12189 | args.addrspace_ref != .none or args.noalias_bits != 0 or args.is_noinline) | |
| 12190 | { | |
| 12191 | var align_body: []Zir.Inst.Index = &.{}; | |
| 12192 | var addrspace_body: []Zir.Inst.Index = &.{}; | |
| 12193 | var section_body: []Zir.Inst.Index = &.{}; | |
| 12194 | var cc_body: []Zir.Inst.Index = &.{}; | |
| 12195 | if (args.ret_gz != null) { | |
| 12196 | align_body = args.align_gz.?.instructionsSliceUpto(args.addrspace_gz.?); | |
| 12197 | addrspace_body = args.addrspace_gz.?.instructionsSliceUpto(args.section_gz.?); | |
| 12198 | section_body = args.section_gz.?.instructionsSliceUpto(args.cc_gz.?); | |
| 12199 | cc_body = args.cc_gz.?.instructionsSliceUpto(args.ret_gz.?); | |
| 12200 | } | |
| 12201 | ||
| 12153 | const tag: Zir.Inst.Tag, const payload_index: u32 = if (args.cc_ref != .none or args.lib_name != .empty or | |
| 12154 | args.is_var_args or args.is_test or args.is_extern or | |
| 12155 | args.noalias_bits != 0 or args.is_noinline) | |
| 12156 | inst_info: { | |
| 12202 | 12157 | try astgen.extra.ensureUnusedCapacity( |
| 12203 | 12158 | gpa, |
| 12204 | 12159 | @typeInfo(Zir.Inst.FuncFancy).@"struct".fields.len + |
| 12205 | fancyFnExprExtraLen(astgen, args.align_param_refs, align_body, args.align_ref) + | |
| 12206 | fancyFnExprExtraLen(astgen, args.addrspace_param_refs, addrspace_body, args.addrspace_ref) + | |
| 12207 | fancyFnExprExtraLen(astgen, args.section_param_refs, section_body, args.section_ref) + | |
| 12208 | fancyFnExprExtraLen(astgen, args.cc_param_refs, cc_body, args.cc_ref) + | |
| 12160 | fancyFnExprExtraLen(astgen, &.{}, cc_body, args.cc_ref) + | |
| 12209 | 12161 | fancyFnExprExtraLen(astgen, args.ret_param_refs, ret_body, ret_ref) + |
| 12210 | 12162 | body_len + src_locs_and_hash.len + |
| 12211 | 12163 | @intFromBool(args.lib_name != .empty) + |
| ... | ... | @@ -12223,15 +12175,9 @@ const GenZir = struct { |
| 12223 | 12175 | .has_lib_name = args.lib_name != .empty, |
| 12224 | 12176 | .has_any_noalias = args.noalias_bits != 0, |
| 12225 | 12177 | |
| 12226 | .has_align_ref = args.align_ref != .none, | |
| 12227 | .has_addrspace_ref = args.addrspace_ref != .none, | |
| 12228 | .has_section_ref = args.section_ref != .none, | |
| 12229 | 12178 | .has_cc_ref = args.cc_ref != .none, |
| 12230 | 12179 | .has_ret_ty_ref = ret_ref != .none, |
| 12231 | 12180 | |
| 12232 | .has_align_body = align_body.len != 0, | |
| 12233 | .has_addrspace_body = addrspace_body.len != 0, | |
| 12234 | .has_section_body = section_body.len != 0, | |
| 12235 | 12181 | .has_cc_body = cc_body.len != 0, |
| 12236 | 12182 | .has_ret_ty_body = ret_body.len != 0, |
| 12237 | 12183 | }, |
| ... | ... | @@ -12241,53 +12187,8 @@ const GenZir = struct { |
| 12241 | 12187 | } |
| 12242 | 12188 | |
| 12243 | 12189 | const zir_datas = astgen.instructions.items(.data); |
| 12244 | if (align_body.len != 0) { | |
| 12245 | astgen.extra.appendAssumeCapacity( | |
| 12246 | astgen.countBodyLenAfterFixups(args.align_param_refs) + | |
| 12247 | astgen.countBodyLenAfterFixups(align_body), | |
| 12248 | ); | |
| 12249 | astgen.appendBodyWithFixups(args.align_param_refs); | |
| 12250 | astgen.appendBodyWithFixups(align_body); | |
| 12251 | const break_extra = zir_datas[@intFromEnum(align_body[align_body.len - 1])].@"break".payload_index; | |
| 12252 | astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] = | |
| 12253 | @intFromEnum(new_index); | |
| 12254 | } else if (args.align_ref != .none) { | |
| 12255 | astgen.extra.appendAssumeCapacity(@intFromEnum(args.align_ref)); | |
| 12256 | } | |
| 12257 | if (addrspace_body.len != 0) { | |
| 12258 | astgen.extra.appendAssumeCapacity( | |
| 12259 | astgen.countBodyLenAfterFixups(args.addrspace_param_refs) + | |
| 12260 | astgen.countBodyLenAfterFixups(addrspace_body), | |
| 12261 | ); | |
| 12262 | astgen.appendBodyWithFixups(args.addrspace_param_refs); | |
| 12263 | astgen.appendBodyWithFixups(addrspace_body); | |
| 12264 | const break_extra = | |
| 12265 | zir_datas[@intFromEnum(addrspace_body[addrspace_body.len - 1])].@"break".payload_index; | |
| 12266 | astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] = | |
| 12267 | @intFromEnum(new_index); | |
| 12268 | } else if (args.addrspace_ref != .none) { | |
| 12269 | astgen.extra.appendAssumeCapacity(@intFromEnum(args.addrspace_ref)); | |
| 12270 | } | |
| 12271 | if (section_body.len != 0) { | |
| 12272 | astgen.extra.appendAssumeCapacity( | |
| 12273 | astgen.countBodyLenAfterFixups(args.section_param_refs) + | |
| 12274 | astgen.countBodyLenAfterFixups(section_body), | |
| 12275 | ); | |
| 12276 | astgen.appendBodyWithFixups(args.section_param_refs); | |
| 12277 | astgen.appendBodyWithFixups(section_body); | |
| 12278 | const break_extra = | |
| 12279 | zir_datas[@intFromEnum(section_body[section_body.len - 1])].@"break".payload_index; | |
| 12280 | astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] = | |
| 12281 | @intFromEnum(new_index); | |
| 12282 | } else if (args.section_ref != .none) { | |
| 12283 | astgen.extra.appendAssumeCapacity(@intFromEnum(args.section_ref)); | |
| 12284 | } | |
| 12285 | 12190 | if (cc_body.len != 0) { |
| 12286 | astgen.extra.appendAssumeCapacity( | |
| 12287 | astgen.countBodyLenAfterFixups(args.cc_param_refs) + | |
| 12288 | astgen.countBodyLenAfterFixups(cc_body), | |
| 12289 | ); | |
| 12290 | astgen.appendBodyWithFixups(args.cc_param_refs); | |
| 12191 | astgen.extra.appendAssumeCapacity(astgen.countBodyLenAfterFixups(cc_body)); | |
| 12291 | 12192 | astgen.appendBodyWithFixups(cc_body); |
| 12292 | 12193 | const break_extra = zir_datas[@intFromEnum(cc_body[cc_body.len - 1])].@"break".payload_index; |
| 12293 | 12194 | astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] = |
| ... | ... | @@ -12316,28 +12217,8 @@ const GenZir = struct { |
| 12316 | 12217 | astgen.appendBodyWithFixupsExtraRefsArrayList(&astgen.extra, body, args.param_insts); |
| 12317 | 12218 | astgen.extra.appendSliceAssumeCapacity(src_locs_and_hash); |
| 12318 | 12219 | |
| 12319 | // Order is important when unstacking. | |
| 12320 | if (args.body_gz) |body_gz| body_gz.unstack(); | |
| 12321 | if (args.ret_gz != null) { | |
| 12322 | args.ret_gz.?.unstack(); | |
| 12323 | args.cc_gz.?.unstack(); | |
| 12324 | args.section_gz.?.unstack(); | |
| 12325 | args.addrspace_gz.?.unstack(); | |
| 12326 | args.align_gz.?.unstack(); | |
| 12327 | } | |
| 12328 | ||
| 12329 | try gz.instructions.ensureUnusedCapacity(gpa, 1); | |
| 12330 | ||
| 12331 | astgen.instructions.appendAssumeCapacity(.{ | |
| 12332 | .tag = .func_fancy, | |
| 12333 | .data = .{ .pl_node = .{ | |
| 12334 | .src_node = gz.nodeIndexToRelative(args.src_node), | |
| 12335 | .payload_index = payload_index, | |
| 12336 | } }, | |
| 12337 | }); | |
| 12338 | gz.instructions.appendAssumeCapacity(new_index); | |
| 12339 | return new_index.toRef(); | |
| 12340 | } else { | |
| 12220 | break :inst_info .{ .func_fancy, payload_index }; | |
| 12221 | } else inst_info: { | |
| 12341 | 12222 | try astgen.extra.ensureUnusedCapacity( |
| 12342 | 12223 | gpa, |
| 12343 | 12224 | @typeInfo(Zir.Inst.Func).@"struct".fields.len + 1 + |
| ... | ... | @@ -12369,30 +12250,29 @@ const GenZir = struct { |
| 12369 | 12250 | astgen.appendBodyWithFixupsExtraRefsArrayList(&astgen.extra, body, args.param_insts); |
| 12370 | 12251 | astgen.extra.appendSliceAssumeCapacity(src_locs_and_hash); |
| 12371 | 12252 | |
| 12372 | // Order is important when unstacking. | |
| 12373 | if (args.body_gz) |body_gz| body_gz.unstack(); | |
| 12374 | if (args.ret_gz) |ret_gz| ret_gz.unstack(); | |
| 12375 | if (args.cc_gz) |cc_gz| cc_gz.unstack(); | |
| 12376 | if (args.section_gz) |section_gz| section_gz.unstack(); | |
| 12377 | if (args.addrspace_gz) |addrspace_gz| addrspace_gz.unstack(); | |
| 12378 | if (args.align_gz) |align_gz| align_gz.unstack(); | |
| 12253 | break :inst_info .{ | |
| 12254 | if (args.is_inferred_error) .func_inferred else .func, | |
| 12255 | payload_index, | |
| 12256 | }; | |
| 12257 | }; | |
| 12379 | 12258 | |
| 12380 | try gz.instructions.ensureUnusedCapacity(gpa, 1); | |
| 12259 | // Order is important when unstacking. | |
| 12260 | if (args.body_gz) |body_gz| body_gz.unstack(); | |
| 12261 | if (args.cc_gz) |cc_gz| cc_gz.unstack(); | |
| 12262 | if (args.ret_gz) |ret_gz| ret_gz.unstack(); | |
| 12381 | 12263 | |
| 12382 | const tag: Zir.Inst.Tag = if (args.is_inferred_error) .func_inferred else .func; | |
| 12383 | astgen.instructions.appendAssumeCapacity(.{ | |
| 12384 | .tag = tag, | |
| 12385 | .data = .{ .pl_node = .{ | |
| 12386 | .src_node = gz.nodeIndexToRelative(args.src_node), | |
| 12387 | .payload_index = payload_index, | |
| 12388 | } }, | |
| 12389 | }); | |
| 12390 | gz.instructions.appendAssumeCapacity(new_index); | |
| 12391 | return new_index.toRef(); | |
| 12392 | } | |
| 12264 | astgen.instructions.appendAssumeCapacity(.{ | |
| 12265 | .tag = tag, | |
| 12266 | .data = .{ .pl_node = .{ | |
| 12267 | .src_node = gz.nodeIndexToRelative(args.src_node), | |
| 12268 | .payload_index = payload_index, | |
| 12269 | } }, | |
| 12270 | }); | |
| 12271 | gz.instructions.appendAssumeCapacity(new_index); | |
| 12272 | return new_index.toRef(); | |
| 12393 | 12273 | } |
| 12394 | 12274 | |
| 12395 | fn fancyFnExprExtraLen(astgen: *AstGen, param_refs_body: []Zir.Inst.Index, main_body: []Zir.Inst.Index, ref: Zir.Inst.Ref) u32 { | |
| 12275 | fn fancyFnExprExtraLen(astgen: *AstGen, param_refs_body: []const Zir.Inst.Index, main_body: []const Zir.Inst.Index, ref: Zir.Inst.Ref) u32 { | |
| 12396 | 12276 | return countBodyLenAfterFixups(astgen, param_refs_body) + |
| 12397 | 12277 | countBodyLenAfterFixups(astgen, main_body) + |
| 12398 | 12278 | // If there is a body, we need an element for its length; otherwise, if there is a ref, we need to include that. |
| ... | ... | @@ -13576,6 +13456,27 @@ fn advanceSourceCursor(astgen: *AstGen, end: usize) void { |
| 13576 | 13456 | astgen.source_column = column; |
| 13577 | 13457 | } |
| 13578 | 13458 | |
| 13459 | const SourceCursor = struct { | |
| 13460 | offset: u32, | |
| 13461 | line: u32, | |
| 13462 | column: u32, | |
| 13463 | }; | |
| 13464 | ||
| 13465 | /// Get the current source cursor, to be restored later with `restoreSourceCursor`. | |
| 13466 | /// This is useful when analyzing source code out-of-order. | |
| 13467 | fn saveSourceCursor(astgen: *const AstGen) SourceCursor { | |
| 13468 | return .{ | |
| 13469 | .offset = astgen.source_offset, | |
| 13470 | .line = astgen.source_line, | |
| 13471 | .column = astgen.source_column, | |
| 13472 | }; | |
| 13473 | } | |
| 13474 | fn restoreSourceCursor(astgen: *AstGen, cursor: SourceCursor) void { | |
| 13475 | astgen.source_offset = cursor.offset; | |
| 13476 | astgen.source_line = cursor.line; | |
| 13477 | astgen.source_column = cursor.column; | |
| 13478 | } | |
| 13479 | ||
| 13579 | 13480 | /// Detects name conflicts for decls and fields, and populates `namespace.decls` with all named declarations. |
| 13580 | 13481 | /// Returns the number of declarations in the namespace, including unnamed declarations (e.g. `comptime` decls). |
| 13581 | 13482 | fn scanContainer( |
lib/std/zig/Zir.zig+12-99| ... | ... | @@ -2494,46 +2494,25 @@ pub const Inst = struct { |
| 2494 | 2494 | |
| 2495 | 2495 | /// Trailing: |
| 2496 | 2496 | /// 0. lib_name: NullTerminatedString, // null terminated string index, if has_lib_name is set |
| 2497 | /// if (has_align_ref and !has_align_body) { | |
| 2498 | /// 1. align: Ref, | |
| 2499 | /// } | |
| 2500 | /// if (has_align_body) { | |
| 2501 | /// 2. align_body_len: u32 | |
| 2502 | /// 3. align_body: u32 // for each align_body_len | |
| 2503 | /// } | |
| 2504 | /// if (has_addrspace_ref and !has_addrspace_body) { | |
| 2505 | /// 4. addrspace: Ref, | |
| 2506 | /// } | |
| 2507 | /// if (has_addrspace_body) { | |
| 2508 | /// 5. addrspace_body_len: u32 | |
| 2509 | /// 6. addrspace_body: u32 // for each addrspace_body_len | |
| 2510 | /// } | |
| 2511 | /// if (has_section_ref and !has_section_body) { | |
| 2512 | /// 7. section: Ref, | |
| 2513 | /// } | |
| 2514 | /// if (has_section_body) { | |
| 2515 | /// 8. section_body_len: u32 | |
| 2516 | /// 9. section_body: u32 // for each section_body_len | |
| 2517 | /// } | |
| 2518 | 2497 | /// if (has_cc_ref and !has_cc_body) { |
| 2519 | /// 10. cc: Ref, | |
| 2498 | /// 1. cc: Ref, | |
| 2520 | 2499 | /// } |
| 2521 | 2500 | /// if (has_cc_body) { |
| 2522 | /// 11. cc_body_len: u32 | |
| 2523 | /// 12. cc_body: u32 // for each cc_body_len | |
| 2501 | /// 2. cc_body_len: u32 | |
| 2502 | /// 3. cc_body: u32 // for each cc_body_len | |
| 2524 | 2503 | /// } |
| 2525 | 2504 | /// if (has_ret_ty_ref and !has_ret_ty_body) { |
| 2526 | /// 13. ret_ty: Ref, | |
| 2505 | /// 4. ret_ty: Ref, | |
| 2527 | 2506 | /// } |
| 2528 | 2507 | /// if (has_ret_ty_body) { |
| 2529 | /// 14. ret_ty_body_len: u32 | |
| 2530 | /// 15. ret_ty_body: u32 // for each ret_ty_body_len | |
| 2508 | /// 5. ret_ty_body_len: u32 | |
| 2509 | /// 6. ret_ty_body: u32 // for each ret_ty_body_len | |
| 2531 | 2510 | /// } |
| 2532 | /// 16. noalias_bits: u32 // if has_any_noalias | |
| 2533 | /// - each bit starting with LSB corresponds to parameter indexes | |
| 2534 | /// 17. body: Index // for each body_len | |
| 2535 | /// 18. src_locs: Func.SrcLocs // if body_len != 0 | |
| 2536 | /// 19. proto_hash: std.zig.SrcHash // if body_len != 0; hash of function prototype | |
| 2511 | /// 7. noalias_bits: u32 // if has_any_noalias | |
| 2512 | /// - each bit starting with LSB corresponds to parameter indexes | |
| 2513 | /// 8. body: Index // for each body_len | |
| 2514 | /// 9. src_locs: Func.SrcLocs // if body_len != 0 | |
| 2515 | /// 10. proto_hash: std.zig.SrcHash // if body_len != 0; hash of function prototype | |
| 2537 | 2516 | pub const FuncFancy = struct { |
| 2538 | 2517 | /// Points to the block that contains the param instructions for this function. |
| 2539 | 2518 | /// If this is a `declaration`, it refers to the declaration's value body. |
| ... | ... | @@ -2542,29 +2521,20 @@ pub const Inst = struct { |
| 2542 | 2521 | bits: Bits, |
| 2543 | 2522 | |
| 2544 | 2523 | /// If both has_cc_ref and has_cc_body are false, it means auto calling convention. |
| 2545 | /// If both has_align_ref and has_align_body are false, it means default alignment. | |
| 2546 | 2524 | /// If both has_ret_ty_ref and has_ret_ty_body are false, it means void return type. |
| 2547 | /// If both has_section_ref and has_section_body are false, it means default section. | |
| 2548 | /// If both has_addrspace_ref and has_addrspace_body are false, it means default addrspace. | |
| 2549 | 2525 | pub const Bits = packed struct { |
| 2550 | 2526 | is_var_args: bool, |
| 2551 | 2527 | is_inferred_error: bool, |
| 2552 | 2528 | is_test: bool, |
| 2553 | 2529 | is_extern: bool, |
| 2554 | 2530 | is_noinline: bool, |
| 2555 | has_align_ref: bool, | |
| 2556 | has_align_body: bool, | |
| 2557 | has_addrspace_ref: bool, | |
| 2558 | has_addrspace_body: bool, | |
| 2559 | has_section_ref: bool, | |
| 2560 | has_section_body: bool, | |
| 2561 | 2531 | has_cc_ref: bool, |
| 2562 | 2532 | has_cc_body: bool, |
| 2563 | 2533 | has_ret_ty_ref: bool, |
| 2564 | 2534 | has_ret_ty_body: bool, |
| 2565 | 2535 | has_lib_name: bool, |
| 2566 | 2536 | has_any_noalias: bool, |
| 2567 | _: u15 = undefined, | |
| 2537 | _: u21 = undefined, | |
| 2568 | 2538 | }; |
| 2569 | 2539 | }; |
| 2570 | 2540 | |
| ... | ... | @@ -4269,36 +4239,6 @@ fn findTrackableInner( |
| 4269 | 4239 | var extra_index: usize = extra.end; |
| 4270 | 4240 | extra_index += @intFromBool(extra.data.bits.has_lib_name); |
| 4271 | 4241 | |
| 4272 | if (extra.data.bits.has_align_body) { | |
| 4273 | const body_len = zir.extra[extra_index]; | |
| 4274 | extra_index += 1; | |
| 4275 | const body = zir.bodySlice(extra_index, body_len); | |
| 4276 | try zir.findTrackableBody(gpa, contents, defers, body); | |
| 4277 | extra_index += body.len; | |
| 4278 | } else if (extra.data.bits.has_align_ref) { | |
| 4279 | extra_index += 1; | |
| 4280 | } | |
| 4281 | ||
| 4282 | if (extra.data.bits.has_addrspace_body) { | |
| 4283 | const body_len = zir.extra[extra_index]; | |
| 4284 | extra_index += 1; | |
| 4285 | const body = zir.bodySlice(extra_index, body_len); | |
| 4286 | try zir.findTrackableBody(gpa, contents, defers, body); | |
| 4287 | extra_index += body.len; | |
| 4288 | } else if (extra.data.bits.has_addrspace_ref) { | |
| 4289 | extra_index += 1; | |
| 4290 | } | |
| 4291 | ||
| 4292 | if (extra.data.bits.has_section_body) { | |
| 4293 | const body_len = zir.extra[extra_index]; | |
| 4294 | extra_index += 1; | |
| 4295 | const body = zir.bodySlice(extra_index, body_len); | |
| 4296 | try zir.findTrackableBody(gpa, contents, defers, body); | |
| 4297 | extra_index += body.len; | |
| 4298 | } else if (extra.data.bits.has_section_ref) { | |
| 4299 | extra_index += 1; | |
| 4300 | } | |
| 4301 | ||
| 4302 | 4242 | if (extra.data.bits.has_cc_body) { |
| 4303 | 4243 | const body_len = zir.extra[extra_index]; |
| 4304 | 4244 | extra_index += 1; |
| ... | ... | @@ -4587,21 +4527,6 @@ pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo { |
| 4587 | 4527 | var ret_ty_body: []const Inst.Index = &.{}; |
| 4588 | 4528 | |
| 4589 | 4529 | extra_index += @intFromBool(extra.data.bits.has_lib_name); |
| 4590 | if (extra.data.bits.has_align_body) { | |
| 4591 | extra_index += zir.extra[extra_index] + 1; | |
| 4592 | } else if (extra.data.bits.has_align_ref) { | |
| 4593 | extra_index += 1; | |
| 4594 | } | |
| 4595 | if (extra.data.bits.has_addrspace_body) { | |
| 4596 | extra_index += zir.extra[extra_index] + 1; | |
| 4597 | } else if (extra.data.bits.has_addrspace_ref) { | |
| 4598 | extra_index += 1; | |
| 4599 | } | |
| 4600 | if (extra.data.bits.has_section_body) { | |
| 4601 | extra_index += zir.extra[extra_index] + 1; | |
| 4602 | } else if (extra.data.bits.has_section_ref) { | |
| 4603 | extra_index += 1; | |
| 4604 | } | |
| 4605 | 4530 | if (extra.data.bits.has_cc_body) { |
| 4606 | 4531 | extra_index += zir.extra[extra_index] + 1; |
| 4607 | 4532 | } else if (extra.data.bits.has_cc_ref) { |
| ... | ... | @@ -4712,18 +4637,6 @@ pub fn getAssociatedSrcHash(zir: Zir, inst: Zir.Inst.Index) ?std.zig.SrcHash { |
| 4712 | 4637 | const bits = extra.data.bits; |
| 4713 | 4638 | var extra_index = extra.end; |
| 4714 | 4639 | extra_index += @intFromBool(bits.has_lib_name); |
| 4715 | if (bits.has_align_body) { | |
| 4716 | const body_len = zir.extra[extra_index]; | |
| 4717 | extra_index += 1 + body_len; | |
| 4718 | } else extra_index += @intFromBool(bits.has_align_ref); | |
| 4719 | if (bits.has_addrspace_body) { | |
| 4720 | const body_len = zir.extra[extra_index]; | |
| 4721 | extra_index += 1 + body_len; | |
| 4722 | } else extra_index += @intFromBool(bits.has_addrspace_ref); | |
| 4723 | if (bits.has_section_body) { | |
| 4724 | const body_len = zir.extra[extra_index]; | |
| 4725 | extra_index += 1 + body_len; | |
| 4726 | } else extra_index += @intFromBool(bits.has_section_ref); | |
| 4727 | 4640 | if (bits.has_cc_body) { |
| 4728 | 4641 | const body_len = zir.extra[extra_index]; |
| 4729 | 4642 | extra_index += 1 + body_len; |
src/InternPool.zig+9-38| ... | ... | @@ -1961,9 +1961,6 @@ pub const Key = union(enum) { |
| 1961 | 1961 | is_var_args: bool, |
| 1962 | 1962 | is_generic: bool, |
| 1963 | 1963 | is_noinline: bool, |
| 1964 | cc_is_generic: bool, | |
| 1965 | section_is_generic: bool, | |
| 1966 | addrspace_is_generic: bool, | |
| 1967 | 1964 | |
| 1968 | 1965 | pub fn paramIsComptime(self: @This(), i: u5) bool { |
| 1969 | 1966 | assert(i < self.param_types.len); |
| ... | ... | @@ -5456,10 +5453,7 @@ pub const Tag = enum(u8) { |
| 5456 | 5453 | has_comptime_bits: bool, |
| 5457 | 5454 | has_noalias_bits: bool, |
| 5458 | 5455 | is_noinline: bool, |
| 5459 | cc_is_generic: bool, | |
| 5460 | section_is_generic: bool, | |
| 5461 | addrspace_is_generic: bool, | |
| 5462 | _: u6 = 0, | |
| 5456 | _: u9 = 0, | |
| 5463 | 5457 | }; |
| 5464 | 5458 | }; |
| 5465 | 5459 | |
| ... | ... | @@ -6885,9 +6879,6 @@ fn extraFuncType(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Ke |
| 6885 | 6879 | .cc = type_function.data.flags.cc.unpack(), |
| 6886 | 6880 | .is_var_args = type_function.data.flags.is_var_args, |
| 6887 | 6881 | .is_noinline = type_function.data.flags.is_noinline, |
| 6888 | .cc_is_generic = type_function.data.flags.cc_is_generic, | |
| 6889 | .section_is_generic = type_function.data.flags.section_is_generic, | |
| 6890 | .addrspace_is_generic = type_function.data.flags.addrspace_is_generic, | |
| 6891 | 6882 | .is_generic = type_function.data.flags.is_generic, |
| 6892 | 6883 | }; |
| 6893 | 6884 | } |
| ... | ... | @@ -8529,9 +8520,6 @@ pub fn getFuncType( |
| 8529 | 8520 | .has_noalias_bits = key.noalias_bits != 0, |
| 8530 | 8521 | .is_generic = key.is_generic, |
| 8531 | 8522 | .is_noinline = key.is_noinline, |
| 8532 | .cc_is_generic = key.cc == null, | |
| 8533 | .section_is_generic = key.section_is_generic, | |
| 8534 | .addrspace_is_generic = key.addrspace_is_generic, | |
| 8535 | 8523 | }, |
| 8536 | 8524 | }); |
| 8537 | 8525 | |
| ... | ... | @@ -8703,10 +8691,6 @@ pub const GetFuncDeclIesKey = struct { |
| 8703 | 8691 | bare_return_type: Index, |
| 8704 | 8692 | /// null means generic. |
| 8705 | 8693 | cc: ?std.builtin.CallingConvention, |
| 8706 | /// null means generic. | |
| 8707 | alignment: ?Alignment, | |
| 8708 | section_is_generic: bool, | |
| 8709 | addrspace_is_generic: bool, | |
| 8710 | 8694 | is_var_args: bool, |
| 8711 | 8695 | is_generic: bool, |
| 8712 | 8696 | is_noinline: bool, |
| ... | ... | @@ -8792,9 +8776,6 @@ pub fn getFuncDeclIes( |
| 8792 | 8776 | .has_noalias_bits = key.noalias_bits != 0, |
| 8793 | 8777 | .is_generic = key.is_generic, |
| 8794 | 8778 | .is_noinline = key.is_noinline, |
| 8795 | .cc_is_generic = key.cc == null, | |
| 8796 | .section_is_generic = key.section_is_generic, | |
| 8797 | .addrspace_is_generic = key.addrspace_is_generic, | |
| 8798 | 8779 | }, |
| 8799 | 8780 | }); |
| 8800 | 8781 | if (key.comptime_bits != 0) extra.appendAssumeCapacity(.{key.comptime_bits}); |
| ... | ... | @@ -8926,9 +8907,6 @@ pub const GetFuncInstanceKey = struct { |
| 8926 | 8907 | comptime_args: []const Index, |
| 8927 | 8908 | noalias_bits: u32, |
| 8928 | 8909 | bare_return_type: Index, |
| 8929 | cc: std.builtin.CallingConvention, | |
| 8930 | alignment: Alignment, | |
| 8931 | section: OptionalNullTerminatedString, | |
| 8932 | 8910 | is_noinline: bool, |
| 8933 | 8911 | generic_owner: Index, |
| 8934 | 8912 | inferred_error_set: bool, |
| ... | ... | @@ -8943,11 +8921,14 @@ pub fn getFuncInstance( |
| 8943 | 8921 | if (arg.inferred_error_set) |
| 8944 | 8922 | return getFuncInstanceIes(ip, gpa, tid, arg); |
| 8945 | 8923 | |
| 8924 | const generic_owner = unwrapCoercedFunc(ip, arg.generic_owner); | |
| 8925 | const generic_owner_ty = ip.indexToKey(ip.funcDeclInfo(generic_owner).ty).func_type; | |
| 8926 | ||
| 8946 | 8927 | const func_ty = try ip.getFuncType(gpa, tid, .{ |
| 8947 | 8928 | .param_types = arg.param_types, |
| 8948 | 8929 | .return_type = arg.bare_return_type, |
| 8949 | 8930 | .noalias_bits = arg.noalias_bits, |
| 8950 | .cc = arg.cc, | |
| 8931 | .cc = generic_owner_ty.cc, | |
| 8951 | 8932 | .is_noinline = arg.is_noinline, |
| 8952 | 8933 | }); |
| 8953 | 8934 | |
| ... | ... | @@ -8957,8 +8938,6 @@ pub fn getFuncInstance( |
| 8957 | 8938 | try extra.ensureUnusedCapacity(@typeInfo(Tag.FuncInstance).@"struct".fields.len + |
| 8958 | 8939 | arg.comptime_args.len); |
| 8959 | 8940 | |
| 8960 | const generic_owner = unwrapCoercedFunc(ip, arg.generic_owner); | |
| 8961 | ||
| 8962 | 8941 | assert(arg.comptime_args.len == ip.funcTypeParamsLen(ip.typeOf(generic_owner))); |
| 8963 | 8942 | |
| 8964 | 8943 | const prev_extra_len = extra.mutate.len; |
| ... | ... | @@ -9005,8 +8984,6 @@ pub fn getFuncInstance( |
| 9005 | 8984 | generic_owner, |
| 9006 | 8985 | func_index, |
| 9007 | 8986 | func_extra_index, |
| 9008 | arg.alignment, | |
| 9009 | arg.section, | |
| 9010 | 8987 | ); |
| 9011 | 8988 | return gop.put(); |
| 9012 | 8989 | } |
| ... | ... | @@ -9031,6 +9008,7 @@ pub fn getFuncInstanceIes( |
| 9031 | 9008 | try items.ensureUnusedCapacity(4); |
| 9032 | 9009 | |
| 9033 | 9010 | const generic_owner = unwrapCoercedFunc(ip, arg.generic_owner); |
| 9011 | const generic_owner_ty = ip.indexToKey(ip.funcDeclInfo(arg.generic_owner).ty).func_type; | |
| 9034 | 9012 | |
| 9035 | 9013 | // The strategy here is to add the function decl unconditionally, then to |
| 9036 | 9014 | // ask if it already exists, and if so, revert the lengths of the mutated |
| ... | ... | @@ -9086,15 +9064,12 @@ pub fn getFuncInstanceIes( |
| 9086 | 9064 | .params_len = params_len, |
| 9087 | 9065 | .return_type = error_union_type, |
| 9088 | 9066 | .flags = .{ |
| 9089 | .cc = .pack(arg.cc), | |
| 9067 | .cc = .pack(generic_owner_ty.cc), | |
| 9090 | 9068 | .is_var_args = false, |
| 9091 | 9069 | .has_comptime_bits = false, |
| 9092 | 9070 | .has_noalias_bits = arg.noalias_bits != 0, |
| 9093 | 9071 | .is_generic = false, |
| 9094 | 9072 | .is_noinline = arg.is_noinline, |
| 9095 | .cc_is_generic = false, | |
| 9096 | .section_is_generic = false, | |
| 9097 | .addrspace_is_generic = false, | |
| 9098 | 9073 | }, |
| 9099 | 9074 | }); |
| 9100 | 9075 | // no comptime_bits because has_comptime_bits is false |
| ... | ... | @@ -9158,8 +9133,6 @@ pub fn getFuncInstanceIes( |
| 9158 | 9133 | generic_owner, |
| 9159 | 9134 | func_index, |
| 9160 | 9135 | func_extra_index, |
| 9161 | arg.alignment, | |
| 9162 | arg.section, | |
| 9163 | 9136 | ); |
| 9164 | 9137 | |
| 9165 | 9138 | func_gop.putFinal(func_index); |
| ... | ... | @@ -9177,8 +9150,6 @@ fn finishFuncInstance( |
| 9177 | 9150 | generic_owner: Index, |
| 9178 | 9151 | func_index: Index, |
| 9179 | 9152 | func_extra_index: u32, |
| 9180 | alignment: Alignment, | |
| 9181 | section: OptionalNullTerminatedString, | |
| 9182 | 9153 | ) Allocator.Error!void { |
| 9183 | 9154 | const fn_owner_nav = ip.getNav(ip.funcDeclInfo(generic_owner).owner_nav); |
| 9184 | 9155 | const fn_namespace = ip.getCau(fn_owner_nav.analysis_owner.unwrap().?).namespace; |
| ... | ... | @@ -9191,8 +9162,8 @@ fn finishFuncInstance( |
| 9191 | 9162 | .name = nav_name, |
| 9192 | 9163 | .fqn = try ip.namespacePtr(fn_namespace).internFullyQualifiedName(ip, gpa, tid, nav_name), |
| 9193 | 9164 | .val = func_index, |
| 9194 | .alignment = alignment, | |
| 9195 | .@"linksection" = section, | |
| 9165 | .alignment = fn_owner_nav.status.resolved.alignment, | |
| 9166 | .@"linksection" = fn_owner_nav.status.resolved.@"linksection", | |
| 9196 | 9167 | .@"addrspace" = fn_owner_nav.status.resolved.@"addrspace", |
| 9197 | 9168 | }); |
| 9198 | 9169 |
src/Sema.zig+89-269| ... | ... | @@ -7815,11 +7815,9 @@ fn analyzeCall( |
| 7815 | 7815 | .param_types = new_param_types, |
| 7816 | 7816 | .return_type = owner_info.return_type, |
| 7817 | 7817 | .noalias_bits = owner_info.noalias_bits, |
| 7818 | .cc = if (owner_info.cc_is_generic) null else owner_info.cc, | |
| 7818 | .cc = owner_info.cc, | |
| 7819 | 7819 | .is_var_args = owner_info.is_var_args, |
| 7820 | 7820 | .is_noinline = owner_info.is_noinline, |
| 7821 | .section_is_generic = owner_info.section_is_generic, | |
| 7822 | .addrspace_is_generic = owner_info.addrspace_is_generic, | |
| 7823 | 7821 | .is_generic = owner_info.is_generic, |
| 7824 | 7822 | }; |
| 7825 | 7823 | |
| ... | ... | @@ -9555,9 +9553,6 @@ fn zirFunc( |
| 9555 | 9553 | block, |
| 9556 | 9554 | inst_data.src_node, |
| 9557 | 9555 | inst, |
| 9558 | .none, | |
| 9559 | target_util.defaultAddressSpace(target, .function), | |
| 9560 | .default, | |
| 9561 | 9556 | cc, |
| 9562 | 9557 | ret_ty, |
| 9563 | 9558 | false, |
| ... | ... | @@ -9843,13 +9838,7 @@ fn funcCommon( |
| 9843 | 9838 | block: *Block, |
| 9844 | 9839 | src_node_offset: i32, |
| 9845 | 9840 | func_inst: Zir.Inst.Index, |
| 9846 | /// null means generic poison | |
| 9847 | alignment: ?Alignment, | |
| 9848 | /// null means generic poison | |
| 9849 | address_space: ?std.builtin.AddressSpace, | |
| 9850 | section: Section, | |
| 9851 | /// null means generic poison | |
| 9852 | cc: ?std.builtin.CallingConvention, | |
| 9841 | cc: std.builtin.CallingConvention, | |
| 9853 | 9842 | /// this might be Type.generic_poison |
| 9854 | 9843 | bare_return_type: Type, |
| 9855 | 9844 | var_args: bool, |
| ... | ... | @@ -9870,26 +9859,17 @@ fn funcCommon( |
| 9870 | 9859 | const cc_src = block.src(.{ .node_offset_fn_type_cc = src_node_offset }); |
| 9871 | 9860 | const func_src = block.nodeOffset(src_node_offset); |
| 9872 | 9861 | |
| 9873 | var is_generic = bare_return_type.isGenericPoison() or | |
| 9874 | alignment == null or | |
| 9875 | address_space == null or | |
| 9876 | section == .generic or | |
| 9877 | cc == null; | |
| 9862 | var is_generic = bare_return_type.isGenericPoison(); | |
| 9878 | 9863 | |
| 9879 | 9864 | if (var_args) { |
| 9880 | 9865 | if (is_generic) { |
| 9881 | 9866 | return sema.fail(block, func_src, "generic function cannot be variadic", .{}); |
| 9882 | 9867 | } |
| 9883 | try sema.checkCallConvSupportsVarArgs(block, cc_src, cc.?); | |
| 9868 | try sema.checkCallConvSupportsVarArgs(block, cc_src, cc); | |
| 9884 | 9869 | } |
| 9885 | 9870 | |
| 9886 | 9871 | const is_source_decl = sema.generic_owner == .none; |
| 9887 | 9872 | |
| 9888 | // In the case of generic calling convention, or generic alignment, we use | |
| 9889 | // default values which are only meaningful for the generic function, *not* | |
| 9890 | // the instantiation, which can depend on comptime parameters. | |
| 9891 | // Related proposal: https://github.com/ziglang/zig/issues/11834 | |
| 9892 | const cc_resolved = cc orelse .auto; | |
| 9893 | 9873 | var comptime_bits: u32 = 0; |
| 9894 | 9874 | for (block.params.items(.ty), block.params.items(.is_comptime), 0..) |param_ty_ip, param_is_comptime, i| { |
| 9895 | 9875 | const param_ty = Type.fromInterned(param_ty_ip); |
| ... | ... | @@ -9907,11 +9887,11 @@ fn funcCommon( |
| 9907 | 9887 | } |
| 9908 | 9888 | const this_generic = param_ty.isGenericPoison(); |
| 9909 | 9889 | is_generic = is_generic or this_generic; |
| 9910 | if (param_is_comptime and !target_util.fnCallConvAllowsZigTypes(cc_resolved)) { | |
| 9911 | return sema.fail(block, param_src, "comptime parameters not allowed in function with calling convention '{s}'", .{@tagName(cc_resolved)}); | |
| 9890 | if (param_is_comptime and !target_util.fnCallConvAllowsZigTypes(cc)) { | |
| 9891 | return sema.fail(block, param_src, "comptime parameters not allowed in function with calling convention '{s}'", .{@tagName(cc)}); | |
| 9912 | 9892 | } |
| 9913 | if (this_generic and !sema.no_partial_func_ty and !target_util.fnCallConvAllowsZigTypes(cc_resolved)) { | |
| 9914 | return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{s}'", .{@tagName(cc_resolved)}); | |
| 9893 | if (this_generic and !sema.no_partial_func_ty and !target_util.fnCallConvAllowsZigTypes(cc)) { | |
| 9894 | return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{s}'", .{@tagName(cc)}); | |
| 9915 | 9895 | } |
| 9916 | 9896 | if (!param_ty.isValidParamType(zcu)) { |
| 9917 | 9897 | const opaque_str = if (param_ty.zigTypeTag(zcu) == .@"opaque") "opaque " else ""; |
| ... | ... | @@ -9919,10 +9899,10 @@ fn funcCommon( |
| 9919 | 9899 | opaque_str, param_ty.fmt(pt), |
| 9920 | 9900 | }); |
| 9921 | 9901 | } |
| 9922 | if (!this_generic and !target_util.fnCallConvAllowsZigTypes(cc_resolved) and !try sema.validateExternType(param_ty, .param_ty)) { | |
| 9902 | if (!this_generic and !target_util.fnCallConvAllowsZigTypes(cc) and !try sema.validateExternType(param_ty, .param_ty)) { | |
| 9923 | 9903 | const msg = msg: { |
| 9924 | 9904 | const msg = try sema.errMsg(param_src, "parameter of type '{}' not allowed in function with calling convention '{s}'", .{ |
| 9925 | param_ty.fmt(pt), @tagName(cc_resolved), | |
| 9905 | param_ty.fmt(pt), @tagName(cc), | |
| 9926 | 9906 | }); |
| 9927 | 9907 | errdefer msg.destroy(sema.gpa); |
| 9928 | 9908 | |
| ... | ... | @@ -9952,13 +9932,13 @@ fn funcCommon( |
| 9952 | 9932 | { |
| 9953 | 9933 | return sema.fail(block, param_src, "non-pointer parameter declared noalias", .{}); |
| 9954 | 9934 | } |
| 9955 | switch (cc_resolved) { | |
| 9935 | switch (cc) { | |
| 9956 | 9936 | .x86_64_interrupt, .x86_interrupt => { |
| 9957 | 9937 | const err_code_size = target.ptrBitWidth(); |
| 9958 | 9938 | switch (i) { |
| 9959 | 0 => if (param_ty.zigTypeTag(zcu) != .pointer) return sema.fail(block, param_src, "first parameter of function with '{s}' calling convention must be a pointer type", .{@tagName(cc_resolved)}), | |
| 9960 | 1 => if (param_ty.bitSize(zcu) != err_code_size) return sema.fail(block, param_src, "second parameter of function with '{s}' calling convention must be a {d}-bit integer", .{ @tagName(cc_resolved), err_code_size }), | |
| 9961 | else => return sema.fail(block, param_src, "'{s}' calling convention supports up to 2 parameters, found {d}", .{ @tagName(cc_resolved), i + 1 }), | |
| 9939 | 0 => if (param_ty.zigTypeTag(zcu) != .pointer) return sema.fail(block, param_src, "first parameter of function with '{s}' calling convention must be a pointer type", .{@tagName(cc)}), | |
| 9940 | 1 => if (param_ty.bitSize(zcu) != err_code_size) return sema.fail(block, param_src, "second parameter of function with '{s}' calling convention must be a {d}-bit integer", .{ @tagName(cc), err_code_size }), | |
| 9941 | else => return sema.fail(block, param_src, "'{s}' calling convention supports up to 2 parameters, found {d}", .{ @tagName(cc), i + 1 }), | |
| 9962 | 9942 | } |
| 9963 | 9943 | }, |
| 9964 | 9944 | .arm_interrupt, |
| ... | ... | @@ -9970,7 +9950,7 @@ fn funcCommon( |
| 9970 | 9950 | .csky_interrupt, |
| 9971 | 9951 | .m68k_interrupt, |
| 9972 | 9952 | .avr_signal, |
| 9973 | => return sema.fail(block, param_src, "parameters are not allowed with '{s}' calling convention", .{@tagName(cc_resolved)}), | |
| 9953 | => return sema.fail(block, param_src, "parameters are not allowed with '{s}' calling convention", .{@tagName(cc)}), | |
| 9974 | 9954 | else => {}, |
| 9975 | 9955 | } |
| 9976 | 9956 | } |
| ... | ... | @@ -9985,9 +9965,6 @@ fn funcCommon( |
| 9985 | 9965 | assert(has_body); |
| 9986 | 9966 | assert(!is_generic); |
| 9987 | 9967 | assert(comptime_bits == 0); |
| 9988 | assert(cc != null); | |
| 9989 | assert(section != .generic); | |
| 9990 | assert(address_space != null); | |
| 9991 | 9968 | assert(!var_args); |
| 9992 | 9969 | if (inferred_error_set) { |
| 9993 | 9970 | try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src); |
| ... | ... | @@ -9996,13 +9973,6 @@ fn funcCommon( |
| 9996 | 9973 | .param_types = param_types, |
| 9997 | 9974 | .noalias_bits = noalias_bits, |
| 9998 | 9975 | .bare_return_type = bare_return_type.toIntern(), |
| 9999 | .cc = cc_resolved, | |
| 10000 | .alignment = alignment.?, | |
| 10001 | .section = switch (section) { | |
| 10002 | .generic => unreachable, | |
| 10003 | .default => .none, | |
| 10004 | .explicit => |x| x.toOptional(), | |
| 10005 | }, | |
| 10006 | 9976 | .is_noinline = is_noinline, |
| 10007 | 9977 | .inferred_error_set = inferred_error_set, |
| 10008 | 9978 | .generic_owner = sema.generic_owner, |
| ... | ... | @@ -10016,7 +9986,7 @@ fn funcCommon( |
| 10016 | 9986 | ret_poison, |
| 10017 | 9987 | bare_return_type, |
| 10018 | 9988 | ret_ty_src, |
| 10019 | cc_resolved, | |
| 9989 | cc, | |
| 10020 | 9990 | is_source_decl, |
| 10021 | 9991 | ret_ty_requires_comptime, |
| 10022 | 9992 | func_inst, |
| ... | ... | @@ -10027,12 +9997,6 @@ fn funcCommon( |
| 10027 | 9997 | ); |
| 10028 | 9998 | } |
| 10029 | 9999 | |
| 10030 | const section_name: InternPool.OptionalNullTerminatedString = switch (section) { | |
| 10031 | .generic => .none, | |
| 10032 | .default => .none, | |
| 10033 | .explicit => |name| name.toOptional(), | |
| 10034 | }; | |
| 10035 | ||
| 10036 | 10000 | if (inferred_error_set) { |
| 10037 | 10001 | assert(!is_extern); |
| 10038 | 10002 | assert(has_body); |
| ... | ... | @@ -10046,9 +10010,6 @@ fn funcCommon( |
| 10046 | 10010 | .comptime_bits = comptime_bits, |
| 10047 | 10011 | .bare_return_type = bare_return_type.toIntern(), |
| 10048 | 10012 | .cc = cc, |
| 10049 | .alignment = alignment, | |
| 10050 | .section_is_generic = section == .generic, | |
| 10051 | .addrspace_is_generic = address_space == null, | |
| 10052 | 10013 | .is_var_args = var_args, |
| 10053 | 10014 | .is_generic = final_is_generic, |
| 10054 | 10015 | .is_noinline = is_noinline, |
| ... | ... | @@ -10059,13 +10020,6 @@ fn funcCommon( |
| 10059 | 10020 | .lbrace_column = @as(u16, @truncate(src_locs.columns)), |
| 10060 | 10021 | .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)), |
| 10061 | 10022 | }); |
| 10062 | // func_decl functions take ownership of the `Nav` of Sema'a owner `Cau`. | |
| 10063 | ip.resolveNavValue(sema.getOwnerCauNav(), .{ | |
| 10064 | .val = func_index, | |
| 10065 | .alignment = alignment orelse .none, | |
| 10066 | .@"linksection" = section_name, | |
| 10067 | .@"addrspace" = address_space orelse .generic, | |
| 10068 | }); | |
| 10069 | 10023 | return finishFunc( |
| 10070 | 10024 | sema, |
| 10071 | 10025 | block, |
| ... | ... | @@ -10074,7 +10028,7 @@ fn funcCommon( |
| 10074 | 10028 | ret_poison, |
| 10075 | 10029 | bare_return_type, |
| 10076 | 10030 | ret_ty_src, |
| 10077 | cc_resolved, | |
| 10031 | cc, | |
| 10078 | 10032 | is_source_decl, |
| 10079 | 10033 | ret_ty_requires_comptime, |
| 10080 | 10034 | func_inst, |
| ... | ... | @@ -10091,8 +10045,6 @@ fn funcCommon( |
| 10091 | 10045 | .comptime_bits = comptime_bits, |
| 10092 | 10046 | .return_type = bare_return_type.toIntern(), |
| 10093 | 10047 | .cc = cc, |
| 10094 | .section_is_generic = section == .generic, | |
| 10095 | .addrspace_is_generic = address_space == null, | |
| 10096 | 10048 | .is_var_args = var_args, |
| 10097 | 10049 | .is_generic = final_is_generic, |
| 10098 | 10050 | .is_noinline = is_noinline, |
| ... | ... | @@ -10100,38 +10052,20 @@ fn funcCommon( |
| 10100 | 10052 | |
| 10101 | 10053 | if (is_extern) { |
| 10102 | 10054 | assert(comptime_bits == 0); |
| 10103 | assert(cc != null); | |
| 10104 | assert(alignment != null); | |
| 10105 | assert(section != .generic); | |
| 10106 | assert(address_space != null); | |
| 10107 | 10055 | assert(!is_generic); |
| 10108 | 10056 | if (opt_lib_name) |lib_name| try sema.handleExternLibName(block, block.src(.{ |
| 10109 | 10057 | .node_offset_lib_name = src_node_offset, |
| 10110 | 10058 | }), lib_name); |
| 10111 | const func_index = try pt.getExtern(.{ | |
| 10112 | .name = sema.getOwnerCauNavName(), | |
| 10113 | .ty = func_ty, | |
| 10114 | .lib_name = try ip.getOrPutStringOpt(gpa, pt.tid, opt_lib_name, .no_embedded_nulls), | |
| 10115 | .is_const = true, | |
| 10116 | .is_threadlocal = false, | |
| 10117 | .is_weak_linkage = false, | |
| 10118 | .is_dll_import = false, | |
| 10119 | .alignment = alignment orelse .none, | |
| 10120 | .@"addrspace" = address_space orelse .generic, | |
| 10121 | .zir_index = sema.getOwnerCauDeclInst(), // `declaration` instruction | |
| 10122 | .owner_nav = undefined, // ignored by `getExtern` | |
| 10123 | }); | |
| 10124 | // Note that unlike function declaration, extern functions don't touch the | |
| 10125 | // Sema's owner Cau's owner Nav. The alignment etc were passed above. | |
| 10059 | const extern_func_index = try sema.resolveExternDecl(block, .fromInterned(func_ty), opt_lib_name, true, false); | |
| 10126 | 10060 | return finishFunc( |
| 10127 | 10061 | sema, |
| 10128 | 10062 | block, |
| 10129 | func_index, | |
| 10063 | extern_func_index, | |
| 10130 | 10064 | func_ty, |
| 10131 | 10065 | ret_poison, |
| 10132 | 10066 | bare_return_type, |
| 10133 | 10067 | ret_ty_src, |
| 10134 | cc_resolved, | |
| 10068 | cc, | |
| 10135 | 10069 | is_source_decl, |
| 10136 | 10070 | ret_ty_requires_comptime, |
| 10137 | 10071 | func_inst, |
| ... | ... | @@ -10154,13 +10088,6 @@ fn funcCommon( |
| 10154 | 10088 | .lbrace_column = @as(u16, @truncate(src_locs.columns)), |
| 10155 | 10089 | .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)), |
| 10156 | 10090 | }); |
| 10157 | // func_decl functions take ownership of the `Nav` of Sema'a owner `Cau`. | |
| 10158 | ip.resolveNavValue(sema.getOwnerCauNav(), .{ | |
| 10159 | .val = func_index, | |
| 10160 | .alignment = alignment orelse .none, | |
| 10161 | .@"linksection" = section_name, | |
| 10162 | .@"addrspace" = address_space orelse .generic, | |
| 10163 | }); | |
| 10164 | 10091 | return finishFunc( |
| 10165 | 10092 | sema, |
| 10166 | 10093 | block, |
| ... | ... | @@ -10169,7 +10096,7 @@ fn funcCommon( |
| 10169 | 10096 | ret_poison, |
| 10170 | 10097 | bare_return_type, |
| 10171 | 10098 | ret_ty_src, |
| 10172 | cc_resolved, | |
| 10099 | cc, | |
| 10173 | 10100 | is_source_decl, |
| 10174 | 10101 | ret_ty_requires_comptime, |
| 10175 | 10102 | func_inst, |
| ... | ... | @@ -10188,7 +10115,7 @@ fn funcCommon( |
| 10188 | 10115 | ret_poison, |
| 10189 | 10116 | bare_return_type, |
| 10190 | 10117 | ret_ty_src, |
| 10191 | cc_resolved, | |
| 10118 | cc, | |
| 10192 | 10119 | is_source_decl, |
| 10193 | 10120 | ret_ty_requires_comptime, |
| 10194 | 10121 | func_inst, |
| ... | ... | @@ -26839,52 +26766,8 @@ fn zirVarExtended( |
| 26839 | 26766 | try sema.validateVarType(block, ty_src, var_ty, small.is_extern); |
| 26840 | 26767 | |
| 26841 | 26768 | if (small.is_extern) { |
| 26842 | // We need to resolve the alignment and addrspace early. | |
| 26843 | // Keep in sync with logic in `Zcu.PerThread.semaCau`. | |
| 26844 | const align_src = block.src(.{ .node_offset_var_decl_align = 0 }); | |
| 26845 | const addrspace_src = block.src(.{ .node_offset_var_decl_addrspace = 0 }); | |
| 26846 | ||
| 26847 | const decl_inst, const decl_bodies = decl: { | |
| 26848 | const decl_inst = sema.getOwnerCauDeclInst().resolve(ip) orelse return error.AnalysisFail; | |
| 26849 | const zir_decl, const extra_end = sema.code.getDeclaration(decl_inst); | |
| 26850 | break :decl .{ decl_inst, zir_decl.getBodies(extra_end, sema.code) }; | |
| 26851 | }; | |
| 26852 | ||
| 26853 | const alignment: InternPool.Alignment = a: { | |
| 26854 | const align_body = decl_bodies.align_body orelse break :a .none; | |
| 26855 | const align_ref = try sema.resolveInlineBody(block, align_body, decl_inst); | |
| 26856 | break :a try sema.analyzeAsAlign(block, align_src, align_ref); | |
| 26857 | }; | |
| 26858 | ||
| 26859 | const @"addrspace": std.builtin.AddressSpace = as: { | |
| 26860 | const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(var_ty.toIntern())) { | |
| 26861 | .func_type => .function, | |
| 26862 | else => .variable, | |
| 26863 | }; | |
| 26864 | const target = zcu.getTarget(); | |
| 26865 | const addrspace_body = decl_bodies.addrspace_body orelse break :as switch (addrspace_ctx) { | |
| 26866 | .function => target_util.defaultAddressSpace(target, .function), | |
| 26867 | .variable => target_util.defaultAddressSpace(target, .global_mutable), | |
| 26868 | .constant => target_util.defaultAddressSpace(target, .global_constant), | |
| 26869 | else => unreachable, | |
| 26870 | }; | |
| 26871 | const addrspace_ref = try sema.resolveInlineBody(block, addrspace_body, decl_inst); | |
| 26872 | break :as try sema.analyzeAsAddressSpace(block, addrspace_src, addrspace_ref, addrspace_ctx); | |
| 26873 | }; | |
| 26874 | ||
| 26875 | return Air.internedToRef(try pt.getExtern(.{ | |
| 26876 | .name = sema.getOwnerCauNavName(), | |
| 26877 | .ty = var_ty.toIntern(), | |
| 26878 | .lib_name = try ip.getOrPutStringOpt(sema.gpa, pt.tid, lib_name, .no_embedded_nulls), | |
| 26879 | .is_const = small.is_const, | |
| 26880 | .is_threadlocal = small.is_threadlocal, | |
| 26881 | .is_weak_linkage = false, | |
| 26882 | .is_dll_import = false, | |
| 26883 | .alignment = alignment, | |
| 26884 | .@"addrspace" = @"addrspace", | |
| 26885 | .zir_index = sema.getOwnerCauDeclInst(), // `declaration` instruction | |
| 26886 | .owner_nav = undefined, // ignored by `getExtern` | |
| 26887 | })); | |
| 26769 | const extern_val = try sema.resolveExternDecl(block, var_ty, lib_name, small.is_const, small.is_threadlocal); | |
| 26770 | return Air.internedToRef(extern_val); | |
| 26888 | 26771 | } |
| 26889 | 26772 | assert(!small.is_const); // non-const non-extern variable is not legal |
| 26890 | 26773 | return Air.internedToRef(try pt.intern(.{ .variable = .{ |
| ... | ... | @@ -26897,6 +26780,66 @@ fn zirVarExtended( |
| 26897 | 26780 | } })); |
| 26898 | 26781 | } |
| 26899 | 26782 | |
| 26783 | fn resolveExternDecl( | |
| 26784 | sema: *Sema, | |
| 26785 | block: *Block, | |
| 26786 | ty: Type, | |
| 26787 | opt_lib_name: ?[]const u8, | |
| 26788 | is_const: bool, | |
| 26789 | is_threadlocal: bool, | |
| 26790 | ) CompileError!InternPool.Index { | |
| 26791 | const pt = sema.pt; | |
| 26792 | const zcu = pt.zcu; | |
| 26793 | const ip = &zcu.intern_pool; | |
| 26794 | ||
| 26795 | // We need to resolve the alignment and addrspace early. | |
| 26796 | // Keep in sync with logic in `Zcu.PerThread.semaCau`. | |
| 26797 | const align_src = block.src(.{ .node_offset_var_decl_align = 0 }); | |
| 26798 | const addrspace_src = block.src(.{ .node_offset_var_decl_addrspace = 0 }); | |
| 26799 | ||
| 26800 | const decl_inst, const decl_bodies = decl: { | |
| 26801 | const decl_inst = sema.getOwnerCauDeclInst().resolve(ip) orelse return error.AnalysisFail; | |
| 26802 | const zir_decl, const extra_end = sema.code.getDeclaration(decl_inst); | |
| 26803 | break :decl .{ decl_inst, zir_decl.getBodies(extra_end, sema.code) }; | |
| 26804 | }; | |
| 26805 | ||
| 26806 | const alignment: InternPool.Alignment = a: { | |
| 26807 | const align_body = decl_bodies.align_body orelse break :a .none; | |
| 26808 | const align_ref = try sema.resolveInlineBody(block, align_body, decl_inst); | |
| 26809 | break :a try sema.analyzeAsAlign(block, align_src, align_ref); | |
| 26810 | }; | |
| 26811 | ||
| 26812 | const @"addrspace": std.builtin.AddressSpace = as: { | |
| 26813 | const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(ty.toIntern())) { | |
| 26814 | .func_type => .function, | |
| 26815 | else => .variable, | |
| 26816 | }; | |
| 26817 | const target = zcu.getTarget(); | |
| 26818 | const addrspace_body = decl_bodies.addrspace_body orelse break :as switch (addrspace_ctx) { | |
| 26819 | .function => target_util.defaultAddressSpace(target, .function), | |
| 26820 | .variable => target_util.defaultAddressSpace(target, .global_mutable), | |
| 26821 | .constant => target_util.defaultAddressSpace(target, .global_constant), | |
| 26822 | else => unreachable, | |
| 26823 | }; | |
| 26824 | const addrspace_ref = try sema.resolveInlineBody(block, addrspace_body, decl_inst); | |
| 26825 | break :as try sema.analyzeAsAddressSpace(block, addrspace_src, addrspace_ref, addrspace_ctx); | |
| 26826 | }; | |
| 26827 | ||
| 26828 | return pt.getExtern(.{ | |
| 26829 | .name = sema.getOwnerCauNavName(), | |
| 26830 | .ty = ty.toIntern(), | |
| 26831 | .lib_name = try ip.getOrPutStringOpt(sema.gpa, pt.tid, opt_lib_name, .no_embedded_nulls), | |
| 26832 | .is_const = is_const, | |
| 26833 | .is_threadlocal = is_threadlocal, | |
| 26834 | .is_weak_linkage = false, | |
| 26835 | .is_dll_import = false, | |
| 26836 | .alignment = alignment, | |
| 26837 | .@"addrspace" = @"addrspace", | |
| 26838 | .zir_index = sema.getOwnerCauDeclInst(), // `declaration` instruction | |
| 26839 | .owner_nav = undefined, // ignored by `getExtern` | |
| 26840 | }); | |
| 26841 | } | |
| 26842 | ||
| 26900 | 26843 | fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 26901 | 26844 | const tracy = trace(@src()); |
| 26902 | 26845 | defer tracy.end(); |
| ... | ... | @@ -26908,9 +26851,6 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 26908 | 26851 | const extra = sema.code.extraData(Zir.Inst.FuncFancy, inst_data.payload_index); |
| 26909 | 26852 | const target = zcu.getTarget(); |
| 26910 | 26853 | |
| 26911 | const align_src = block.src(.{ .node_offset_fn_type_align = inst_data.src_node }); | |
| 26912 | const addrspace_src = block.src(.{ .node_offset_fn_type_addrspace = inst_data.src_node }); | |
| 26913 | const section_src = block.src(.{ .node_offset_fn_type_section = inst_data.src_node }); | |
| 26914 | 26854 | const cc_src = block.src(.{ .node_offset_fn_type_cc = inst_data.src_node }); |
| 26915 | 26855 | const ret_src = block.src(.{ .node_offset_fn_type_ret_ty = inst_data.src_node }); |
| 26916 | 26856 | const has_body = extra.data.body_len != 0; |
| ... | ... | @@ -26924,112 +26864,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 26924 | 26864 | break :blk lib_name; |
| 26925 | 26865 | } else null; |
| 26926 | 26866 | |
| 26927 | if (has_body and | |
| 26928 | (extra.data.bits.has_align_body or extra.data.bits.has_align_ref) and | |
| 26929 | !target_util.supportsFunctionAlignment(target)) | |
| 26930 | { | |
| 26931 | return sema.fail(block, align_src, "target does not support function alignment", .{}); | |
| 26932 | } | |
| 26933 | ||
| 26934 | const @"align": ?Alignment = if (extra.data.bits.has_align_body) blk: { | |
| 26935 | const body_len = sema.code.extra[extra_index]; | |
| 26936 | extra_index += 1; | |
| 26937 | const body = sema.code.bodySlice(extra_index, body_len); | |
| 26938 | extra_index += body.len; | |
| 26939 | ||
| 26940 | const val = try sema.resolveGenericBody(block, align_src, body, inst, Type.u29, .{ | |
| 26941 | .needed_comptime_reason = "alignment must be comptime-known", | |
| 26942 | }); | |
| 26943 | if (val.isGenericPoison()) { | |
| 26944 | break :blk null; | |
| 26945 | } | |
| 26946 | break :blk try sema.validateAlign(block, align_src, try val.toUnsignedIntSema(pt)); | |
| 26947 | } else if (extra.data.bits.has_align_ref) blk: { | |
| 26948 | const align_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]); | |
| 26949 | extra_index += 1; | |
| 26950 | const uncoerced_align = sema.resolveInst(align_ref) catch |err| switch (err) { | |
| 26951 | error.GenericPoison => break :blk null, | |
| 26952 | else => |e| return e, | |
| 26953 | }; | |
| 26954 | const coerced_align = sema.coerce(block, Type.u29, uncoerced_align, align_src) catch |err| switch (err) { | |
| 26955 | error.GenericPoison => break :blk null, | |
| 26956 | else => |e| return e, | |
| 26957 | }; | |
| 26958 | const align_val = sema.resolveConstDefinedValue(block, align_src, coerced_align, .{ | |
| 26959 | .needed_comptime_reason = "alignment must be comptime-known", | |
| 26960 | }) catch |err| switch (err) { | |
| 26961 | error.GenericPoison => break :blk null, | |
| 26962 | else => |e| return e, | |
| 26963 | }; | |
| 26964 | break :blk try sema.validateAlign(block, align_src, try align_val.toUnsignedIntSema(pt)); | |
| 26965 | } else .none; | |
| 26966 | ||
| 26967 | const @"addrspace": ?std.builtin.AddressSpace = if (extra.data.bits.has_addrspace_body) blk: { | |
| 26968 | const body_len = sema.code.extra[extra_index]; | |
| 26969 | extra_index += 1; | |
| 26970 | const body = sema.code.bodySlice(extra_index, body_len); | |
| 26971 | extra_index += body.len; | |
| 26972 | ||
| 26973 | const addrspace_ty = try sema.getBuiltinType("AddressSpace"); | |
| 26974 | const val = try sema.resolveGenericBody(block, addrspace_src, body, inst, addrspace_ty, .{ | |
| 26975 | .needed_comptime_reason = "addrspace must be comptime-known", | |
| 26976 | }); | |
| 26977 | if (val.isGenericPoison()) { | |
| 26978 | break :blk null; | |
| 26979 | } | |
| 26980 | break :blk zcu.toEnum(std.builtin.AddressSpace, val); | |
| 26981 | } else if (extra.data.bits.has_addrspace_ref) blk: { | |
| 26982 | const addrspace_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]); | |
| 26983 | extra_index += 1; | |
| 26984 | const addrspace_ty = try sema.getBuiltinType("AddressSpace"); | |
| 26985 | const uncoerced_addrspace = sema.resolveInst(addrspace_ref) catch |err| switch (err) { | |
| 26986 | error.GenericPoison => break :blk null, | |
| 26987 | else => |e| return e, | |
| 26988 | }; | |
| 26989 | const coerced_addrspace = sema.coerce(block, addrspace_ty, uncoerced_addrspace, addrspace_src) catch |err| switch (err) { | |
| 26990 | error.GenericPoison => break :blk null, | |
| 26991 | else => |e| return e, | |
| 26992 | }; | |
| 26993 | const addrspace_val = sema.resolveConstDefinedValue(block, addrspace_src, coerced_addrspace, .{ | |
| 26994 | .needed_comptime_reason = "addrspace must be comptime-known", | |
| 26995 | }) catch |err| switch (err) { | |
| 26996 | error.GenericPoison => break :blk null, | |
| 26997 | else => |e| return e, | |
| 26998 | }; | |
| 26999 | break :blk zcu.toEnum(std.builtin.AddressSpace, addrspace_val); | |
| 27000 | } else target_util.defaultAddressSpace(target, .function); | |
| 27001 | ||
| 27002 | const section: Section = if (extra.data.bits.has_section_body) blk: { | |
| 27003 | const body_len = sema.code.extra[extra_index]; | |
| 27004 | extra_index += 1; | |
| 27005 | const body = sema.code.bodySlice(extra_index, body_len); | |
| 27006 | extra_index += body.len; | |
| 27007 | ||
| 27008 | const ty = Type.slice_const_u8; | |
| 27009 | const val = try sema.resolveGenericBody(block, section_src, body, inst, ty, .{ | |
| 27010 | .needed_comptime_reason = "linksection must be comptime-known", | |
| 27011 | }); | |
| 27012 | if (val.isGenericPoison()) { | |
| 27013 | break :blk .generic; | |
| 27014 | } | |
| 27015 | break :blk .{ .explicit = try sema.sliceToIpString(block, section_src, val, .{ | |
| 27016 | .needed_comptime_reason = "linksection must be comptime-known", | |
| 27017 | }) }; | |
| 27018 | } else if (extra.data.bits.has_section_ref) blk: { | |
| 27019 | const section_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]); | |
| 27020 | extra_index += 1; | |
| 27021 | const section_name = sema.resolveConstStringIntern(block, section_src, section_ref, .{ | |
| 27022 | .needed_comptime_reason = "linksection must be comptime-known", | |
| 27023 | }) catch |err| switch (err) { | |
| 27024 | error.GenericPoison => { | |
| 27025 | break :blk .generic; | |
| 27026 | }, | |
| 27027 | else => |e| return e, | |
| 27028 | }; | |
| 27029 | break :blk .{ .explicit = section_name }; | |
| 27030 | } else .default; | |
| 27031 | ||
| 27032 | const cc: ?std.builtin.CallingConvention = if (extra.data.bits.has_cc_body) blk: { | |
| 26867 | const cc: std.builtin.CallingConvention = if (extra.data.bits.has_cc_body) blk: { | |
| 27033 | 26868 | const body_len = sema.code.extra[extra_index]; |
| 27034 | 26869 | extra_index += 1; |
| 27035 | 26870 | const body = sema.code.bodySlice(extra_index, body_len); |
| ... | ... | @@ -27039,28 +26874,16 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 27039 | 26874 | const val = try sema.resolveGenericBody(block, cc_src, body, inst, cc_ty, .{ |
| 27040 | 26875 | .needed_comptime_reason = "calling convention must be comptime-known", |
| 27041 | 26876 | }); |
| 27042 | if (val.isGenericPoison()) { | |
| 27043 | break :blk null; | |
| 27044 | } | |
| 27045 | 26877 | break :blk try sema.analyzeValueAsCallconv(block, cc_src, val); |
| 27046 | 26878 | } else if (extra.data.bits.has_cc_ref) blk: { |
| 27047 | 26879 | const cc_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]); |
| 27048 | 26880 | extra_index += 1; |
| 27049 | 26881 | const cc_ty = try sema.getBuiltinType("CallingConvention"); |
| 27050 | const uncoerced_cc = sema.resolveInst(cc_ref) catch |err| switch (err) { | |
| 27051 | error.GenericPoison => break :blk null, | |
| 27052 | else => |e| return e, | |
| 27053 | }; | |
| 27054 | const coerced_cc = sema.coerce(block, cc_ty, uncoerced_cc, cc_src) catch |err| switch (err) { | |
| 27055 | error.GenericPoison => break :blk null, | |
| 27056 | else => |e| return e, | |
| 27057 | }; | |
| 27058 | const cc_val = sema.resolveConstDefinedValue(block, cc_src, coerced_cc, .{ | |
| 26882 | const uncoerced_cc = try sema.resolveInst(cc_ref); | |
| 26883 | const coerced_cc = try sema.coerce(block, cc_ty, uncoerced_cc, cc_src); | |
| 26884 | const cc_val = try sema.resolveConstDefinedValue(block, cc_src, coerced_cc, .{ | |
| 27059 | 26885 | .needed_comptime_reason = "calling convention must be comptime-known", |
| 27060 | }) catch |err| switch (err) { | |
| 27061 | error.GenericPoison => break :blk null, | |
| 27062 | else => |e| return e, | |
| 27063 | }; | |
| 26886 | }); | |
| 27064 | 26887 | break :blk try sema.analyzeValueAsCallconv(block, cc_src, cc_val); |
| 27065 | 26888 | } else cc: { |
| 27066 | 26889 | if (has_body) { |
| ... | ... | @@ -27142,9 +26965,6 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 27142 | 26965 | block, |
| 27143 | 26966 | inst_data.src_node, |
| 27144 | 26967 | inst, |
| 27145 | @"align", | |
| 27146 | @"addrspace", | |
| 27147 | section, | |
| 27148 | 26968 | cc, |
| 27149 | 26969 | ret_ty, |
| 27150 | 26970 | is_var_args, |
src/Zcu/PerThread.zig+49-55| ... | ... | @@ -1314,67 +1314,61 @@ fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult { |
| 1314 | 1314 | }; |
| 1315 | 1315 | } |
| 1316 | 1316 | |
| 1317 | const nav_already_populated, const queue_linker_work = switch (ip.indexToKey(decl_val.toIntern())) { | |
| 1318 | .func => |f| .{ f.owner_nav == nav_index, true }, | |
| 1319 | .variable => |v| .{ false, v.owner_nav == nav_index }, | |
| 1320 | .@"extern" => .{ false, false }, | |
| 1321 | else => .{ false, true }, | |
| 1317 | const queue_linker_work = switch (ip.indexToKey(decl_val.toIntern())) { | |
| 1318 | .func => true, // mote that this lets function aliases reach codegen | |
| 1319 | .variable => |v| v.owner_nav == nav_index, | |
| 1320 | .@"extern" => false, | |
| 1321 | else => true, | |
| 1322 | 1322 | }; |
| 1323 | 1323 | |
| 1324 | if (nav_already_populated) { | |
| 1325 | // This is a function declaration. | |
| 1326 | // Logic in `Sema.funcCommon` has already populated the `Nav` for us. | |
| 1327 | assert(ip.getNav(nav_index).status.resolved.val == decl_val.toIntern()); | |
| 1328 | } else { | |
| 1329 | // Keep in sync with logic in `Sema.zirVarExtended`. | |
| 1330 | const alignment: InternPool.Alignment = a: { | |
| 1331 | const align_body = decl_bodies.align_body orelse break :a .none; | |
| 1332 | const align_ref = try sema.resolveInlineBody(&block, align_body, inst_info.inst); | |
| 1333 | break :a try sema.analyzeAsAlign(&block, align_src, align_ref); | |
| 1334 | }; | |
| 1324 | // Keep in sync with logic in `Sema.zirVarExtended`. | |
| 1325 | const alignment: InternPool.Alignment = a: { | |
| 1326 | const align_body = decl_bodies.align_body orelse break :a .none; | |
| 1327 | const align_ref = try sema.resolveInlineBody(&block, align_body, inst_info.inst); | |
| 1328 | break :a try sema.analyzeAsAlign(&block, align_src, align_ref); | |
| 1329 | }; | |
| 1335 | 1330 | |
| 1336 | const @"linksection": InternPool.OptionalNullTerminatedString = ls: { | |
| 1337 | const linksection_body = decl_bodies.linksection_body orelse break :ls .none; | |
| 1338 | const linksection_ref = try sema.resolveInlineBody(&block, linksection_body, inst_info.inst); | |
| 1339 | const bytes = try sema.toConstString(&block, section_src, linksection_ref, .{ | |
| 1340 | .needed_comptime_reason = "linksection must be comptime-known", | |
| 1341 | }); | |
| 1342 | if (std.mem.indexOfScalar(u8, bytes, 0) != null) { | |
| 1343 | return sema.fail(&block, section_src, "linksection cannot contain null bytes", .{}); | |
| 1344 | } else if (bytes.len == 0) { | |
| 1345 | return sema.fail(&block, section_src, "linksection cannot be empty", .{}); | |
| 1346 | } | |
| 1347 | break :ls try ip.getOrPutStringOpt(gpa, pt.tid, bytes, .no_embedded_nulls); | |
| 1348 | }; | |
| 1331 | const @"linksection": InternPool.OptionalNullTerminatedString = ls: { | |
| 1332 | const linksection_body = decl_bodies.linksection_body orelse break :ls .none; | |
| 1333 | const linksection_ref = try sema.resolveInlineBody(&block, linksection_body, inst_info.inst); | |
| 1334 | const bytes = try sema.toConstString(&block, section_src, linksection_ref, .{ | |
| 1335 | .needed_comptime_reason = "linksection must be comptime-known", | |
| 1336 | }); | |
| 1337 | if (std.mem.indexOfScalar(u8, bytes, 0) != null) { | |
| 1338 | return sema.fail(&block, section_src, "linksection cannot contain null bytes", .{}); | |
| 1339 | } else if (bytes.len == 0) { | |
| 1340 | return sema.fail(&block, section_src, "linksection cannot be empty", .{}); | |
| 1341 | } | |
| 1342 | break :ls try ip.getOrPutStringOpt(gpa, pt.tid, bytes, .no_embedded_nulls); | |
| 1343 | }; | |
| 1349 | 1344 | |
| 1350 | const @"addrspace": std.builtin.AddressSpace = as: { | |
| 1351 | const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(decl_val.toIntern())) { | |
| 1352 | .func => .function, | |
| 1353 | .variable => .variable, | |
| 1354 | .@"extern" => |e| if (ip.indexToKey(e.ty) == .func_type) | |
| 1355 | .function | |
| 1356 | else | |
| 1357 | .variable, | |
| 1358 | else => .constant, | |
| 1359 | }; | |
| 1360 | const target = zcu.getTarget(); | |
| 1361 | const addrspace_body = decl_bodies.addrspace_body orelse break :as switch (addrspace_ctx) { | |
| 1362 | .function => target_util.defaultAddressSpace(target, .function), | |
| 1363 | .variable => target_util.defaultAddressSpace(target, .global_mutable), | |
| 1364 | .constant => target_util.defaultAddressSpace(target, .global_constant), | |
| 1365 | else => unreachable, | |
| 1366 | }; | |
| 1367 | const addrspace_ref = try sema.resolveInlineBody(&block, addrspace_body, inst_info.inst); | |
| 1368 | break :as try sema.analyzeAsAddressSpace(&block, addrspace_src, addrspace_ref, addrspace_ctx); | |
| 1345 | const @"addrspace": std.builtin.AddressSpace = as: { | |
| 1346 | const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(decl_val.toIntern())) { | |
| 1347 | .func => .function, | |
| 1348 | .variable => .variable, | |
| 1349 | .@"extern" => |e| if (ip.indexToKey(e.ty) == .func_type) | |
| 1350 | .function | |
| 1351 | else | |
| 1352 | .variable, | |
| 1353 | else => .constant, | |
| 1369 | 1354 | }; |
| 1355 | const target = zcu.getTarget(); | |
| 1356 | const addrspace_body = decl_bodies.addrspace_body orelse break :as switch (addrspace_ctx) { | |
| 1357 | .function => target_util.defaultAddressSpace(target, .function), | |
| 1358 | .variable => target_util.defaultAddressSpace(target, .global_mutable), | |
| 1359 | .constant => target_util.defaultAddressSpace(target, .global_constant), | |
| 1360 | else => unreachable, | |
| 1361 | }; | |
| 1362 | const addrspace_ref = try sema.resolveInlineBody(&block, addrspace_body, inst_info.inst); | |
| 1363 | break :as try sema.analyzeAsAddressSpace(&block, addrspace_src, addrspace_ref, addrspace_ctx); | |
| 1364 | }; | |
| 1370 | 1365 | |
| 1371 | ip.resolveNavValue(nav_index, .{ | |
| 1372 | .val = decl_val.toIntern(), | |
| 1373 | .alignment = alignment, | |
| 1374 | .@"linksection" = @"linksection", | |
| 1375 | .@"addrspace" = @"addrspace", | |
| 1376 | }); | |
| 1377 | } | |
| 1366 | ip.resolveNavValue(nav_index, .{ | |
| 1367 | .val = decl_val.toIntern(), | |
| 1368 | .alignment = alignment, | |
| 1369 | .@"linksection" = @"linksection", | |
| 1370 | .@"addrspace" = @"addrspace", | |
| 1371 | }); | |
| 1378 | 1372 | |
| 1379 | 1373 | // Mark the `Cau` as completed before evaluating the export! |
| 1380 | 1374 | assert(zcu.analysis_in_progress.swapRemove(anal_unit)); |
src/print_zir.zig-54| ... | ... | @@ -2349,12 +2349,6 @@ const Writer = struct { |
| 2349 | 2349 | false, |
| 2350 | 2350 | false, |
| 2351 | 2351 | |
| 2352 | .none, | |
| 2353 | &.{}, | |
| 2354 | .none, | |
| 2355 | &.{}, | |
| 2356 | .none, | |
| 2357 | &.{}, | |
| 2358 | 2352 | .none, |
| 2359 | 2353 | &.{}, |
| 2360 | 2354 | ret_ty_ref, |
| ... | ... | @@ -2372,12 +2366,6 @@ const Writer = struct { |
| 2372 | 2366 | const extra = self.code.extraData(Zir.Inst.FuncFancy, inst_data.payload_index); |
| 2373 | 2367 | |
| 2374 | 2368 | var extra_index: usize = extra.end; |
| 2375 | var align_ref: Zir.Inst.Ref = .none; | |
| 2376 | var align_body: []const Zir.Inst.Index = &.{}; | |
| 2377 | var addrspace_ref: Zir.Inst.Ref = .none; | |
| 2378 | var addrspace_body: []const Zir.Inst.Index = &.{}; | |
| 2379 | var section_ref: Zir.Inst.Ref = .none; | |
| 2380 | var section_body: []const Zir.Inst.Index = &.{}; | |
| 2381 | 2369 | var cc_ref: Zir.Inst.Ref = .none; |
| 2382 | 2370 | var cc_body: []const Zir.Inst.Index = &.{}; |
| 2383 | 2371 | var ret_ty_ref: Zir.Inst.Ref = .none; |
| ... | ... | @@ -2390,33 +2378,6 @@ const Writer = struct { |
| 2390 | 2378 | } |
| 2391 | 2379 | try self.writeFlag(stream, "test, ", extra.data.bits.is_test); |
| 2392 | 2380 | |
| 2393 | if (extra.data.bits.has_align_body) { | |
| 2394 | const body_len = self.code.extra[extra_index]; | |
| 2395 | extra_index += 1; | |
| 2396 | align_body = self.code.bodySlice(extra_index, body_len); | |
| 2397 | extra_index += align_body.len; | |
| 2398 | } else if (extra.data.bits.has_align_ref) { | |
| 2399 | align_ref = @as(Zir.Inst.Ref, @enumFromInt(self.code.extra[extra_index])); | |
| 2400 | extra_index += 1; | |
| 2401 | } | |
| 2402 | if (extra.data.bits.has_addrspace_body) { | |
| 2403 | const body_len = self.code.extra[extra_index]; | |
| 2404 | extra_index += 1; | |
| 2405 | addrspace_body = self.code.bodySlice(extra_index, body_len); | |
| 2406 | extra_index += addrspace_body.len; | |
| 2407 | } else if (extra.data.bits.has_addrspace_ref) { | |
| 2408 | addrspace_ref = @as(Zir.Inst.Ref, @enumFromInt(self.code.extra[extra_index])); | |
| 2409 | extra_index += 1; | |
| 2410 | } | |
| 2411 | if (extra.data.bits.has_section_body) { | |
| 2412 | const body_len = self.code.extra[extra_index]; | |
| 2413 | extra_index += 1; | |
| 2414 | section_body = self.code.bodySlice(extra_index, body_len); | |
| 2415 | extra_index += section_body.len; | |
| 2416 | } else if (extra.data.bits.has_section_ref) { | |
| 2417 | section_ref = @as(Zir.Inst.Ref, @enumFromInt(self.code.extra[extra_index])); | |
| 2418 | extra_index += 1; | |
| 2419 | } | |
| 2420 | 2381 | if (extra.data.bits.has_cc_body) { |
| 2421 | 2382 | const body_len = self.code.extra[extra_index]; |
| 2422 | 2383 | extra_index += 1; |
| ... | ... | @@ -2455,12 +2416,6 @@ const Writer = struct { |
| 2455 | 2416 | extra.data.bits.is_var_args, |
| 2456 | 2417 | extra.data.bits.is_extern, |
| 2457 | 2418 | extra.data.bits.is_noinline, |
| 2458 | align_ref, | |
| 2459 | align_body, | |
| 2460 | addrspace_ref, | |
| 2461 | addrspace_body, | |
| 2462 | section_ref, | |
| 2463 | section_body, | |
| 2464 | 2419 | cc_ref, |
| 2465 | 2420 | cc_body, |
| 2466 | 2421 | ret_ty_ref, |
| ... | ... | @@ -2651,12 +2606,6 @@ const Writer = struct { |
| 2651 | 2606 | var_args: bool, |
| 2652 | 2607 | is_extern: bool, |
| 2653 | 2608 | is_noinline: bool, |
| 2654 | align_ref: Zir.Inst.Ref, | |
| 2655 | align_body: []const Zir.Inst.Index, | |
| 2656 | addrspace_ref: Zir.Inst.Ref, | |
| 2657 | addrspace_body: []const Zir.Inst.Index, | |
| 2658 | section_ref: Zir.Inst.Ref, | |
| 2659 | section_body: []const Zir.Inst.Index, | |
| 2660 | 2609 | cc_ref: Zir.Inst.Ref, |
| 2661 | 2610 | cc_body: []const Zir.Inst.Index, |
| 2662 | 2611 | ret_ty_ref: Zir.Inst.Ref, |
| ... | ... | @@ -2666,9 +2615,6 @@ const Writer = struct { |
| 2666 | 2615 | src_locs: Zir.Inst.Func.SrcLocs, |
| 2667 | 2616 | noalias_bits: u32, |
| 2668 | 2617 | ) !void { |
| 2669 | try self.writeOptionalInstRefOrBody(stream, "align=", align_ref, align_body); | |
| 2670 | try self.writeOptionalInstRefOrBody(stream, "addrspace=", addrspace_ref, addrspace_body); | |
| 2671 | try self.writeOptionalInstRefOrBody(stream, "section=", section_ref, section_body); | |
| 2672 | 2618 | try self.writeOptionalInstRefOrBody(stream, "cc=", cc_ref, cc_body); |
| 2673 | 2619 | try self.writeOptionalInstRefOrBody(stream, "ret_ty=", ret_ty_ref, ret_ty_body); |
| 2674 | 2620 | try self.writeFlag(stream, "vargs, ", var_args); |
test/behavior/align.zig-41| ... | ... | @@ -361,47 +361,6 @@ fn simple4() align(4) i32 { |
| 361 | 361 | return 0x19; |
| 362 | 362 | } |
| 363 | 363 | |
| 364 | test "function align expression depends on generic parameter" { | |
| 365 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | |
| 366 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | |
| 367 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | |
| 368 | ||
| 369 | // function alignment is a compile error on wasm32/wasm64 | |
| 370 | if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest; | |
| 371 | if (native_arch == .thumb) return error.SkipZigTest; | |
| 372 | ||
| 373 | const S = struct { | |
| 374 | fn doTheTest() !void { | |
| 375 | try expect(foobar(1) == 2); | |
| 376 | try expect(foobar(4) == 5); | |
| 377 | try expect(foobar(8) == 9); | |
| 378 | } | |
| 379 | ||
| 380 | fn foobar(comptime align_bytes: u8) align(align_bytes) u8 { | |
| 381 | return align_bytes + 1; | |
| 382 | } | |
| 383 | }; | |
| 384 | try S.doTheTest(); | |
| 385 | try comptime S.doTheTest(); | |
| 386 | } | |
| 387 | ||
| 388 | test "function callconv expression depends on generic parameter" { | |
| 389 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | |
| 390 | ||
| 391 | const S = struct { | |
| 392 | fn doTheTest() !void { | |
| 393 | try expect(foobar(.C, 1) == 2); | |
| 394 | try expect(foobar(.Unspecified, 2) == 3); | |
| 395 | } | |
| 396 | ||
| 397 | fn foobar(comptime cc: std.builtin.CallingConvention, arg: u8) callconv(cc) u8 { | |
| 398 | return arg + 1; | |
| 399 | } | |
| 400 | }; | |
| 401 | try S.doTheTest(); | |
| 402 | try comptime S.doTheTest(); | |
| 403 | } | |
| 404 | ||
| 405 | 364 | test "runtime-known array index has best alignment possible" { |
| 406 | 365 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 407 | 366 |
test/behavior/fn.zig-25| ... | ... | @@ -637,24 +637,6 @@ test "address of function parameter is consistent in other parameter type" { |
| 637 | 637 | S.paramAddrMatch(1, 2); |
| 638 | 638 | } |
| 639 | 639 | |
| 640 | test "address of function parameter is consistent in function align" { | |
| 641 | switch (builtin.target.cpu.arch) { | |
| 642 | .wasm32, .wasm64 => return, // function alignment not supported | |
| 643 | else => {}, | |
| 644 | } | |
| 645 | const S = struct { | |
| 646 | fn paramAddrMatch(comptime x: u8) align(if (&x != &x) unreachable else 1) void {} | |
| 647 | }; | |
| 648 | S.paramAddrMatch(1); | |
| 649 | } | |
| 650 | ||
| 651 | test "address of function parameter is consistent in function callconv" { | |
| 652 | const S = struct { | |
| 653 | fn paramAddrMatch(comptime x: u8) callconv(if (&x != &x) unreachable else .auto) void {} | |
| 654 | }; | |
| 655 | S.paramAddrMatch(1); | |
| 656 | } | |
| 657 | ||
| 658 | 640 | test "address of function parameter is consistent in function return type" { |
| 659 | 641 | const S = struct { |
| 660 | 642 | fn paramAddrMatch(comptime x: u8) if (&x != &x) unreachable else void {} |
| ... | ... | @@ -662,13 +644,6 @@ test "address of function parameter is consistent in function return type" { |
| 662 | 644 | S.paramAddrMatch(1); |
| 663 | 645 | } |
| 664 | 646 | |
| 665 | test "address of function parameter is consistent in function addrspace" { | |
| 666 | const S = struct { | |
| 667 | fn paramAddrMatch(comptime x: u8) addrspace(if (&x != &x) unreachable else .generic) void {} | |
| 668 | }; | |
| 669 | S.paramAddrMatch(1); | |
| 670 | } | |
| 671 | ||
| 672 | 647 | test "function parameter self equality" { |
| 673 | 648 | const S = struct { |
| 674 | 649 | fn equal(x: u32) bool { |
test/cases/compile_errors/invalid_variadic_function.zig-5| ... | ... | @@ -1,13 +1,9 @@ |
| 1 | 1 | fn foo(...) void {} |
| 2 | fn bar(a: anytype, ...) callconv(a) void {} | |
| 3 | 2 | inline fn foo2(...) void {} |
| 4 | 3 | |
| 5 | 4 | comptime { |
| 6 | 5 | _ = foo; |
| 7 | 6 | } |
| 8 | comptime { | |
| 9 | _ = bar; | |
| 10 | } | |
| 11 | 7 | comptime { |
| 12 | 8 | _ = foo2; |
| 13 | 9 | } |
| ... | ... | @@ -19,4 +15,3 @@ comptime { |
| 19 | 15 | // :1:1: note: supported calling conventions: 'x86_64_sysv', 'x86_64_win' |
| 20 | 16 | // :1:1: error: variadic function does not support 'inline' calling convention |
| 21 | 17 | // :1:1: note: supported calling conventions: 'x86_64_sysv', 'x86_64_win' |
| 22 | // :2:1: error: generic function cannot be variadic |
test/link/macho.zig+7-3| ... | ... | @@ -937,9 +937,13 @@ fn testLinksection(b: *Build, opts: Options) *Step { |
| 937 | 937 | const obj = addObject(b, opts, .{ .name = "main", .zig_source_bytes = |
| 938 | 938 | \\export var test_global: u32 linksection("__DATA,__TestGlobal") = undefined; |
| 939 | 939 | \\export fn testFn() linksection("__TEXT,__TestFn") callconv(.C) void { |
| 940 | \\ testGenericFn("A"); | |
| 940 | \\ TestGenericFn("A").f(); | |
| 941 | \\} | |
| 942 | \\fn TestGenericFn(comptime suffix: []const u8) type { | |
| 943 | \\ return struct { | |
| 944 | \\ fn f() linksection("__TEXT,__TestGenFn" ++ suffix) void {} | |
| 945 | \\ }; | |
| 941 | 946 | \\} |
| 942 | \\fn testGenericFn(comptime suffix: []const u8) linksection("__TEXT,__TestGenFn" ++ suffix) void {} | |
| 943 | 947 | }); |
| 944 | 948 | |
| 945 | 949 | const check = obj.checkObject(); |
| ... | ... | @@ -950,7 +954,7 @@ fn testLinksection(b: *Build, opts: Options) *Step { |
| 950 | 954 | |
| 951 | 955 | if (opts.optimize == .Debug) { |
| 952 | 956 | check.checkInSymtab(); |
| 953 | check.checkContains("(__TEXT,__TestGenFnA) _main.testGenericFn__anon_"); | |
| 957 | check.checkContains("(__TEXT,__TestGenFnA) _main.TestGenericFn("); | |
| 954 | 958 | } |
| 955 | 959 | |
| 956 | 960 | test_step.dependOn(&check.step); |