authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-12-19 07:57:16+00:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-12-19 07:57:16+00:00
loge2e3633612be656177512873a9de6524082d04dd
treec71b592a592e21b108fccc0be3f99a45b6a13c6e
parentf857bf72e2239718bbbe4cba08d6961ad77fc69a
parent58b8b1ac2af642e886f3a561bf6dfd971bb80a96
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #22264 from mlugg/no-generic-callconv

compiler: disallow `callconv` etc from depending on function parameters Also, disallow `align`/`linksection`/`addrspace` annotations on container-level declarations with comptime-only types.

14 files changed, 433 insertions(+), 871 deletions(-)

lib/std/zig/AstGen.zig+161-260
...@@ -1420,19 +1420,9 @@ fn fnProtoExpr(...@@ -1420,19 +1420,9 @@ fn fnProtoExpr(
14201420
1421 .cc_ref = cc,1421 .cc_ref = cc,
1422 .cc_gz = null,1422 .cc_gz = null,
1423 .align_ref = .none,
1424 .align_gz = null,
1425 .ret_ref = ret_ty,1423 .ret_ref = ret_ty,
1426 .ret_gz = null,1424 .ret_gz = null,
1427 .section_ref = .none,1425
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 = &.{},
1436 .ret_param_refs = &.{},1426 .ret_param_refs = &.{},
1437 .param_insts = &.{},1427 .param_insts = &.{},
14381428
...@@ -4129,6 +4119,8 @@ fn fnDecl(...@@ -4129,6 +4119,8 @@ fn fnDecl(
4129 const decl_inst = try gz.makeDeclaration(fn_proto.ast.proto_node);4119 const decl_inst = try gz.makeDeclaration(fn_proto.ast.proto_node);
4130 astgen.advanceSourceCursorToNode(decl_node);4120 astgen.advanceSourceCursorToNode(decl_node);
41314121
4122 const saved_cursor = astgen.saveSourceCursor();
4123
4132 var decl_gz: GenZir = .{4124 var decl_gz: GenZir = .{
4133 .is_comptime = true,4125 .is_comptime = true,
4134 .decl_node_index = fn_proto.ast.proto_node,4126 .decl_node_index = fn_proto.ast.proto_node,
...@@ -4140,17 +4132,6 @@ fn fnDecl(...@@ -4140,17 +4132,6 @@ fn fnDecl(
4140 };4132 };
4141 defer decl_gz.unstack();4133 defer decl_gz.unstack();
41424134
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 const decl_column = astgen.source_column;4135 const decl_column = astgen.source_column;
41554136
4156 // Set this now, since parameter types, return type, etc may be generic.4137 // Set this now, since parameter types, return type, etc may be generic.
...@@ -4182,7 +4163,7 @@ fn fnDecl(...@@ -4182,7 +4163,7 @@ fn fnDecl(
4182 var param_insts: std.ArrayListUnmanaged(Zir.Inst.Index) = try .initCapacity(astgen.arena, fn_proto.ast.params.len);4163 var param_insts: std.ArrayListUnmanaged(Zir.Inst.Index) = try .initCapacity(astgen.arena, fn_proto.ast.params.len);
41834164
4184 var noalias_bits: u32 = 0;4165 var noalias_bits: u32 = 0;
4185 var params_scope = &fn_gz.base;4166 var params_scope = scope;
4186 const is_var_args = is_var_args: {4167 const is_var_args = is_var_args: {
4187 var param_type_i: usize = 0;4168 var param_type_i: usize = 0;
4188 var it = fn_proto.iterate(tree);4169 var it = fn_proto.iterate(tree);
...@@ -4305,47 +4286,26 @@ fn fnDecl(...@@ -4305,47 +4286,26 @@ fn fnDecl(
4305 // instructions inside the expression blocks for align, addrspace, cc, and ret_ty4286 // instructions inside the expression blocks for align, addrspace, cc, and ret_ty
4306 // to use the function instruction as the "block" to break from.4287 // to use the function instruction as the "block" to break from.
43074288
4308 var align_gz = decl_gz.makeSubBlock(params_scope);4289 var ret_gz = decl_gz.makeSubBlock(params_scope);
4309 defer align_gz.unstack();4290 defer ret_gz.unstack();
4310 const align_ref: Zir.Inst.Ref = if (fn_proto.ast.align_expr == 0) .none else inst: {4291 const ret_ref: Zir.Inst.Ref = inst: {
4311 const inst = try expr(&decl_gz, params_scope, coerced_align_ri, fn_proto.ast.align_expr);4292 // Parameters are in scope for the return type, so we use `params_scope` here.
4312 if (align_gz.instructionsSlice().len == 0) {4293 // The calling convention will not have parameters in scope, so we'll just use `scope`.
4313 // In this case we will send a len=0 body which can be encoded more efficiently.4294 // See #22263 for a proposal to solve the inconsistency here.
4314 break :inst inst;4295 const inst = try fullBodyExpr(&ret_gz, params_scope, coerced_type_ri, fn_proto.ast.return_type, .normal);
4315 }4296 if (ret_gz.instructionsSlice().len == 0) {
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) {
4327 // In this case we will send a len=0 body which can be encoded more efficiently.4297 // In this case we will send a len=0 body which can be encoded more efficiently.
4328 break :inst inst;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 break :inst inst;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);
43344304
4335 var section_gz = decl_gz.makeSubBlock(params_scope);4305 // We're jumping back in source, so restore the cursor.
4336 defer section_gz.unstack();4306 astgen.restoreSourceCursor(saved_cursor);
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);
43474307
4348 var cc_gz = decl_gz.makeSubBlock(params_scope);4308 var cc_gz = decl_gz.makeSubBlock(scope);
4349 defer cc_gz.unstack();4309 defer cc_gz.unstack();
4350 const cc_ref: Zir.Inst.Ref = blk: {4310 const cc_ref: Zir.Inst.Ref = blk: {
4351 if (fn_proto.ast.callconv_expr != 0) {4311 if (fn_proto.ast.callconv_expr != 0) {
...@@ -4358,7 +4318,7 @@ fn fnDecl(...@@ -4358,7 +4318,7 @@ fn fnDecl(
4358 }4318 }
4359 const inst = try expr(4319 const inst = try expr(
4360 &cc_gz,4320 &cc_gz,
4361 params_scope,4321 scope,
4362 .{ .rl = .{ .coerced_ty = try cc_gz.addBuiltinValue(fn_proto.ast.callconv_expr, .calling_convention) } },4322 .{ .rl = .{ .coerced_ty = try cc_gz.addBuiltinValue(fn_proto.ast.callconv_expr, .calling_convention) } },
4363 fn_proto.ast.callconv_expr,4323 fn_proto.ast.callconv_expr,
4364 );4324 );
...@@ -4380,20 +4340,6 @@ fn fnDecl(...@@ -4380,20 +4340,6 @@ fn fnDecl(
4380 break :blk .none;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);
43974343
4398 const func_inst: Zir.Inst.Ref = if (body_node == 0) func: {4344 const func_inst: Zir.Inst.Ref = if (body_node == 0) func: {
4399 if (!is_extern) {4345 if (!is_extern) {
...@@ -4406,19 +4352,9 @@ fn fnDecl(...@@ -4406,19 +4352,9 @@ fn fnDecl(
4406 .src_node = decl_node,4352 .src_node = decl_node,
4407 .cc_ref = cc_ref,4353 .cc_ref = cc_ref,
4408 .cc_gz = &cc_gz,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 .ret_ref = ret_ref,4355 .ret_ref = ret_ref,
4414 .ret_gz = &ret_gz,4356 .ret_gz = &ret_gz,
4415 .ret_param_refs = ret_body_param_refs,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 .param_block = decl_inst,4358 .param_block = decl_inst,
4423 .param_insts = param_insts.items,4359 .param_insts = param_insts.items,
4424 .body_gz = null,4360 .body_gz = null,
...@@ -4432,8 +4368,23 @@ fn fnDecl(...@@ -4432,8 +4368,23 @@ fn fnDecl(
4432 .proto_hash = undefined, // ignored for `body_gz == null`4368 .proto_hash = undefined, // ignored for `body_gz == null`
4433 });4369 });
4434 } else func: {4370 } else func: {
4435 // as a scope, fn_gz encloses ret_gz, but for instruction list, fn_gz stacks on ret_gz4371 var body_gz: GenZir = .{
4436 fn_gz.instructions_top = ret_gz.instructions.items.len;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)
44374388
4438 // Construct the prototype hash.4389 // Construct the prototype hash.
4439 // Leave `astgen.src_hasher` unmodified; this will be used for hashing4390 // Leave `astgen.src_hasher` unmodified; this will be used for hashing
...@@ -4450,13 +4401,13 @@ fn fnDecl(...@@ -4450,13 +4401,13 @@ fn fnDecl(
4450 astgen.fn_block = prev_fn_block;4401 astgen.fn_block = prev_fn_block;
4451 astgen.fn_ret_ty = prev_fn_ret_ty;4402 astgen.fn_ret_ty = prev_fn_ret_ty;
4452 }4403 }
4453 astgen.fn_block = &fn_gz;4404 astgen.fn_block = &body_gz;
4454 astgen.fn_ret_ty = if (is_inferred_error or ret_ref.toIndex() != null) r: {4405 astgen.fn_ret_ty = if (is_inferred_error or ret_ref.toIndex() != null) r: {
4455 // We're essentially guaranteed to need the return type at some point,4406 // We're essentially guaranteed to need the return type at some point,
4456 // since the return type is likely not `void` or `noreturn` so there4407 // since the return type is likely not `void` or `noreturn` so there
4457 // will probably be an explicit return requiring RLS. Fetch this4408 // will probably be an explicit return requiring RLS. Fetch this
4458 // return type now so the rest of the function can use it.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 } else ret_ref;4411 } else ret_ref;
44614412
4462 const prev_var_args = astgen.fn_var_args;4413 const prev_var_args = astgen.fn_var_args;
...@@ -4467,39 +4418,29 @@ fn fnDecl(...@@ -4467,39 +4418,29 @@ fn fnDecl(
4467 const lbrace_line = astgen.source_line - decl_gz.decl_line;4418 const lbrace_line = astgen.source_line - decl_gz.decl_line;
4468 const lbrace_column = astgen.source_column;4419 const lbrace_column = astgen.source_column;
44694420
4470 _ = try fullBodyExpr(&fn_gz, params_scope, .{ .rl = .none }, body_node, .allow_branch_hint);4421 _ = try fullBodyExpr(&body_gz, &body_gz.base, .{ .rl = .none }, body_node, .allow_branch_hint);
4471 try checkUsed(gz, &fn_gz.base, params_scope);4422 try checkUsed(gz, scope, params_scope);
44724423
4473 if (!fn_gz.endsWithNoReturn()) {4424 if (!body_gz.endsWithNoReturn()) {
4474 // As our last action before the return, "pop" the error trace if needed4425 // 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);
44764427
4477 // Add implicit return at end of function.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 }
44804431
4481 break :func try decl_gz.addFunc(.{4432 break :func try decl_gz.addFunc(.{
4482 .src_node = decl_node,4433 .src_node = decl_node,
4483 .cc_ref = cc_ref,4434 .cc_ref = cc_ref,
4484 .cc_gz = &cc_gz,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 .ret_ref = ret_ref,4436 .ret_ref = ret_ref,
4490 .ret_gz = &ret_gz,4437 .ret_gz = &ret_gz,
4491 .ret_param_refs = ret_body_param_refs,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 .lbrace_line = lbrace_line,4439 .lbrace_line = lbrace_line,
4499 .lbrace_column = lbrace_column,4440 .lbrace_column = lbrace_column,
4500 .param_block = decl_inst,4441 .param_block = decl_inst,
4501 .param_insts = param_insts.items,4442 .param_insts = param_insts.items,
4502 .body_gz = &fn_gz,4443 .body_gz = &body_gz,
4503 .lib_name = lib_name,4444 .lib_name = lib_name,
4504 .is_var_args = is_var_args,4445 .is_var_args = is_var_args,
4505 .is_inferred_error = is_inferred_error,4446 .is_inferred_error = is_inferred_error,
...@@ -4511,13 +4452,39 @@ fn fnDecl(...@@ -4511,13 +4452,39 @@ fn fnDecl(
4511 });4452 });
4512 };4453 };
45134454
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 // *Now* we can incorporate the full source code into the hasher.4485 // *Now* we can incorporate the full source code into the hasher.
4515 astgen.src_hasher.update(tree.getNodeSource(decl_node));4486 astgen.src_hasher.update(tree.getNodeSource(decl_node));
45164487
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 var hash: std.zig.SrcHash = undefined;4488 var hash: std.zig.SrcHash = undefined;
4522 astgen.src_hasher.final(&hash);4489 astgen.src_hasher.final(&hash);
4523 try setDeclaration(4490 try setDeclaration(
...@@ -4529,9 +4496,11 @@ fn fnDecl(...@@ -4529,9 +4496,11 @@ fn fnDecl(
4529 is_pub,4496 is_pub,
4530 is_export,4497 is_export,
4531 &decl_gz,4498 &decl_gz,
4532 // align, linksection, and addrspace are passed in the func instruction in this case.4499 .{
4533 // TODO: move them from the function instruction to the declaration instruction?4500 .align_gz = &align_gz,
4534 null,4501 .linksection_gz = &section_gz,
4502 .addrspace_gz = &addrspace_gz,
4503 },
4535 );4504 );
4536}4505}
45374506
...@@ -4986,19 +4955,9 @@ fn testDecl(...@@ -4986,19 +4955,9 @@ fn testDecl(
49864955
4987 .cc_ref = .none,4956 .cc_ref = .none,
4988 .cc_gz = null,4957 .cc_gz = null,
4989 .align_ref = .none,
4990 .align_gz = null,
4991 .ret_ref = .anyerror_void_error_union_type,4958 .ret_ref = .anyerror_void_error_union_type,
4992 .ret_gz = null,4959 .ret_gz = null,
4993 .section_ref = .none,4960
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 = &.{},
5002 .ret_param_refs = &.{},4961 .ret_param_refs = &.{},
5003 .param_insts = &.{},4962 .param_insts = &.{},
50044963
...@@ -11952,6 +11911,14 @@ const GenZir = struct {...@@ -11952,6 +11911,14 @@ const GenZir = struct {
11952 self.instructions.items[self.instructions_top..];11911 self.instructions.items[self.instructions_top..];
11953 }11912 }
1195411913
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 fn makeSubBlock(gz: *GenZir, scope: *Scope) GenZir {11922 fn makeSubBlock(gz: *GenZir, scope: *Scope) GenZir {
11956 return .{11923 return .{
11957 .is_comptime = gz.is_comptime,11924 .is_comptime = gz.is_comptime,
...@@ -12088,11 +12055,8 @@ const GenZir = struct {...@@ -12088,11 +12055,8 @@ const GenZir = struct {
1208812055
12089 /// Must be called with the following stack set up:12056 /// Must be called with the following stack set up:
12090 /// * gz (bottom)12057 /// * gz (bottom)
12091 /// * align_gz
12092 /// * addrspace_gz
12093 /// * section_gz
12094 /// * cc_gz
12095 /// * ret_gz12058 /// * ret_gz
12059 /// * cc_gz
12096 /// * body_gz (top)12060 /// * body_gz (top)
12097 /// Unstacks all of those except for `gz`.12061 /// Unstacks all of those except for `gz`.
12098 fn addFunc(12062 fn addFunc(
...@@ -12103,23 +12067,13 @@ const GenZir = struct {...@@ -12103,23 +12067,13 @@ const GenZir = struct {
12103 lbrace_column: u32 = 0,12067 lbrace_column: u32 = 0,
12104 param_block: Zir.Inst.Index,12068 param_block: Zir.Inst.Index,
1210512069
12106 align_gz: ?*GenZir,
12107 addrspace_gz: ?*GenZir,
12108 section_gz: ?*GenZir,
12109 cc_gz: ?*GenZir,
12110 ret_gz: ?*GenZir,12070 ret_gz: ?*GenZir,
12111 body_gz: ?*GenZir,12071 body_gz: ?*GenZir,
12072 cc_gz: ?*GenZir,
1211212073
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 ret_param_refs: []Zir.Inst.Index,12074 ret_param_refs: []Zir.Inst.Index,
12118 param_insts: []Zir.Inst.Index, // refs to params in `body_gz` should still be in `astgen.ref_table`12075 param_insts: []Zir.Inst.Index, // refs to params in `body_gz` should still be in `astgen.ref_table`
1211912076
12120 align_ref: Zir.Inst.Ref,
12121 addrspace_ref: Zir.Inst.Ref,
12122 section_ref: Zir.Inst.Ref,
12123 cc_ref: Zir.Inst.Ref,12077 cc_ref: Zir.Inst.Ref,
12124 ret_ref: Zir.Inst.Ref,12078 ret_ref: Zir.Inst.Ref,
1212512079
...@@ -12141,13 +12095,31 @@ const GenZir = struct {...@@ -12141,13 +12095,31 @@ const GenZir = struct {
12141 const ret_ref = if (args.ret_ref == .void_type) .none else args.ret_ref;12095 const ret_ref = if (args.ret_ref == .void_type) .none else args.ret_ref;
12142 const new_index: Zir.Inst.Index = @enumFromInt(astgen.instructions.len);12096 const new_index: Zir.Inst.Index = @enumFromInt(astgen.instructions.len);
1214312097
12098 try gz.instructions.ensureUnusedCapacity(gpa, 1);
12144 try astgen.instructions.ensureUnusedCapacity(gpa, 1);12099 try astgen.instructions.ensureUnusedCapacity(gpa, 1);
1214512100
12146 var body: []Zir.Inst.Index = &[0]Zir.Inst.Index{};12101 const body, const cc_body, const ret_body = bodies: {
12147 var ret_body: []Zir.Inst.Index = &[0]Zir.Inst.Index{};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 var src_locs_and_hash_buffer: [7]u32 = undefined;12121 var src_locs_and_hash_buffer: [7]u32 = undefined;
12149 var src_locs_and_hash: []u32 = src_locs_and_hash_buffer[0..0];12122 const src_locs_and_hash: []const u32 = if (args.body_gz != null) src_locs_and_hash: {
12150 if (args.body_gz) |body_gz| {
12151 const tree = astgen.tree;12123 const tree = astgen.tree;
12152 const node_tags = tree.nodes.items(.tag);12124 const node_tags = tree.nodes.items(.tag);
12153 const node_datas = tree.nodes.items(.data);12125 const node_datas = tree.nodes.items(.data);
...@@ -12173,39 +12145,19 @@ const GenZir = struct {...@@ -12173,39 +12145,19 @@ const GenZir = struct {
12173 proto_hash_arr[2],12145 proto_hash_arr[2],
12174 proto_hash_arr[3],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 &.{};
1217712150
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 const body_len = astgen.countBodyLenAfterFixupsExtraRefs(body, args.param_insts);12151 const body_len = astgen.countBodyLenAfterFixupsExtraRefs(body, args.param_insts);
1218612152
12187 if (args.cc_ref != .none or args.lib_name != .empty or args.is_var_args or args.is_test or12153 const tag: Zir.Inst.Tag, const payload_index: u32 = if (args.cc_ref != .none or args.lib_name != .empty or
12188 args.is_extern or args.align_ref != .none or args.section_ref != .none or12154 args.is_var_args or args.is_test or args.is_extern or
12189 args.addrspace_ref != .none or args.noalias_bits != 0 or args.is_noinline)12155 args.noalias_bits != 0 or args.is_noinline)
12190 {12156 inst_info: {
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
12202 try astgen.extra.ensureUnusedCapacity(12157 try astgen.extra.ensureUnusedCapacity(
12203 gpa,12158 gpa,
12204 @typeInfo(Zir.Inst.FuncFancy).@"struct".fields.len +12159 @typeInfo(Zir.Inst.FuncFancy).@"struct".fields.len +
12205 fancyFnExprExtraLen(astgen, args.align_param_refs, align_body, args.align_ref) +12160 fancyFnExprExtraLen(astgen, &.{}, cc_body, args.cc_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) +
12209 fancyFnExprExtraLen(astgen, args.ret_param_refs, ret_body, ret_ref) +12161 fancyFnExprExtraLen(astgen, args.ret_param_refs, ret_body, ret_ref) +
12210 body_len + src_locs_and_hash.len +12162 body_len + src_locs_and_hash.len +
12211 @intFromBool(args.lib_name != .empty) +12163 @intFromBool(args.lib_name != .empty) +
...@@ -12223,15 +12175,9 @@ const GenZir = struct {...@@ -12223,15 +12175,9 @@ const GenZir = struct {
12223 .has_lib_name = args.lib_name != .empty,12175 .has_lib_name = args.lib_name != .empty,
12224 .has_any_noalias = args.noalias_bits != 0,12176 .has_any_noalias = args.noalias_bits != 0,
1222512177
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 .has_cc_ref = args.cc_ref != .none,12178 .has_cc_ref = args.cc_ref != .none,
12230 .has_ret_ty_ref = ret_ref != .none,12179 .has_ret_ty_ref = ret_ref != .none,
1223112180
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 .has_cc_body = cc_body.len != 0,12181 .has_cc_body = cc_body.len != 0,
12236 .has_ret_ty_body = ret_body.len != 0,12182 .has_ret_ty_body = ret_body.len != 0,
12237 },12183 },
...@@ -12241,53 +12187,8 @@ const GenZir = struct {...@@ -12241,53 +12187,8 @@ const GenZir = struct {
12241 }12187 }
1224212188
12243 const zir_datas = astgen.instructions.items(.data);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 if (cc_body.len != 0) {12190 if (cc_body.len != 0) {
12286 astgen.extra.appendAssumeCapacity(12191 astgen.extra.appendAssumeCapacity(astgen.countBodyLenAfterFixups(cc_body));
12287 astgen.countBodyLenAfterFixups(args.cc_param_refs) +
12288 astgen.countBodyLenAfterFixups(cc_body),
12289 );
12290 astgen.appendBodyWithFixups(args.cc_param_refs);
12291 astgen.appendBodyWithFixups(cc_body);12192 astgen.appendBodyWithFixups(cc_body);
12292 const break_extra = zir_datas[@intFromEnum(cc_body[cc_body.len - 1])].@"break".payload_index;12193 const break_extra = zir_datas[@intFromEnum(cc_body[cc_body.len - 1])].@"break".payload_index;
12293 astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] =12194 astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] =
...@@ -12316,28 +12217,8 @@ const GenZir = struct {...@@ -12316,28 +12217,8 @@ const GenZir = struct {
12316 astgen.appendBodyWithFixupsExtraRefsArrayList(&astgen.extra, body, args.param_insts);12217 astgen.appendBodyWithFixupsExtraRefsArrayList(&astgen.extra, body, args.param_insts);
12317 astgen.extra.appendSliceAssumeCapacity(src_locs_and_hash);12218 astgen.extra.appendSliceAssumeCapacity(src_locs_and_hash);
1231812219
12319 // Order is important when unstacking.12220 break :inst_info .{ .func_fancy, payload_index };
12320 if (args.body_gz) |body_gz| body_gz.unstack();12221 } else inst_info: {
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 {
12341 try astgen.extra.ensureUnusedCapacity(12222 try astgen.extra.ensureUnusedCapacity(
12342 gpa,12223 gpa,
12343 @typeInfo(Zir.Inst.Func).@"struct".fields.len + 1 +12224 @typeInfo(Zir.Inst.Func).@"struct".fields.len + 1 +
...@@ -12369,30 +12250,29 @@ const GenZir = struct {...@@ -12369,30 +12250,29 @@ const GenZir = struct {
12369 astgen.appendBodyWithFixupsExtraRefsArrayList(&astgen.extra, body, args.param_insts);12250 astgen.appendBodyWithFixupsExtraRefsArrayList(&astgen.extra, body, args.param_insts);
12370 astgen.extra.appendSliceAssumeCapacity(src_locs_and_hash);12251 astgen.extra.appendSliceAssumeCapacity(src_locs_and_hash);
1237112252
12372 // Order is important when unstacking.12253 break :inst_info .{
12373 if (args.body_gz) |body_gz| body_gz.unstack();12254 if (args.is_inferred_error) .func_inferred else .func,
12374 if (args.ret_gz) |ret_gz| ret_gz.unstack();12255 payload_index,
12375 if (args.cc_gz) |cc_gz| cc_gz.unstack();12256 };
12376 if (args.section_gz) |section_gz| section_gz.unstack();12257 };
12377 if (args.addrspace_gz) |addrspace_gz| addrspace_gz.unstack();
12378 if (args.align_gz) |align_gz| align_gz.unstack();
1237912258
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();
1238112263
12382 const tag: Zir.Inst.Tag = if (args.is_inferred_error) .func_inferred else .func;12264 astgen.instructions.appendAssumeCapacity(.{
12383 astgen.instructions.appendAssumeCapacity(.{12265 .tag = tag,
12384 .tag = tag,12266 .data = .{ .pl_node = .{
12385 .data = .{ .pl_node = .{12267 .src_node = gz.nodeIndexToRelative(args.src_node),
12386 .src_node = gz.nodeIndexToRelative(args.src_node),12268 .payload_index = payload_index,
12387 .payload_index = payload_index,12269 } },
12388 } },12270 });
12389 });12271 gz.instructions.appendAssumeCapacity(new_index);
12390 gz.instructions.appendAssumeCapacity(new_index);12272 return new_index.toRef();
12391 return new_index.toRef();
12392 }
12393 }12273 }
1239412274
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 return countBodyLenAfterFixups(astgen, param_refs_body) +12276 return countBodyLenAfterFixups(astgen, param_refs_body) +
12397 countBodyLenAfterFixups(astgen, main_body) +12277 countBodyLenAfterFixups(astgen, main_body) +
12398 // If there is a body, we need an element for its length; otherwise, if there is a ref, we need to include that.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,6 +13456,27 @@ fn advanceSourceCursor(astgen: *AstGen, end: usize) void {
13576 astgen.source_column = column;13456 astgen.source_column = column;
13577}13457}
1357813458
13459const 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.
13467fn saveSourceCursor(astgen: *const AstGen) SourceCursor {
13468 return .{
13469 .offset = astgen.source_offset,
13470 .line = astgen.source_line,
13471 .column = astgen.source_column,
13472 };
13473}
13474fn 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/// Detects name conflicts for decls and fields, and populates `namespace.decls` with all named declarations.13480/// Detects name conflicts for decls and fields, and populates `namespace.decls` with all named declarations.
13580/// Returns the number of declarations in the namespace, including unnamed declarations (e.g. `comptime` decls).13481/// Returns the number of declarations in the namespace, including unnamed declarations (e.g. `comptime` decls).
13581fn scanContainer(13482fn scanContainer(
lib/std/zig/Zir.zig+12-99
...@@ -2494,46 +2494,25 @@ pub const Inst = struct {...@@ -2494,46 +2494,25 @@ pub const Inst = struct {
24942494
2495 /// Trailing:2495 /// Trailing:
2496 /// 0. lib_name: NullTerminatedString, // null terminated string index, if has_lib_name is set2496 /// 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 /// if (has_cc_ref and !has_cc_body) {2497 /// if (has_cc_ref and !has_cc_body) {
2519 /// 10. cc: Ref,2498 /// 1. cc: Ref,
2520 /// }2499 /// }
2521 /// if (has_cc_body) {2500 /// if (has_cc_body) {
2522 /// 11. cc_body_len: u322501 /// 2. cc_body_len: u32
2523 /// 12. cc_body: u32 // for each cc_body_len2502 /// 3. cc_body: u32 // for each cc_body_len
2524 /// }2503 /// }
2525 /// if (has_ret_ty_ref and !has_ret_ty_body) {2504 /// if (has_ret_ty_ref and !has_ret_ty_body) {
2526 /// 13. ret_ty: Ref,2505 /// 4. ret_ty: Ref,
2527 /// }2506 /// }
2528 /// if (has_ret_ty_body) {2507 /// if (has_ret_ty_body) {
2529 /// 14. ret_ty_body_len: u322508 /// 5. ret_ty_body_len: u32
2530 /// 15. ret_ty_body: u32 // for each ret_ty_body_len2509 /// 6. ret_ty_body: u32 // for each ret_ty_body_len
2531 /// }2510 /// }
2532 /// 16. noalias_bits: u32 // if has_any_noalias2511 /// 7. noalias_bits: u32 // if has_any_noalias
2533 /// - each bit starting with LSB corresponds to parameter indexes2512 /// - each bit starting with LSB corresponds to parameter indexes
2534 /// 17. body: Index // for each body_len2513 /// 8. body: Index // for each body_len
2535 /// 18. src_locs: Func.SrcLocs // if body_len != 02514 /// 9. src_locs: Func.SrcLocs // if body_len != 0
2536 /// 19. proto_hash: std.zig.SrcHash // if body_len != 0; hash of function prototype2515 /// 10. proto_hash: std.zig.SrcHash // if body_len != 0; hash of function prototype
2537 pub const FuncFancy = struct {2516 pub const FuncFancy = struct {
2538 /// Points to the block that contains the param instructions for this function.2517 /// Points to the block that contains the param instructions for this function.
2539 /// If this is a `declaration`, it refers to the declaration's value body.2518 /// If this is a `declaration`, it refers to the declaration's value body.
...@@ -2542,29 +2521,20 @@ pub const Inst = struct {...@@ -2542,29 +2521,20 @@ pub const Inst = struct {
2542 bits: Bits,2521 bits: Bits,
25432522
2544 /// If both has_cc_ref and has_cc_body are false, it means auto calling convention.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 /// If both has_ret_ty_ref and has_ret_ty_body are false, it means void return type.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 pub const Bits = packed struct {2525 pub const Bits = packed struct {
2550 is_var_args: bool,2526 is_var_args: bool,
2551 is_inferred_error: bool,2527 is_inferred_error: bool,
2552 is_test: bool,2528 is_test: bool,
2553 is_extern: bool,2529 is_extern: bool,
2554 is_noinline: bool,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 has_cc_ref: bool,2531 has_cc_ref: bool,
2562 has_cc_body: bool,2532 has_cc_body: bool,
2563 has_ret_ty_ref: bool,2533 has_ret_ty_ref: bool,
2564 has_ret_ty_body: bool,2534 has_ret_ty_body: bool,
2565 has_lib_name: bool,2535 has_lib_name: bool,
2566 has_any_noalias: bool,2536 has_any_noalias: bool,
2567 _: u15 = undefined,2537 _: u21 = undefined,
2568 };2538 };
2569 };2539 };
25702540
...@@ -4269,36 +4239,6 @@ fn findTrackableInner(...@@ -4269,36 +4239,6 @@ fn findTrackableInner(
4269 var extra_index: usize = extra.end;4239 var extra_index: usize = extra.end;
4270 extra_index += @intFromBool(extra.data.bits.has_lib_name);4240 extra_index += @intFromBool(extra.data.bits.has_lib_name);
42714241
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 if (extra.data.bits.has_cc_body) {4242 if (extra.data.bits.has_cc_body) {
4303 const body_len = zir.extra[extra_index];4243 const body_len = zir.extra[extra_index];
4304 extra_index += 1;4244 extra_index += 1;
...@@ -4587,21 +4527,6 @@ pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo {...@@ -4587,21 +4527,6 @@ pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo {
4587 var ret_ty_body: []const Inst.Index = &.{};4527 var ret_ty_body: []const Inst.Index = &.{};
45884528
4589 extra_index += @intFromBool(extra.data.bits.has_lib_name);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 if (extra.data.bits.has_cc_body) {4530 if (extra.data.bits.has_cc_body) {
4606 extra_index += zir.extra[extra_index] + 1;4531 extra_index += zir.extra[extra_index] + 1;
4607 } else if (extra.data.bits.has_cc_ref) {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,18 +4637,6 @@ pub fn getAssociatedSrcHash(zir: Zir, inst: Zir.Inst.Index) ?std.zig.SrcHash {
4712 const bits = extra.data.bits;4637 const bits = extra.data.bits;
4713 var extra_index = extra.end;4638 var extra_index = extra.end;
4714 extra_index += @intFromBool(bits.has_lib_name);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 if (bits.has_cc_body) {4640 if (bits.has_cc_body) {
4728 const body_len = zir.extra[extra_index];4641 const body_len = zir.extra[extra_index];
4729 extra_index += 1 + body_len;4642 extra_index += 1 + body_len;
src/InternPool.zig+9-50
...@@ -1462,16 +1462,6 @@ pub const MapIndex = enum(u32) {...@@ -1462,16 +1462,6 @@ pub const MapIndex = enum(u32) {
1462 }1462 }
1463};1463};
14641464
1465pub const RuntimeIndex = enum(u32) {
1466 zero = 0,
1467 comptime_field_ptr = std.math.maxInt(u32),
1468 _,
1469
1470 pub fn increment(ri: *RuntimeIndex) void {
1471 ri.* = @enumFromInt(@intFromEnum(ri.*) + 1);
1472 }
1473};
1474
1475pub const ComptimeAllocIndex = enum(u32) { _ };1465pub const ComptimeAllocIndex = enum(u32) { _ };
14761466
1477pub const NamespaceIndex = enum(u32) {1467pub const NamespaceIndex = enum(u32) {
...@@ -1971,9 +1961,6 @@ pub const Key = union(enum) {...@@ -1971,9 +1961,6 @@ pub const Key = union(enum) {
1971 is_var_args: bool,1961 is_var_args: bool,
1972 is_generic: bool,1962 is_generic: bool,
1973 is_noinline: bool,1963 is_noinline: bool,
1974 cc_is_generic: bool,
1975 section_is_generic: bool,
1976 addrspace_is_generic: bool,
19771964
1978 pub fn paramIsComptime(self: @This(), i: u5) bool {1965 pub fn paramIsComptime(self: @This(), i: u5) bool {
1979 assert(i < self.param_types.len);1966 assert(i < self.param_types.len);
...@@ -5466,10 +5453,7 @@ pub const Tag = enum(u8) {...@@ -5466,10 +5453,7 @@ pub const Tag = enum(u8) {
5466 has_comptime_bits: bool,5453 has_comptime_bits: bool,
5467 has_noalias_bits: bool,5454 has_noalias_bits: bool,
5468 is_noinline: bool,5455 is_noinline: bool,
5469 cc_is_generic: bool,5456 _: u9 = 0,
5470 section_is_generic: bool,
5471 addrspace_is_generic: bool,
5472 _: u6 = 0,
5473 };5457 };
5474 };5458 };
54755459
...@@ -6895,9 +6879,6 @@ fn extraFuncType(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Ke...@@ -6895,9 +6879,6 @@ fn extraFuncType(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Ke
6895 .cc = type_function.data.flags.cc.unpack(),6879 .cc = type_function.data.flags.cc.unpack(),
6896 .is_var_args = type_function.data.flags.is_var_args,6880 .is_var_args = type_function.data.flags.is_var_args,
6897 .is_noinline = type_function.data.flags.is_noinline,6881 .is_noinline = type_function.data.flags.is_noinline,
6898 .cc_is_generic = type_function.data.flags.cc_is_generic,
6899 .section_is_generic = type_function.data.flags.section_is_generic,
6900 .addrspace_is_generic = type_function.data.flags.addrspace_is_generic,
6901 .is_generic = type_function.data.flags.is_generic,6882 .is_generic = type_function.data.flags.is_generic,
6902 };6883 };
6903}6884}
...@@ -8539,9 +8520,6 @@ pub fn getFuncType(...@@ -8539,9 +8520,6 @@ pub fn getFuncType(
8539 .has_noalias_bits = key.noalias_bits != 0,8520 .has_noalias_bits = key.noalias_bits != 0,
8540 .is_generic = key.is_generic,8521 .is_generic = key.is_generic,
8541 .is_noinline = key.is_noinline,8522 .is_noinline = key.is_noinline,
8542 .cc_is_generic = key.cc == null,
8543 .section_is_generic = key.section_is_generic,
8544 .addrspace_is_generic = key.addrspace_is_generic,
8545 },8523 },
8546 });8524 });
85478525
...@@ -8713,10 +8691,6 @@ pub const GetFuncDeclIesKey = struct {...@@ -8713,10 +8691,6 @@ pub const GetFuncDeclIesKey = struct {
8713 bare_return_type: Index,8691 bare_return_type: Index,
8714 /// null means generic.8692 /// null means generic.
8715 cc: ?std.builtin.CallingConvention,8693 cc: ?std.builtin.CallingConvention,
8716 /// null means generic.
8717 alignment: ?Alignment,
8718 section_is_generic: bool,
8719 addrspace_is_generic: bool,
8720 is_var_args: bool,8694 is_var_args: bool,
8721 is_generic: bool,8695 is_generic: bool,
8722 is_noinline: bool,8696 is_noinline: bool,
...@@ -8802,9 +8776,6 @@ pub fn getFuncDeclIes(...@@ -8802,9 +8776,6 @@ pub fn getFuncDeclIes(
8802 .has_noalias_bits = key.noalias_bits != 0,8776 .has_noalias_bits = key.noalias_bits != 0,
8803 .is_generic = key.is_generic,8777 .is_generic = key.is_generic,
8804 .is_noinline = key.is_noinline,8778 .is_noinline = key.is_noinline,
8805 .cc_is_generic = key.cc == null,
8806 .section_is_generic = key.section_is_generic,
8807 .addrspace_is_generic = key.addrspace_is_generic,
8808 },8779 },
8809 });8780 });
8810 if (key.comptime_bits != 0) extra.appendAssumeCapacity(.{key.comptime_bits});8781 if (key.comptime_bits != 0) extra.appendAssumeCapacity(.{key.comptime_bits});
...@@ -8936,9 +8907,6 @@ pub const GetFuncInstanceKey = struct {...@@ -8936,9 +8907,6 @@ pub const GetFuncInstanceKey = struct {
8936 comptime_args: []const Index,8907 comptime_args: []const Index,
8937 noalias_bits: u32,8908 noalias_bits: u32,
8938 bare_return_type: Index,8909 bare_return_type: Index,
8939 cc: std.builtin.CallingConvention,
8940 alignment: Alignment,
8941 section: OptionalNullTerminatedString,
8942 is_noinline: bool,8910 is_noinline: bool,
8943 generic_owner: Index,8911 generic_owner: Index,
8944 inferred_error_set: bool,8912 inferred_error_set: bool,
...@@ -8953,11 +8921,14 @@ pub fn getFuncInstance(...@@ -8953,11 +8921,14 @@ pub fn getFuncInstance(
8953 if (arg.inferred_error_set)8921 if (arg.inferred_error_set)
8954 return getFuncInstanceIes(ip, gpa, tid, arg);8922 return getFuncInstanceIes(ip, gpa, tid, arg);
89558923
8924 const generic_owner = unwrapCoercedFunc(ip, arg.generic_owner);
8925 const generic_owner_ty = ip.indexToKey(ip.funcDeclInfo(generic_owner).ty).func_type;
8926
8956 const func_ty = try ip.getFuncType(gpa, tid, .{8927 const func_ty = try ip.getFuncType(gpa, tid, .{
8957 .param_types = arg.param_types,8928 .param_types = arg.param_types,
8958 .return_type = arg.bare_return_type,8929 .return_type = arg.bare_return_type,
8959 .noalias_bits = arg.noalias_bits,8930 .noalias_bits = arg.noalias_bits,
8960 .cc = arg.cc,8931 .cc = generic_owner_ty.cc,
8961 .is_noinline = arg.is_noinline,8932 .is_noinline = arg.is_noinline,
8962 });8933 });
89638934
...@@ -8967,8 +8938,6 @@ pub fn getFuncInstance(...@@ -8967,8 +8938,6 @@ pub fn getFuncInstance(
8967 try extra.ensureUnusedCapacity(@typeInfo(Tag.FuncInstance).@"struct".fields.len +8938 try extra.ensureUnusedCapacity(@typeInfo(Tag.FuncInstance).@"struct".fields.len +
8968 arg.comptime_args.len);8939 arg.comptime_args.len);
89698940
8970 const generic_owner = unwrapCoercedFunc(ip, arg.generic_owner);
8971
8972 assert(arg.comptime_args.len == ip.funcTypeParamsLen(ip.typeOf(generic_owner)));8941 assert(arg.comptime_args.len == ip.funcTypeParamsLen(ip.typeOf(generic_owner)));
89738942
8974 const prev_extra_len = extra.mutate.len;8943 const prev_extra_len = extra.mutate.len;
...@@ -9015,8 +8984,6 @@ pub fn getFuncInstance(...@@ -9015,8 +8984,6 @@ pub fn getFuncInstance(
9015 generic_owner,8984 generic_owner,
9016 func_index,8985 func_index,
9017 func_extra_index,8986 func_extra_index,
9018 arg.alignment,
9019 arg.section,
9020 );8987 );
9021 return gop.put();8988 return gop.put();
9022}8989}
...@@ -9041,6 +9008,7 @@ pub fn getFuncInstanceIes(...@@ -9041,6 +9008,7 @@ pub fn getFuncInstanceIes(
9041 try items.ensureUnusedCapacity(4);9008 try items.ensureUnusedCapacity(4);
90429009
9043 const generic_owner = unwrapCoercedFunc(ip, arg.generic_owner);9010 const generic_owner = unwrapCoercedFunc(ip, arg.generic_owner);
9011 const generic_owner_ty = ip.indexToKey(ip.funcDeclInfo(arg.generic_owner).ty).func_type;
90449012
9045 // The strategy here is to add the function decl unconditionally, then to9013 // The strategy here is to add the function decl unconditionally, then to
9046 // ask if it already exists, and if so, revert the lengths of the mutated9014 // ask if it already exists, and if so, revert the lengths of the mutated
...@@ -9096,15 +9064,12 @@ pub fn getFuncInstanceIes(...@@ -9096,15 +9064,12 @@ pub fn getFuncInstanceIes(
9096 .params_len = params_len,9064 .params_len = params_len,
9097 .return_type = error_union_type,9065 .return_type = error_union_type,
9098 .flags = .{9066 .flags = .{
9099 .cc = .pack(arg.cc),9067 .cc = .pack(generic_owner_ty.cc),
9100 .is_var_args = false,9068 .is_var_args = false,
9101 .has_comptime_bits = false,9069 .has_comptime_bits = false,
9102 .has_noalias_bits = arg.noalias_bits != 0,9070 .has_noalias_bits = arg.noalias_bits != 0,
9103 .is_generic = false,9071 .is_generic = false,
9104 .is_noinline = arg.is_noinline,9072 .is_noinline = arg.is_noinline,
9105 .cc_is_generic = false,
9106 .section_is_generic = false,
9107 .addrspace_is_generic = false,
9108 },9073 },
9109 });9074 });
9110 // no comptime_bits because has_comptime_bits is false9075 // no comptime_bits because has_comptime_bits is false
...@@ -9168,8 +9133,6 @@ pub fn getFuncInstanceIes(...@@ -9168,8 +9133,6 @@ pub fn getFuncInstanceIes(
9168 generic_owner,9133 generic_owner,
9169 func_index,9134 func_index,
9170 func_extra_index,9135 func_extra_index,
9171 arg.alignment,
9172 arg.section,
9173 );9136 );
91749137
9175 func_gop.putFinal(func_index);9138 func_gop.putFinal(func_index);
...@@ -9187,8 +9150,6 @@ fn finishFuncInstance(...@@ -9187,8 +9150,6 @@ fn finishFuncInstance(
9187 generic_owner: Index,9150 generic_owner: Index,
9188 func_index: Index,9151 func_index: Index,
9189 func_extra_index: u32,9152 func_extra_index: u32,
9190 alignment: Alignment,
9191 section: OptionalNullTerminatedString,
9192) Allocator.Error!void {9153) Allocator.Error!void {
9193 const fn_owner_nav = ip.getNav(ip.funcDeclInfo(generic_owner).owner_nav);9154 const fn_owner_nav = ip.getNav(ip.funcDeclInfo(generic_owner).owner_nav);
9194 const fn_namespace = ip.getCau(fn_owner_nav.analysis_owner.unwrap().?).namespace;9155 const fn_namespace = ip.getCau(fn_owner_nav.analysis_owner.unwrap().?).namespace;
...@@ -9201,8 +9162,8 @@ fn finishFuncInstance(...@@ -9201,8 +9162,8 @@ fn finishFuncInstance(
9201 .name = nav_name,9162 .name = nav_name,
9202 .fqn = try ip.namespacePtr(fn_namespace).internFullyQualifiedName(ip, gpa, tid, nav_name),9163 .fqn = try ip.namespacePtr(fn_namespace).internFullyQualifiedName(ip, gpa, tid, nav_name),
9203 .val = func_index,9164 .val = func_index,
9204 .alignment = alignment,9165 .alignment = fn_owner_nav.status.resolved.alignment,
9205 .@"linksection" = section,9166 .@"linksection" = fn_owner_nav.status.resolved.@"linksection",
9206 .@"addrspace" = fn_owner_nav.status.resolved.@"addrspace",9167 .@"addrspace" = fn_owner_nav.status.resolved.@"addrspace",
9207 });9168 });
92089169
...@@ -9788,7 +9749,6 @@ fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 {...@@ -9788,7 +9749,6 @@ fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 {
9788 OptionalNamespaceIndex,9749 OptionalNamespaceIndex,
9789 MapIndex,9750 MapIndex,
9790 OptionalMapIndex,9751 OptionalMapIndex,
9791 RuntimeIndex,
9792 String,9752 String,
9793 NullTerminatedString,9753 NullTerminatedString,
9794 OptionalNullTerminatedString,9754 OptionalNullTerminatedString,
...@@ -9852,7 +9812,6 @@ fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { dat...@@ -9852,7 +9812,6 @@ fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { dat
9852 OptionalNamespaceIndex,9812 OptionalNamespaceIndex,
9853 MapIndex,9813 MapIndex,
9854 OptionalMapIndex,9814 OptionalMapIndex,
9855 RuntimeIndex,
9856 String,9815 String,
9857 NullTerminatedString,9816 NullTerminatedString,
9858 OptionalNullTerminatedString,9817 OptionalNullTerminatedString,
src/Sema.zig+102-272
...@@ -122,9 +122,19 @@ allow_memoize: bool = true,...@@ -122,9 +122,19 @@ allow_memoize: bool = true,
122/// This state is on `Sema` so that `cold` hints can be propagated up through blocks with less special handling.122/// This state is on `Sema` so that `cold` hints can be propagated up through blocks with less special handling.
123branch_hint: ?std.builtin.BranchHint = null,123branch_hint: ?std.builtin.BranchHint = null,
124124
125const RuntimeIndex = enum(u32) {
126 zero = 0,
127 comptime_field_ptr = std.math.maxInt(u32),
128 _,
129
130 pub fn increment(ri: *RuntimeIndex) void {
131 ri.* = @enumFromInt(@intFromEnum(ri.*) + 1);
132 }
133};
134
125const MaybeComptimeAlloc = struct {135const MaybeComptimeAlloc = struct {
126 /// The runtime index of the `alloc` instruction.136 /// The runtime index of the `alloc` instruction.
127 runtime_index: Value.RuntimeIndex,137 runtime_index: RuntimeIndex,
128 /// Backed by sema.arena. Tracks all comptime-known stores to this `alloc`. Due to138 /// Backed by sema.arena. Tracks all comptime-known stores to this `alloc`. Due to
129 /// RLS, a single comptime-known allocation may have arbitrarily many stores.139 /// RLS, a single comptime-known allocation may have arbitrarily many stores.
130 /// This list also contains `set_union_tag`, `optional_payload_ptr_set`, and140 /// This list also contains `set_union_tag`, `optional_payload_ptr_set`, and
...@@ -144,7 +154,7 @@ const ComptimeAlloc = struct {...@@ -144,7 +154,7 @@ const ComptimeAlloc = struct {
144 /// This is the `runtime_index` at the point of this allocation. If an store154 /// This is the `runtime_index` at the point of this allocation. If an store
145 /// to this alloc ever occurs with a runtime index greater than this one, it155 /// to this alloc ever occurs with a runtime index greater than this one, it
146 /// is behind a runtime condition, so a compile error will be emitted.156 /// is behind a runtime condition, so a compile error will be emitted.
147 runtime_index: Value.RuntimeIndex,157 runtime_index: RuntimeIndex,
148};158};
149159
150fn newComptimeAlloc(sema: *Sema, block: *Block, ty: Type, alignment: Alignment) !ComptimeAllocIndex {160fn newComptimeAlloc(sema: *Sema, block: *Block, ty: Type, alignment: Alignment) !ComptimeAllocIndex {
...@@ -364,7 +374,7 @@ pub const Block = struct {...@@ -364,7 +374,7 @@ pub const Block = struct {
364 runtime_loop: ?LazySrcLoc = null,374 runtime_loop: ?LazySrcLoc = null,
365 /// Non zero if a non-inline loop or a runtime conditional have been encountered.375 /// Non zero if a non-inline loop or a runtime conditional have been encountered.
366 /// Stores to comptime variables are only allowed when var.runtime_index <= runtime_index.376 /// Stores to comptime variables are only allowed when var.runtime_index <= runtime_index.
367 runtime_index: Value.RuntimeIndex = .zero,377 runtime_index: RuntimeIndex = .zero,
368 inline_block: Zir.Inst.OptionalIndex = .none,378 inline_block: Zir.Inst.OptionalIndex = .none,
369379
370 comptime_reason: ?*const ComptimeReason = null,380 comptime_reason: ?*const ComptimeReason = null,
...@@ -7805,11 +7815,9 @@ fn analyzeCall(...@@ -7805,11 +7815,9 @@ fn analyzeCall(
7805 .param_types = new_param_types,7815 .param_types = new_param_types,
7806 .return_type = owner_info.return_type,7816 .return_type = owner_info.return_type,
7807 .noalias_bits = owner_info.noalias_bits,7817 .noalias_bits = owner_info.noalias_bits,
7808 .cc = if (owner_info.cc_is_generic) null else owner_info.cc,7818 .cc = owner_info.cc,
7809 .is_var_args = owner_info.is_var_args,7819 .is_var_args = owner_info.is_var_args,
7810 .is_noinline = owner_info.is_noinline,7820 .is_noinline = owner_info.is_noinline,
7811 .section_is_generic = owner_info.section_is_generic,
7812 .addrspace_is_generic = owner_info.addrspace_is_generic,
7813 .is_generic = owner_info.is_generic,7821 .is_generic = owner_info.is_generic,
7814 };7822 };
78157823
...@@ -9545,9 +9553,6 @@ fn zirFunc(...@@ -9545,9 +9553,6 @@ fn zirFunc(
9545 block,9553 block,
9546 inst_data.src_node,9554 inst_data.src_node,
9547 inst,9555 inst,
9548 .none,
9549 target_util.defaultAddressSpace(target, .function),
9550 .default,
9551 cc,9556 cc,
9552 ret_ty,9557 ret_ty,
9553 false,9558 false,
...@@ -9833,13 +9838,7 @@ fn funcCommon(...@@ -9833,13 +9838,7 @@ fn funcCommon(
9833 block: *Block,9838 block: *Block,
9834 src_node_offset: i32,9839 src_node_offset: i32,
9835 func_inst: Zir.Inst.Index,9840 func_inst: Zir.Inst.Index,
9836 /// null means generic poison9841 cc: std.builtin.CallingConvention,
9837 alignment: ?Alignment,
9838 /// null means generic poison
9839 address_space: ?std.builtin.AddressSpace,
9840 section: Section,
9841 /// null means generic poison
9842 cc: ?std.builtin.CallingConvention,
9843 /// this might be Type.generic_poison9842 /// this might be Type.generic_poison
9844 bare_return_type: Type,9843 bare_return_type: Type,
9845 var_args: bool,9844 var_args: bool,
...@@ -9860,26 +9859,17 @@ fn funcCommon(...@@ -9860,26 +9859,17 @@ fn funcCommon(
9860 const cc_src = block.src(.{ .node_offset_fn_type_cc = src_node_offset });9859 const cc_src = block.src(.{ .node_offset_fn_type_cc = src_node_offset });
9861 const func_src = block.nodeOffset(src_node_offset);9860 const func_src = block.nodeOffset(src_node_offset);
98629861
9863 var is_generic = bare_return_type.isGenericPoison() or9862 var is_generic = bare_return_type.isGenericPoison();
9864 alignment == null or
9865 address_space == null or
9866 section == .generic or
9867 cc == null;
98689863
9869 if (var_args) {9864 if (var_args) {
9870 if (is_generic) {9865 if (is_generic) {
9871 return sema.fail(block, func_src, "generic function cannot be variadic", .{});9866 return sema.fail(block, func_src, "generic function cannot be variadic", .{});
9872 }9867 }
9873 try sema.checkCallConvSupportsVarArgs(block, cc_src, cc.?);9868 try sema.checkCallConvSupportsVarArgs(block, cc_src, cc);
9874 }9869 }
98759870
9876 const is_source_decl = sema.generic_owner == .none;9871 const is_source_decl = sema.generic_owner == .none;
98779872
9878 // In the case of generic calling convention, or generic alignment, we use
9879 // default values which are only meaningful for the generic function, *not*
9880 // the instantiation, which can depend on comptime parameters.
9881 // Related proposal: https://github.com/ziglang/zig/issues/11834
9882 const cc_resolved = cc orelse .auto;
9883 var comptime_bits: u32 = 0;9873 var comptime_bits: u32 = 0;
9884 for (block.params.items(.ty), block.params.items(.is_comptime), 0..) |param_ty_ip, param_is_comptime, i| {9874 for (block.params.items(.ty), block.params.items(.is_comptime), 0..) |param_ty_ip, param_is_comptime, i| {
9885 const param_ty = Type.fromInterned(param_ty_ip);9875 const param_ty = Type.fromInterned(param_ty_ip);
...@@ -9897,11 +9887,11 @@ fn funcCommon(...@@ -9897,11 +9887,11 @@ fn funcCommon(
9897 }9887 }
9898 const this_generic = param_ty.isGenericPoison();9888 const this_generic = param_ty.isGenericPoison();
9899 is_generic = is_generic or this_generic;9889 is_generic = is_generic or this_generic;
9900 if (param_is_comptime and !target_util.fnCallConvAllowsZigTypes(cc_resolved)) {9890 if (param_is_comptime and !target_util.fnCallConvAllowsZigTypes(cc)) {
9901 return sema.fail(block, param_src, "comptime parameters not allowed in function with calling convention '{s}'", .{@tagName(cc_resolved)});9891 return sema.fail(block, param_src, "comptime parameters not allowed in function with calling convention '{s}'", .{@tagName(cc)});
9902 }9892 }
9903 if (this_generic and !sema.no_partial_func_ty and !target_util.fnCallConvAllowsZigTypes(cc_resolved)) {9893 if (this_generic and !sema.no_partial_func_ty and !target_util.fnCallConvAllowsZigTypes(cc)) {
9904 return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{s}'", .{@tagName(cc_resolved)});9894 return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{s}'", .{@tagName(cc)});
9905 }9895 }
9906 if (!param_ty.isValidParamType(zcu)) {9896 if (!param_ty.isValidParamType(zcu)) {
9907 const opaque_str = if (param_ty.zigTypeTag(zcu) == .@"opaque") "opaque " else "";9897 const opaque_str = if (param_ty.zigTypeTag(zcu) == .@"opaque") "opaque " else "";
...@@ -9909,10 +9899,10 @@ fn funcCommon(...@@ -9909,10 +9899,10 @@ fn funcCommon(
9909 opaque_str, param_ty.fmt(pt),9899 opaque_str, param_ty.fmt(pt),
9910 });9900 });
9911 }9901 }
9912 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)) {
9913 const msg = msg: {9903 const msg = msg: {
9914 const msg = try sema.errMsg(param_src, "parameter of type '{}' not allowed in function with calling convention '{s}'", .{9904 const msg = try sema.errMsg(param_src, "parameter of type '{}' not allowed in function with calling convention '{s}'", .{
9915 param_ty.fmt(pt), @tagName(cc_resolved),9905 param_ty.fmt(pt), @tagName(cc),
9916 });9906 });
9917 errdefer msg.destroy(sema.gpa);9907 errdefer msg.destroy(sema.gpa);
99189908
...@@ -9942,13 +9932,13 @@ fn funcCommon(...@@ -9942,13 +9932,13 @@ fn funcCommon(
9942 {9932 {
9943 return sema.fail(block, param_src, "non-pointer parameter declared noalias", .{});9933 return sema.fail(block, param_src, "non-pointer parameter declared noalias", .{});
9944 }9934 }
9945 switch (cc_resolved) {9935 switch (cc) {
9946 .x86_64_interrupt, .x86_interrupt => {9936 .x86_64_interrupt, .x86_interrupt => {
9947 const err_code_size = target.ptrBitWidth();9937 const err_code_size = target.ptrBitWidth();
9948 switch (i) {9938 switch (i) {
9949 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)}),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)}),
9950 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 }),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 }),
9951 else => return sema.fail(block, param_src, "'{s}' calling convention supports up to 2 parameters, found {d}", .{ @tagName(cc_resolved), i + 1 }),9941 else => return sema.fail(block, param_src, "'{s}' calling convention supports up to 2 parameters, found {d}", .{ @tagName(cc), i + 1 }),
9952 }9942 }
9953 },9943 },
9954 .arm_interrupt,9944 .arm_interrupt,
...@@ -9960,7 +9950,7 @@ fn funcCommon(...@@ -9960,7 +9950,7 @@ fn funcCommon(
9960 .csky_interrupt,9950 .csky_interrupt,
9961 .m68k_interrupt,9951 .m68k_interrupt,
9962 .avr_signal,9952 .avr_signal,
9963 => 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)}),
9964 else => {},9954 else => {},
9965 }9955 }
9966 }9956 }
...@@ -9975,9 +9965,6 @@ fn funcCommon(...@@ -9975,9 +9965,6 @@ fn funcCommon(
9975 assert(has_body);9965 assert(has_body);
9976 assert(!is_generic);9966 assert(!is_generic);
9977 assert(comptime_bits == 0);9967 assert(comptime_bits == 0);
9978 assert(cc != null);
9979 assert(section != .generic);
9980 assert(address_space != null);
9981 assert(!var_args);9968 assert(!var_args);
9982 if (inferred_error_set) {9969 if (inferred_error_set) {
9983 try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src);9970 try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src);
...@@ -9986,13 +9973,6 @@ fn funcCommon(...@@ -9986,13 +9973,6 @@ fn funcCommon(
9986 .param_types = param_types,9973 .param_types = param_types,
9987 .noalias_bits = noalias_bits,9974 .noalias_bits = noalias_bits,
9988 .bare_return_type = bare_return_type.toIntern(),9975 .bare_return_type = bare_return_type.toIntern(),
9989 .cc = cc_resolved,
9990 .alignment = alignment.?,
9991 .section = switch (section) {
9992 .generic => unreachable,
9993 .default => .none,
9994 .explicit => |x| x.toOptional(),
9995 },
9996 .is_noinline = is_noinline,9976 .is_noinline = is_noinline,
9997 .inferred_error_set = inferred_error_set,9977 .inferred_error_set = inferred_error_set,
9998 .generic_owner = sema.generic_owner,9978 .generic_owner = sema.generic_owner,
...@@ -10006,7 +9986,7 @@ fn funcCommon(...@@ -10006,7 +9986,7 @@ fn funcCommon(
10006 ret_poison,9986 ret_poison,
10007 bare_return_type,9987 bare_return_type,
10008 ret_ty_src,9988 ret_ty_src,
10009 cc_resolved,9989 cc,
10010 is_source_decl,9990 is_source_decl,
10011 ret_ty_requires_comptime,9991 ret_ty_requires_comptime,
10012 func_inst,9992 func_inst,
...@@ -10017,12 +9997,6 @@ fn funcCommon(...@@ -10017,12 +9997,6 @@ fn funcCommon(
10017 );9997 );
10018 }9998 }
100199999
10020 const section_name: InternPool.OptionalNullTerminatedString = switch (section) {
10021 .generic => .none,
10022 .default => .none,
10023 .explicit => |name| name.toOptional(),
10024 };
10025
10026 if (inferred_error_set) {10000 if (inferred_error_set) {
10027 assert(!is_extern);10001 assert(!is_extern);
10028 assert(has_body);10002 assert(has_body);
...@@ -10036,9 +10010,6 @@ fn funcCommon(...@@ -10036,9 +10010,6 @@ fn funcCommon(
10036 .comptime_bits = comptime_bits,10010 .comptime_bits = comptime_bits,
10037 .bare_return_type = bare_return_type.toIntern(),10011 .bare_return_type = bare_return_type.toIntern(),
10038 .cc = cc,10012 .cc = cc,
10039 .alignment = alignment,
10040 .section_is_generic = section == .generic,
10041 .addrspace_is_generic = address_space == null,
10042 .is_var_args = var_args,10013 .is_var_args = var_args,
10043 .is_generic = final_is_generic,10014 .is_generic = final_is_generic,
10044 .is_noinline = is_noinline,10015 .is_noinline = is_noinline,
...@@ -10049,13 +10020,6 @@ fn funcCommon(...@@ -10049,13 +10020,6 @@ fn funcCommon(
10049 .lbrace_column = @as(u16, @truncate(src_locs.columns)),10020 .lbrace_column = @as(u16, @truncate(src_locs.columns)),
10050 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),10021 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),
10051 });10022 });
10052 // func_decl functions take ownership of the `Nav` of Sema'a owner `Cau`.
10053 ip.resolveNavValue(sema.getOwnerCauNav(), .{
10054 .val = func_index,
10055 .alignment = alignment orelse .none,
10056 .@"linksection" = section_name,
10057 .@"addrspace" = address_space orelse .generic,
10058 });
10059 return finishFunc(10023 return finishFunc(
10060 sema,10024 sema,
10061 block,10025 block,
...@@ -10064,7 +10028,7 @@ fn funcCommon(...@@ -10064,7 +10028,7 @@ fn funcCommon(
10064 ret_poison,10028 ret_poison,
10065 bare_return_type,10029 bare_return_type,
10066 ret_ty_src,10030 ret_ty_src,
10067 cc_resolved,10031 cc,
10068 is_source_decl,10032 is_source_decl,
10069 ret_ty_requires_comptime,10033 ret_ty_requires_comptime,
10070 func_inst,10034 func_inst,
...@@ -10081,8 +10045,6 @@ fn funcCommon(...@@ -10081,8 +10045,6 @@ fn funcCommon(
10081 .comptime_bits = comptime_bits,10045 .comptime_bits = comptime_bits,
10082 .return_type = bare_return_type.toIntern(),10046 .return_type = bare_return_type.toIntern(),
10083 .cc = cc,10047 .cc = cc,
10084 .section_is_generic = section == .generic,
10085 .addrspace_is_generic = address_space == null,
10086 .is_var_args = var_args,10048 .is_var_args = var_args,
10087 .is_generic = final_is_generic,10049 .is_generic = final_is_generic,
10088 .is_noinline = is_noinline,10050 .is_noinline = is_noinline,
...@@ -10090,38 +10052,20 @@ fn funcCommon(...@@ -10090,38 +10052,20 @@ fn funcCommon(
1009010052
10091 if (is_extern) {10053 if (is_extern) {
10092 assert(comptime_bits == 0);10054 assert(comptime_bits == 0);
10093 assert(cc != null);
10094 assert(alignment != null);
10095 assert(section != .generic);
10096 assert(address_space != null);
10097 assert(!is_generic);10055 assert(!is_generic);
10098 if (opt_lib_name) |lib_name| try sema.handleExternLibName(block, block.src(.{10056 if (opt_lib_name) |lib_name| try sema.handleExternLibName(block, block.src(.{
10099 .node_offset_lib_name = src_node_offset,10057 .node_offset_lib_name = src_node_offset,
10100 }), lib_name);10058 }), lib_name);
10101 const func_index = try pt.getExtern(.{10059 const extern_func_index = try sema.resolveExternDecl(block, .fromInterned(func_ty), opt_lib_name, true, false);
10102 .name = sema.getOwnerCauNavName(),
10103 .ty = func_ty,
10104 .lib_name = try ip.getOrPutStringOpt(gpa, pt.tid, opt_lib_name, .no_embedded_nulls),
10105 .is_const = true,
10106 .is_threadlocal = false,
10107 .is_weak_linkage = false,
10108 .is_dll_import = false,
10109 .alignment = alignment orelse .none,
10110 .@"addrspace" = address_space orelse .generic,
10111 .zir_index = sema.getOwnerCauDeclInst(), // `declaration` instruction
10112 .owner_nav = undefined, // ignored by `getExtern`
10113 });
10114 // Note that unlike function declaration, extern functions don't touch the
10115 // Sema's owner Cau's owner Nav. The alignment etc were passed above.
10116 return finishFunc(10060 return finishFunc(
10117 sema,10061 sema,
10118 block,10062 block,
10119 func_index,10063 extern_func_index,
10120 func_ty,10064 func_ty,
10121 ret_poison,10065 ret_poison,
10122 bare_return_type,10066 bare_return_type,
10123 ret_ty_src,10067 ret_ty_src,
10124 cc_resolved,10068 cc,
10125 is_source_decl,10069 is_source_decl,
10126 ret_ty_requires_comptime,10070 ret_ty_requires_comptime,
10127 func_inst,10071 func_inst,
...@@ -10144,13 +10088,6 @@ fn funcCommon(...@@ -10144,13 +10088,6 @@ fn funcCommon(
10144 .lbrace_column = @as(u16, @truncate(src_locs.columns)),10088 .lbrace_column = @as(u16, @truncate(src_locs.columns)),
10145 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),10089 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),
10146 });10090 });
10147 // func_decl functions take ownership of the `Nav` of Sema'a owner `Cau`.
10148 ip.resolveNavValue(sema.getOwnerCauNav(), .{
10149 .val = func_index,
10150 .alignment = alignment orelse .none,
10151 .@"linksection" = section_name,
10152 .@"addrspace" = address_space orelse .generic,
10153 });
10154 return finishFunc(10091 return finishFunc(
10155 sema,10092 sema,
10156 block,10093 block,
...@@ -10159,7 +10096,7 @@ fn funcCommon(...@@ -10159,7 +10096,7 @@ fn funcCommon(
10159 ret_poison,10096 ret_poison,
10160 bare_return_type,10097 bare_return_type,
10161 ret_ty_src,10098 ret_ty_src,
10162 cc_resolved,10099 cc,
10163 is_source_decl,10100 is_source_decl,
10164 ret_ty_requires_comptime,10101 ret_ty_requires_comptime,
10165 func_inst,10102 func_inst,
...@@ -10178,7 +10115,7 @@ fn funcCommon(...@@ -10178,7 +10115,7 @@ fn funcCommon(
10178 ret_poison,10115 ret_poison,
10179 bare_return_type,10116 bare_return_type,
10180 ret_ty_src,10117 ret_ty_src,
10181 cc_resolved,10118 cc,
10182 is_source_decl,10119 is_source_decl,
10183 ret_ty_requires_comptime,10120 ret_ty_requires_comptime,
10184 func_inst,10121 func_inst,
...@@ -26829,52 +26766,8 @@ fn zirVarExtended(...@@ -26829,52 +26766,8 @@ fn zirVarExtended(
26829 try sema.validateVarType(block, ty_src, var_ty, small.is_extern);26766 try sema.validateVarType(block, ty_src, var_ty, small.is_extern);
2683026767
26831 if (small.is_extern) {26768 if (small.is_extern) {
26832 // We need to resolve the alignment and addrspace early.26769 const extern_val = try sema.resolveExternDecl(block, var_ty, lib_name, small.is_const, small.is_threadlocal);
26833 // Keep in sync with logic in `Zcu.PerThread.semaCau`.26770 return Air.internedToRef(extern_val);
26834 const align_src = block.src(.{ .node_offset_var_decl_align = 0 });
26835 const addrspace_src = block.src(.{ .node_offset_var_decl_addrspace = 0 });
26836
26837 const decl_inst, const decl_bodies = decl: {
26838 const decl_inst = sema.getOwnerCauDeclInst().resolve(ip) orelse return error.AnalysisFail;
26839 const zir_decl, const extra_end = sema.code.getDeclaration(decl_inst);
26840 break :decl .{ decl_inst, zir_decl.getBodies(extra_end, sema.code) };
26841 };
26842
26843 const alignment: InternPool.Alignment = a: {
26844 const align_body = decl_bodies.align_body orelse break :a .none;
26845 const align_ref = try sema.resolveInlineBody(block, align_body, decl_inst);
26846 break :a try sema.analyzeAsAlign(block, align_src, align_ref);
26847 };
26848
26849 const @"addrspace": std.builtin.AddressSpace = as: {
26850 const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(var_ty.toIntern())) {
26851 .func_type => .function,
26852 else => .variable,
26853 };
26854 const target = zcu.getTarget();
26855 const addrspace_body = decl_bodies.addrspace_body orelse break :as switch (addrspace_ctx) {
26856 .function => target_util.defaultAddressSpace(target, .function),
26857 .variable => target_util.defaultAddressSpace(target, .global_mutable),
26858 .constant => target_util.defaultAddressSpace(target, .global_constant),
26859 else => unreachable,
26860 };
26861 const addrspace_ref = try sema.resolveInlineBody(block, addrspace_body, decl_inst);
26862 break :as try sema.analyzeAsAddressSpace(block, addrspace_src, addrspace_ref, addrspace_ctx);
26863 };
26864
26865 return Air.internedToRef(try pt.getExtern(.{
26866 .name = sema.getOwnerCauNavName(),
26867 .ty = var_ty.toIntern(),
26868 .lib_name = try ip.getOrPutStringOpt(sema.gpa, pt.tid, lib_name, .no_embedded_nulls),
26869 .is_const = small.is_const,
26870 .is_threadlocal = small.is_threadlocal,
26871 .is_weak_linkage = false,
26872 .is_dll_import = false,
26873 .alignment = alignment,
26874 .@"addrspace" = @"addrspace",
26875 .zir_index = sema.getOwnerCauDeclInst(), // `declaration` instruction
26876 .owner_nav = undefined, // ignored by `getExtern`
26877 }));
26878 }26771 }
26879 assert(!small.is_const); // non-const non-extern variable is not legal26772 assert(!small.is_const); // non-const non-extern variable is not legal
26880 return Air.internedToRef(try pt.intern(.{ .variable = .{26773 return Air.internedToRef(try pt.intern(.{ .variable = .{
...@@ -26887,6 +26780,66 @@ fn zirVarExtended(...@@ -26887,6 +26780,66 @@ fn zirVarExtended(
26887 } }));26780 } }));
26888}26781}
2688926782
26783fn 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
26890fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {26843fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
26891 const tracy = trace(@src());26844 const tracy = trace(@src());
26892 defer tracy.end();26845 defer tracy.end();
...@@ -26898,9 +26851,6 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -26898,9 +26851,6 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
26898 const extra = sema.code.extraData(Zir.Inst.FuncFancy, inst_data.payload_index);26851 const extra = sema.code.extraData(Zir.Inst.FuncFancy, inst_data.payload_index);
26899 const target = zcu.getTarget();26852 const target = zcu.getTarget();
2690026853
26901 const align_src = block.src(.{ .node_offset_fn_type_align = inst_data.src_node });
26902 const addrspace_src = block.src(.{ .node_offset_fn_type_addrspace = inst_data.src_node });
26903 const section_src = block.src(.{ .node_offset_fn_type_section = inst_data.src_node });
26904 const cc_src = block.src(.{ .node_offset_fn_type_cc = inst_data.src_node });26854 const cc_src = block.src(.{ .node_offset_fn_type_cc = inst_data.src_node });
26905 const ret_src = block.src(.{ .node_offset_fn_type_ret_ty = inst_data.src_node });26855 const ret_src = block.src(.{ .node_offset_fn_type_ret_ty = inst_data.src_node });
26906 const has_body = extra.data.body_len != 0;26856 const has_body = extra.data.body_len != 0;
...@@ -26914,112 +26864,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -26914,112 +26864,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
26914 break :blk lib_name;26864 break :blk lib_name;
26915 } else null;26865 } else null;
2691626866
26917 if (has_body and26867 const cc: std.builtin.CallingConvention = if (extra.data.bits.has_cc_body) blk: {
26918 (extra.data.bits.has_align_body or extra.data.bits.has_align_ref) and
26919 !target_util.supportsFunctionAlignment(target))
26920 {
26921 return sema.fail(block, align_src, "target does not support function alignment", .{});
26922 }
26923
26924 const @"align": ?Alignment = if (extra.data.bits.has_align_body) blk: {
26925 const body_len = sema.code.extra[extra_index];
26926 extra_index += 1;
26927 const body = sema.code.bodySlice(extra_index, body_len);
26928 extra_index += body.len;
26929
26930 const val = try sema.resolveGenericBody(block, align_src, body, inst, Type.u29, .{
26931 .needed_comptime_reason = "alignment must be comptime-known",
26932 });
26933 if (val.isGenericPoison()) {
26934 break :blk null;
26935 }
26936 break :blk try sema.validateAlign(block, align_src, try val.toUnsignedIntSema(pt));
26937 } else if (extra.data.bits.has_align_ref) blk: {
26938 const align_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
26939 extra_index += 1;
26940 const uncoerced_align = sema.resolveInst(align_ref) catch |err| switch (err) {
26941 error.GenericPoison => break :blk null,
26942 else => |e| return e,
26943 };
26944 const coerced_align = sema.coerce(block, Type.u29, uncoerced_align, align_src) catch |err| switch (err) {
26945 error.GenericPoison => break :blk null,
26946 else => |e| return e,
26947 };
26948 const align_val = sema.resolveConstDefinedValue(block, align_src, coerced_align, .{
26949 .needed_comptime_reason = "alignment must be comptime-known",
26950 }) catch |err| switch (err) {
26951 error.GenericPoison => break :blk null,
26952 else => |e| return e,
26953 };
26954 break :blk try sema.validateAlign(block, align_src, try align_val.toUnsignedIntSema(pt));
26955 } else .none;
26956
26957 const @"addrspace": ?std.builtin.AddressSpace = if (extra.data.bits.has_addrspace_body) blk: {
26958 const body_len = sema.code.extra[extra_index];
26959 extra_index += 1;
26960 const body = sema.code.bodySlice(extra_index, body_len);
26961 extra_index += body.len;
26962
26963 const addrspace_ty = try sema.getBuiltinType("AddressSpace");
26964 const val = try sema.resolveGenericBody(block, addrspace_src, body, inst, addrspace_ty, .{
26965 .needed_comptime_reason = "addrspace must be comptime-known",
26966 });
26967 if (val.isGenericPoison()) {
26968 break :blk null;
26969 }
26970 break :blk zcu.toEnum(std.builtin.AddressSpace, val);
26971 } else if (extra.data.bits.has_addrspace_ref) blk: {
26972 const addrspace_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
26973 extra_index += 1;
26974 const addrspace_ty = try sema.getBuiltinType("AddressSpace");
26975 const uncoerced_addrspace = sema.resolveInst(addrspace_ref) catch |err| switch (err) {
26976 error.GenericPoison => break :blk null,
26977 else => |e| return e,
26978 };
26979 const coerced_addrspace = sema.coerce(block, addrspace_ty, uncoerced_addrspace, addrspace_src) catch |err| switch (err) {
26980 error.GenericPoison => break :blk null,
26981 else => |e| return e,
26982 };
26983 const addrspace_val = sema.resolveConstDefinedValue(block, addrspace_src, coerced_addrspace, .{
26984 .needed_comptime_reason = "addrspace must be comptime-known",
26985 }) catch |err| switch (err) {
26986 error.GenericPoison => break :blk null,
26987 else => |e| return e,
26988 };
26989 break :blk zcu.toEnum(std.builtin.AddressSpace, addrspace_val);
26990 } else target_util.defaultAddressSpace(target, .function);
26991
26992 const section: Section = if (extra.data.bits.has_section_body) blk: {
26993 const body_len = sema.code.extra[extra_index];
26994 extra_index += 1;
26995 const body = sema.code.bodySlice(extra_index, body_len);
26996 extra_index += body.len;
26997
26998 const ty = Type.slice_const_u8;
26999 const val = try sema.resolveGenericBody(block, section_src, body, inst, ty, .{
27000 .needed_comptime_reason = "linksection must be comptime-known",
27001 });
27002 if (val.isGenericPoison()) {
27003 break :blk .generic;
27004 }
27005 break :blk .{ .explicit = try sema.sliceToIpString(block, section_src, val, .{
27006 .needed_comptime_reason = "linksection must be comptime-known",
27007 }) };
27008 } else if (extra.data.bits.has_section_ref) blk: {
27009 const section_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
27010 extra_index += 1;
27011 const section_name = sema.resolveConstStringIntern(block, section_src, section_ref, .{
27012 .needed_comptime_reason = "linksection must be comptime-known",
27013 }) catch |err| switch (err) {
27014 error.GenericPoison => {
27015 break :blk .generic;
27016 },
27017 else => |e| return e,
27018 };
27019 break :blk .{ .explicit = section_name };
27020 } else .default;
27021
27022 const cc: ?std.builtin.CallingConvention = if (extra.data.bits.has_cc_body) blk: {
27023 const body_len = sema.code.extra[extra_index];26868 const body_len = sema.code.extra[extra_index];
27024 extra_index += 1;26869 extra_index += 1;
27025 const body = sema.code.bodySlice(extra_index, body_len);26870 const body = sema.code.bodySlice(extra_index, body_len);
...@@ -27029,28 +26874,16 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -27029,28 +26874,16 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
27029 const val = try sema.resolveGenericBody(block, cc_src, body, inst, cc_ty, .{26874 const val = try sema.resolveGenericBody(block, cc_src, body, inst, cc_ty, .{
27030 .needed_comptime_reason = "calling convention must be comptime-known",26875 .needed_comptime_reason = "calling convention must be comptime-known",
27031 });26876 });
27032 if (val.isGenericPoison()) {
27033 break :blk null;
27034 }
27035 break :blk try sema.analyzeValueAsCallconv(block, cc_src, val);26877 break :blk try sema.analyzeValueAsCallconv(block, cc_src, val);
27036 } else if (extra.data.bits.has_cc_ref) blk: {26878 } else if (extra.data.bits.has_cc_ref) blk: {
27037 const cc_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);26879 const cc_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
27038 extra_index += 1;26880 extra_index += 1;
27039 const cc_ty = try sema.getBuiltinType("CallingConvention");26881 const cc_ty = try sema.getBuiltinType("CallingConvention");
27040 const uncoerced_cc = sema.resolveInst(cc_ref) catch |err| switch (err) {26882 const uncoerced_cc = try sema.resolveInst(cc_ref);
27041 error.GenericPoison => break :blk null,26883 const coerced_cc = try sema.coerce(block, cc_ty, uncoerced_cc, cc_src);
27042 else => |e| return e,26884 const cc_val = try sema.resolveConstDefinedValue(block, cc_src, coerced_cc, .{
27043 };
27044 const coerced_cc = sema.coerce(block, cc_ty, uncoerced_cc, cc_src) catch |err| switch (err) {
27045 error.GenericPoison => break :blk null,
27046 else => |e| return e,
27047 };
27048 const cc_val = sema.resolveConstDefinedValue(block, cc_src, coerced_cc, .{
27049 .needed_comptime_reason = "calling convention must be comptime-known",26885 .needed_comptime_reason = "calling convention must be comptime-known",
27050 }) catch |err| switch (err) {26886 });
27051 error.GenericPoison => break :blk null,
27052 else => |e| return e,
27053 };
27054 break :blk try sema.analyzeValueAsCallconv(block, cc_src, cc_val);26887 break :blk try sema.analyzeValueAsCallconv(block, cc_src, cc_val);
27055 } else cc: {26888 } else cc: {
27056 if (has_body) {26889 if (has_body) {
...@@ -27132,9 +26965,6 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -27132,9 +26965,6 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
27132 block,26965 block,
27133 inst_data.src_node,26966 inst_data.src_node,
27134 inst,26967 inst,
27135 @"align",
27136 @"addrspace",
27137 section,
27138 cc,26968 cc,
27139 ret_ty,26969 ret_ty,
27140 is_var_args,26970 is_var_args,
src/Value.zig-2
...@@ -3710,8 +3710,6 @@ pub fn makeBool(x: bool) Value {...@@ -3710,8 +3710,6 @@ pub fn makeBool(x: bool) Value {
3710 return if (x) Value.true else Value.false;3710 return if (x) Value.true else Value.false;
3711}3711}
37123712
3713pub const RuntimeIndex = InternPool.RuntimeIndex;
3714
3715/// `parent_ptr` must be a single-pointer to some optional.3713/// `parent_ptr` must be a single-pointer to some optional.
3716/// Returns a pointer to the payload of the optional.3714/// Returns a pointer to the payload of the optional.
3717/// May perform type resolution.3715/// May perform type resolution.
src/Zcu.zig+24-6
...@@ -836,20 +836,38 @@ pub const SrcLoc = struct {...@@ -836,20 +836,38 @@ pub const SrcLoc = struct {
836 .node_offset_var_decl_align => |node_off| {836 .node_offset_var_decl_align => |node_off| {
837 const tree = try src_loc.file_scope.getTree(gpa);837 const tree = try src_loc.file_scope.getTree(gpa);
838 const node = src_loc.relativeToNodeIndex(node_off);838 const node = src_loc.relativeToNodeIndex(node_off);
839 const full = tree.fullVarDecl(node).?;839 var buf: [1]Ast.Node.Index = undefined;
840 return tree.nodeToSpan(full.ast.align_node);840 const align_node = if (tree.fullVarDecl(node)) |v|
841 v.ast.align_node
842 else if (tree.fullFnProto(&buf, node)) |f|
843 f.ast.align_expr
844 else
845 unreachable;
846 return tree.nodeToSpan(align_node);
841 },847 },
842 .node_offset_var_decl_section => |node_off| {848 .node_offset_var_decl_section => |node_off| {
843 const tree = try src_loc.file_scope.getTree(gpa);849 const tree = try src_loc.file_scope.getTree(gpa);
844 const node = src_loc.relativeToNodeIndex(node_off);850 const node = src_loc.relativeToNodeIndex(node_off);
845 const full = tree.fullVarDecl(node).?;851 var buf: [1]Ast.Node.Index = undefined;
846 return tree.nodeToSpan(full.ast.section_node);852 const section_node = if (tree.fullVarDecl(node)) |v|
853 v.ast.section_node
854 else if (tree.fullFnProto(&buf, node)) |f|
855 f.ast.section_expr
856 else
857 unreachable;
858 return tree.nodeToSpan(section_node);
847 },859 },
848 .node_offset_var_decl_addrspace => |node_off| {860 .node_offset_var_decl_addrspace => |node_off| {
849 const tree = try src_loc.file_scope.getTree(gpa);861 const tree = try src_loc.file_scope.getTree(gpa);
850 const node = src_loc.relativeToNodeIndex(node_off);862 const node = src_loc.relativeToNodeIndex(node_off);
851 const full = tree.fullVarDecl(node).?;863 var buf: [1]Ast.Node.Index = undefined;
852 return tree.nodeToSpan(full.ast.addrspace_node);864 const addrspace_node = if (tree.fullVarDecl(node)) |v|
865 v.ast.addrspace_node
866 else if (tree.fullFnProto(&buf, node)) |f|
867 f.ast.addrspace_expr
868 else
869 unreachable;
870 return tree.nodeToSpan(addrspace_node);
853 },871 },
854 .node_offset_var_decl_init => |node_off| {872 .node_offset_var_decl_init => |node_off| {
855 const tree = try src_loc.file_scope.getTree(gpa);873 const tree = try src_loc.file_scope.getTree(gpa);
src/Zcu/PerThread.zig+70-54
...@@ -1314,68 +1314,84 @@ fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult {...@@ -1314,68 +1314,84 @@ fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult {
1314 };1314 };
1315 }1315 }
13161316
1317 const nav_already_populated, const queue_linker_work = switch (ip.indexToKey(decl_val.toIntern())) {1317 const queue_linker_work, const is_owned_fn = switch (ip.indexToKey(decl_val.toIntern())) {
1318 .func => |f| .{ f.owner_nav == nav_index, true },1318 .func => |f| .{ true, f.owner_nav == nav_index }, // note that this lets function aliases reach codegen
1319 .variable => |v| .{ false, v.owner_nav == nav_index },1319 .variable => |v| .{ v.owner_nav == nav_index, false },
1320 .@"extern" => .{ false, false },1320 .@"extern" => |e| .{ false, Type.fromInterned(e.ty).zigTypeTag(zcu) == .@"fn" },
1321 else => .{ false, true },1321 else => .{ true, false },
1322 };1322 };
13231323
1324 if (nav_already_populated) {1324 // Keep in sync with logic in `Sema.zirVarExtended`.
1325 // This is a function declaration.1325 const alignment: InternPool.Alignment = a: {
1326 // Logic in `Sema.funcCommon` has already populated the `Nav` for us.1326 const align_body = decl_bodies.align_body orelse break :a .none;
1327 assert(ip.getNav(nav_index).status.resolved.val == decl_val.toIntern());1327 const align_ref = try sema.resolveInlineBody(&block, align_body, inst_info.inst);
1328 } else {1328 break :a try sema.analyzeAsAlign(&block, align_src, align_ref);
1329 // Keep in sync with logic in `Sema.zirVarExtended`.1329 };
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 };
13351330
1336 const @"linksection": InternPool.OptionalNullTerminatedString = ls: {1331 const @"linksection": InternPool.OptionalNullTerminatedString = ls: {
1337 const linksection_body = decl_bodies.linksection_body orelse break :ls .none;1332 const linksection_body = decl_bodies.linksection_body orelse break :ls .none;
1338 const linksection_ref = try sema.resolveInlineBody(&block, linksection_body, inst_info.inst);1333 const linksection_ref = try sema.resolveInlineBody(&block, linksection_body, inst_info.inst);
1339 const bytes = try sema.toConstString(&block, section_src, linksection_ref, .{1334 const bytes = try sema.toConstString(&block, section_src, linksection_ref, .{
1340 .needed_comptime_reason = "linksection must be comptime-known",1335 .needed_comptime_reason = "linksection must be comptime-known",
1341 });1336 });
1342 if (std.mem.indexOfScalar(u8, bytes, 0) != null) {1337 if (std.mem.indexOfScalar(u8, bytes, 0) != null) {
1343 return sema.fail(&block, section_src, "linksection cannot contain null bytes", .{});1338 return sema.fail(&block, section_src, "linksection cannot contain null bytes", .{});
1344 } else if (bytes.len == 0) {1339 } else if (bytes.len == 0) {
1345 return sema.fail(&block, section_src, "linksection cannot be empty", .{});1340 return sema.fail(&block, section_src, "linksection cannot be empty", .{});
1346 }1341 }
1347 break :ls try ip.getOrPutStringOpt(gpa, pt.tid, bytes, .no_embedded_nulls);1342 break :ls try ip.getOrPutStringOpt(gpa, pt.tid, bytes, .no_embedded_nulls);
1348 };1343 };
13491344
1350 const @"addrspace": std.builtin.AddressSpace = as: {1345 const @"addrspace": std.builtin.AddressSpace = as: {
1351 const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(decl_val.toIntern())) {1346 const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(decl_val.toIntern())) {
1352 .func => .function,1347 .func => .function,
1353 .variable => .variable,1348 .variable => .variable,
1354 .@"extern" => |e| if (ip.indexToKey(e.ty) == .func_type)1349 .@"extern" => |e| if (ip.indexToKey(e.ty) == .func_type)
1355 .function1350 .function
1356 else1351 else
1357 .variable,1352 .variable,
1358 else => .constant,1353 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);
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 };
13701365
1371 ip.resolveNavValue(nav_index, .{1366 if (is_owned_fn) {
1372 .val = decl_val.toIntern(),1367 // linksection etc are legal, except some targets do not support function alignment.
1373 .alignment = alignment,1368 if (decl_bodies.align_body != null and !target_util.supportsFunctionAlignment(zcu.getTarget())) {
1374 .@"linksection" = @"linksection",1369 return sema.fail(&block, align_src, "target does not support function alignment", .{});
1375 .@"addrspace" = @"addrspace",1370 }
1376 });1371 } else if (try decl_ty.comptimeOnlySema(pt)) {
1372 // alignment, linksection, addrspace annotations are not allowed for comptime-only types.
1373 const reason: []const u8 = switch (ip.indexToKey(decl_val.toIntern())) {
1374 .func => "function alias", // slightly clearer message, since you *can* specify these on function *declarations*
1375 else => "comptime-only type",
1376 };
1377 if (decl_bodies.align_body != null) {
1378 return sema.fail(&block, align_src, "cannot specify alignment of {s}", .{reason});
1379 }
1380 if (decl_bodies.linksection_body != null) {
1381 return sema.fail(&block, section_src, "cannot specify linksection of {s}", .{reason});
1382 }
1383 if (decl_bodies.addrspace_body != null) {
1384 return sema.fail(&block, addrspace_src, "cannot specify addrspace of {s}", .{reason});
1385 }
1377 }1386 }
13781387
1388 ip.resolveNavValue(nav_index, .{
1389 .val = decl_val.toIntern(),
1390 .alignment = alignment,
1391 .@"linksection" = @"linksection",
1392 .@"addrspace" = @"addrspace",
1393 });
1394
1379 // Mark the `Cau` as completed before evaluating the export!1395 // Mark the `Cau` as completed before evaluating the export!
1380 assert(zcu.analysis_in_progress.swapRemove(anal_unit));1396 assert(zcu.analysis_in_progress.swapRemove(anal_unit));
13811397
src/print_zir.zig-54
...@@ -2349,12 +2349,6 @@ const Writer = struct {...@@ -2349,12 +2349,6 @@ const Writer = struct {
2349 false,2349 false,
2350 false,2350 false,
23512351
2352 .none,
2353 &.{},
2354 .none,
2355 &.{},
2356 .none,
2357 &.{},
2358 .none,2352 .none,
2359 &.{},2353 &.{},
2360 ret_ty_ref,2354 ret_ty_ref,
...@@ -2372,12 +2366,6 @@ const Writer = struct {...@@ -2372,12 +2366,6 @@ const Writer = struct {
2372 const extra = self.code.extraData(Zir.Inst.FuncFancy, inst_data.payload_index);2366 const extra = self.code.extraData(Zir.Inst.FuncFancy, inst_data.payload_index);
23732367
2374 var extra_index: usize = extra.end;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 var cc_ref: Zir.Inst.Ref = .none;2369 var cc_ref: Zir.Inst.Ref = .none;
2382 var cc_body: []const Zir.Inst.Index = &.{};2370 var cc_body: []const Zir.Inst.Index = &.{};
2383 var ret_ty_ref: Zir.Inst.Ref = .none;2371 var ret_ty_ref: Zir.Inst.Ref = .none;
...@@ -2390,33 +2378,6 @@ const Writer = struct {...@@ -2390,33 +2378,6 @@ const Writer = struct {
2390 }2378 }
2391 try self.writeFlag(stream, "test, ", extra.data.bits.is_test);2379 try self.writeFlag(stream, "test, ", extra.data.bits.is_test);
23922380
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 if (extra.data.bits.has_cc_body) {2381 if (extra.data.bits.has_cc_body) {
2421 const body_len = self.code.extra[extra_index];2382 const body_len = self.code.extra[extra_index];
2422 extra_index += 1;2383 extra_index += 1;
...@@ -2455,12 +2416,6 @@ const Writer = struct {...@@ -2455,12 +2416,6 @@ const Writer = struct {
2455 extra.data.bits.is_var_args,2416 extra.data.bits.is_var_args,
2456 extra.data.bits.is_extern,2417 extra.data.bits.is_extern,
2457 extra.data.bits.is_noinline,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 cc_ref,2419 cc_ref,
2465 cc_body,2420 cc_body,
2466 ret_ty_ref,2421 ret_ty_ref,
...@@ -2651,12 +2606,6 @@ const Writer = struct {...@@ -2651,12 +2606,6 @@ const Writer = struct {
2651 var_args: bool,2606 var_args: bool,
2652 is_extern: bool,2607 is_extern: bool,
2653 is_noinline: bool,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 cc_ref: Zir.Inst.Ref,2609 cc_ref: Zir.Inst.Ref,
2661 cc_body: []const Zir.Inst.Index,2610 cc_body: []const Zir.Inst.Index,
2662 ret_ty_ref: Zir.Inst.Ref,2611 ret_ty_ref: Zir.Inst.Ref,
...@@ -2666,9 +2615,6 @@ const Writer = struct {...@@ -2666,9 +2615,6 @@ const Writer = struct {
2666 src_locs: Zir.Inst.Func.SrcLocs,2615 src_locs: Zir.Inst.Func.SrcLocs,
2667 noalias_bits: u32,2616 noalias_bits: u32,
2668 ) !void {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 try self.writeOptionalInstRefOrBody(stream, "cc=", cc_ref, cc_body);2618 try self.writeOptionalInstRefOrBody(stream, "cc=", cc_ref, cc_body);
2673 try self.writeOptionalInstRefOrBody(stream, "ret_ty=", ret_ty_ref, ret_ty_body);2619 try self.writeOptionalInstRefOrBody(stream, "ret_ty=", ret_ty_ref, ret_ty_body);
2674 try self.writeFlag(stream, "vargs, ", var_args);2620 try self.writeFlag(stream, "vargs, ", var_args);
test/behavior/align.zig-41
...@@ -361,47 +361,6 @@ fn simple4() align(4) i32 {...@@ -361,47 +361,6 @@ fn simple4() align(4) i32 {
361 return 0x19;361 return 0x19;
362}362}
363363
364test "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
388test "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
405test "runtime-known array index has best alignment possible" {364test "runtime-known array index has best alignment possible" {
406 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO365 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
407366
test/behavior/fn.zig-25
...@@ -637,24 +637,6 @@ test "address of function parameter is consistent in other parameter type" {...@@ -637,24 +637,6 @@ test "address of function parameter is consistent in other parameter type" {
637 S.paramAddrMatch(1, 2);637 S.paramAddrMatch(1, 2);
638}638}
639639
640test "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
651test "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
658test "address of function parameter is consistent in function return type" {640test "address of function parameter is consistent in function return type" {
659 const S = struct {641 const S = struct {
660 fn paramAddrMatch(comptime x: u8) if (&x != &x) unreachable else void {}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,13 +644,6 @@ test "address of function parameter is consistent in function return type" {
662 S.paramAddrMatch(1);644 S.paramAddrMatch(1);
663}645}
664646
665test "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
672test "function parameter self equality" {647test "function parameter self equality" {
673 const S = struct {648 const S = struct {
674 fn equal(x: u32) bool {649 fn equal(x: u32) bool {
test/behavior/type_info.zig+11
...@@ -373,6 +373,17 @@ fn testFunction() !void {...@@ -373,6 +373,17 @@ fn testFunction() !void {
373 try expect(!foo_ptr_fn_info.pointer.is_allowzero);373 try expect(!foo_ptr_fn_info.pointer.is_allowzero);
374 try expect(foo_ptr_fn_info.pointer.sentinel == null);374 try expect(foo_ptr_fn_info.pointer.sentinel == null);
375375
376 // Avoid looking at `typeInfoFooAligned` on targets which don't support function alignment.
377 switch (builtin.target.cpu.arch) {
378 .spirv,
379 .spirv32,
380 .spirv64,
381 .wasm32,
382 .wasm64,
383 => return,
384 else => {},
385 }
386
376 const aligned_foo_fn_type = @TypeOf(typeInfoFooAligned);387 const aligned_foo_fn_type = @TypeOf(typeInfoFooAligned);
377 const aligned_foo_fn_info = @typeInfo(aligned_foo_fn_type);388 const aligned_foo_fn_info = @typeInfo(aligned_foo_fn_type);
378 try expect(aligned_foo_fn_info.@"fn".calling_convention.eql(.c));389 try expect(aligned_foo_fn_info.@"fn".calling_convention.eql(.c));
test/cases/compile_errors/comptime_only_global_align_section_addrspace.zig created+37
...@@ -0,0 +1,37 @@
1fn okay_func() void {}
2
3const a align(64) = okay_func;
4const b addrspace(.generic) = okay_func;
5const c linksection("irrelevant") = okay_func;
6
7const d align(64) = 1.23;
8const e addrspace(.generic) = 1.23;
9const f linksection("irrelevant") = 1.23;
10
11const g: comptime_float align(64) = 1.23;
12const h: comptime_float addrspace(.generic) = 1.23;
13const i: comptime_float linksection("irrelevant") = 1.23;
14
15// zig fmt: off
16comptime { _ = a; }
17comptime { _ = b; }
18comptime { _ = c; }
19comptime { _ = d; }
20comptime { _ = e; }
21comptime { _ = f; }
22comptime { _ = g; }
23comptime { _ = h; }
24comptime { _ = i; }
25// zig fmt: on
26
27// error
28//
29// :3:15: error: cannot specify alignment of function alias
30// :4:20: error: cannot specify addrspace of function alias
31// :5:21: error: cannot specify linksection of function alias
32// :7:15: error: cannot specify alignment of comptime-only type
33// :8:20: error: cannot specify addrspace of comptime-only type
34// :9:21: error: cannot specify linksection of comptime-only type
35// :11:31: error: cannot specify alignment of comptime-only type
36// :12:36: error: cannot specify addrspace of comptime-only type
37// :13:37: error: cannot specify linksection of comptime-only type
test/cases/compile_errors/invalid_variadic_function.zig-5
...@@ -1,13 +1,9 @@...@@ -1,13 +1,9 @@
1fn foo(...) void {}1fn foo(...) void {}
2fn bar(a: anytype, ...) callconv(a) void {}
3inline fn foo2(...) void {}2inline fn foo2(...) void {}
43
5comptime {4comptime {
6 _ = foo;5 _ = foo;
7}6}
8comptime {
9 _ = bar;
10}
11comptime {7comptime {
12 _ = foo2;8 _ = foo2;
13}9}
...@@ -19,4 +15,3 @@ comptime {...@@ -19,4 +15,3 @@ comptime {
19// :1:1: note: supported calling conventions: 'x86_64_sysv', 'x86_64_win'15// :1:1: note: supported calling conventions: 'x86_64_sysv', 'x86_64_win'
20// :1:1: error: variadic function does not support 'inline' calling convention16// :1:1: error: variadic function does not support 'inline' calling convention
21// :1:1: note: supported calling conventions: 'x86_64_sysv', 'x86_64_win'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,9 +937,13 @@ fn testLinksection(b: *Build, opts: Options) *Step {
937 const obj = addObject(b, opts, .{ .name = "main", .zig_source_bytes = 937 const obj = addObject(b, opts, .{ .name = "main", .zig_source_bytes =
938 \\export var test_global: u32 linksection("__DATA,__TestGlobal") = undefined;938 \\export var test_global: u32 linksection("__DATA,__TestGlobal") = undefined;
939 \\export fn testFn() linksection("__TEXT,__TestFn") callconv(.C) void {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 });
944948
945 const check = obj.checkObject();949 const check = obj.checkObject();
...@@ -950,7 +954,7 @@ fn testLinksection(b: *Build, opts: Options) *Step {...@@ -950,7 +954,7 @@ fn testLinksection(b: *Build, opts: Options) *Step {
950954
951 if (opts.optimize == .Debug) {955 if (opts.optimize == .Debug) {
952 check.checkInSymtab();956 check.checkInSymtab();
953 check.checkContains("(__TEXT,__TestGenFnA) _main.testGenericFn__anon_");957 check.checkContains("(__TEXT,__TestGenFnA) _main.TestGenericFn(");
954 }958 }
955959
956 test_step.dependOn(&check.step);960 test_step.dependOn(&check.step);