| author | |
| committer | |
| log | dea437edfb124b8a4cf4f2e09330ef4282991cc9 |
| tree | cff1a5c5f9b89c4f8f94def8006f7d07f9757dbc |
| parent | 903bed931dddc8b3f7ad1fa87e57eca13375dd32 |
| signature |
7 files changed, 47 insertions(+), 7 deletions(-)
src/AstGen.zig+13-5| ... | ... | @@ -1274,6 +1274,7 @@ fn fnProtoExpr( |
| 1274 | 1274 | .is_inferred_error = false, |
| 1275 | 1275 | .is_test = false, |
| 1276 | 1276 | .is_extern = false, |
| 1277 | .is_noinline = false, | |
| 1277 | 1278 | .noalias_bits = noalias_bits, |
| 1278 | 1279 | }); |
| 1279 | 1280 | |
| ... | ... | @@ -3389,7 +3390,6 @@ fn fnDecl( |
| 3389 | 3390 | }; |
| 3390 | 3391 | defer fn_gz.unstack(); |
| 3391 | 3392 | |
| 3392 | // TODO: support noinline | |
| 3393 | 3393 | const is_pub = fn_proto.visib_token != null; |
| 3394 | 3394 | const is_export = blk: { |
| 3395 | 3395 | const maybe_export_token = fn_proto.extern_export_inline_token orelse break :blk false; |
| ... | ... | @@ -3403,6 +3403,10 @@ fn fnDecl( |
| 3403 | 3403 | const maybe_inline_token = fn_proto.extern_export_inline_token orelse break :blk false; |
| 3404 | 3404 | break :blk token_tags[maybe_inline_token] == .keyword_inline; |
| 3405 | 3405 | }; |
| 3406 | const is_noinline = blk: { | |
| 3407 | const maybe_noinline_token = fn_proto.extern_export_inline_token orelse break :blk false; | |
| 3408 | break :blk token_tags[maybe_noinline_token] == .keyword_noinline; | |
| 3409 | }; | |
| 3406 | 3410 | |
| 3407 | 3411 | const doc_comment_index = try astgen.docCommentAsString(fn_proto.firstToken()); |
| 3408 | 3412 | |
| ... | ... | @@ -3610,6 +3614,7 @@ fn fnDecl( |
| 3610 | 3614 | .is_inferred_error = false, |
| 3611 | 3615 | .is_test = false, |
| 3612 | 3616 | .is_extern = true, |
| 3617 | .is_noinline = is_noinline, | |
| 3613 | 3618 | .noalias_bits = noalias_bits, |
| 3614 | 3619 | }); |
| 3615 | 3620 | } else func: { |
| ... | ... | @@ -3658,6 +3663,7 @@ fn fnDecl( |
| 3658 | 3663 | .is_inferred_error = is_inferred_error, |
| 3659 | 3664 | .is_test = false, |
| 3660 | 3665 | .is_extern = false, |
| 3666 | .is_noinline = is_noinline, | |
| 3661 | 3667 | .noalias_bits = noalias_bits, |
| 3662 | 3668 | }); |
| 3663 | 3669 | }; |
| ... | ... | @@ -4093,6 +4099,7 @@ fn testDecl( |
| 4093 | 4099 | .is_inferred_error = true, |
| 4094 | 4100 | .is_test = true, |
| 4095 | 4101 | .is_extern = false, |
| 4102 | .is_noinline = false, | |
| 4096 | 4103 | .noalias_bits = 0, |
| 4097 | 4104 | }); |
| 4098 | 4105 | |
| ... | ... | @@ -10175,6 +10182,7 @@ const GenZir = struct { |
| 10175 | 10182 | is_inferred_error: bool, |
| 10176 | 10183 | is_test: bool, |
| 10177 | 10184 | is_extern: bool, |
| 10185 | is_noinline: bool, | |
| 10178 | 10186 | }) !Zir.Inst.Ref { |
| 10179 | 10187 | assert(args.src_node != 0); |
| 10180 | 10188 | const astgen = gz.astgen; |
| ... | ... | @@ -10216,10 +10224,9 @@ const GenZir = struct { |
| 10216 | 10224 | } |
| 10217 | 10225 | const body_len = astgen.countBodyLenAfterFixups(body); |
| 10218 | 10226 | |
| 10219 | if (args.cc_ref != .none or args.lib_name != 0 or | |
| 10220 | args.is_var_args or args.is_test or args.is_extern or | |
| 10221 | args.align_ref != .none or args.section_ref != .none or | |
| 10222 | args.addrspace_ref != .none or args.noalias_bits != 0) | |
| 10227 | if (args.cc_ref != .none or args.lib_name != 0 or args.is_var_args or args.is_test or | |
| 10228 | args.is_extern or args.align_ref != .none or args.section_ref != .none or | |
| 10229 | args.addrspace_ref != .none or args.noalias_bits != 0 or args.is_noinline) | |
| 10223 | 10230 | { |
| 10224 | 10231 | var align_body: []Zir.Inst.Index = &.{}; |
| 10225 | 10232 | var addrspace_body: []Zir.Inst.Index = &.{}; |
| ... | ... | @@ -10252,6 +10259,7 @@ const GenZir = struct { |
| 10252 | 10259 | .is_inferred_error = args.is_inferred_error, |
| 10253 | 10260 | .is_test = args.is_test, |
| 10254 | 10261 | .is_extern = args.is_extern, |
| 10262 | .is_noinline = args.is_noinline, | |
| 10255 | 10263 | .has_lib_name = args.lib_name != 0, |
| 10256 | 10264 | .has_any_noalias = args.noalias_bits != 0, |
| 10257 | 10265 |
src/Module.zig+1-1| ... | ... | @@ -1488,7 +1488,7 @@ pub const Fn = struct { |
| 1488 | 1488 | branch_quota: u32, |
| 1489 | 1489 | state: Analysis, |
| 1490 | 1490 | is_cold: bool = false, |
| 1491 | is_noinline: bool = false, | |
| 1491 | is_noinline: bool, | |
| 1492 | 1492 | calls_or_awaits_errorable_fn: bool = false, |
| 1493 | 1493 | |
| 1494 | 1494 | /// Any inferred error sets that this function owns, both its own inferred error set and |
src/Sema.zig+9| ... | ... | @@ -7252,6 +7252,7 @@ fn zirFunc( |
| 7252 | 7252 | src_locs, |
| 7253 | 7253 | null, |
| 7254 | 7254 | 0, |
| 7255 | false, | |
| 7255 | 7256 | ); |
| 7256 | 7257 | } |
| 7257 | 7258 | |
| ... | ... | @@ -7382,6 +7383,7 @@ fn funcCommon( |
| 7382 | 7383 | src_locs: Zir.Inst.Func.SrcLocs, |
| 7383 | 7384 | opt_lib_name: ?[]const u8, |
| 7384 | 7385 | noalias_bits: u32, |
| 7386 | is_noinline: bool, | |
| 7385 | 7387 | ) CompileError!Air.Inst.Ref { |
| 7386 | 7388 | const fn_src = LazySrcLoc.nodeOffset(src_node_offset); |
| 7387 | 7389 | const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = src_node_offset }; |
| ... | ... | @@ -7577,6 +7579,10 @@ fn funcCommon( |
| 7577 | 7579 | }); |
| 7578 | 7580 | } |
| 7579 | 7581 | |
| 7582 | if (cc_workaround == .Inline and is_noinline) { | |
| 7583 | return sema.fail(block, cc_src, "'noinline' function cannot have callconv 'Inline'", .{}); | |
| 7584 | } | |
| 7585 | ||
| 7580 | 7586 | break :fn_ty try Type.Tag.function.create(sema.arena, .{ |
| 7581 | 7587 | .param_types = param_types, |
| 7582 | 7588 | .comptime_params = comptime_params.ptr, |
| ... | ... | @@ -7657,6 +7663,7 @@ fn funcCommon( |
| 7657 | 7663 | .rbrace_column = @truncate(u16, src_locs.columns >> 16), |
| 7658 | 7664 | .param_names = param_names, |
| 7659 | 7665 | .branch_quota = default_branch_quota, |
| 7666 | .is_noinline = is_noinline, | |
| 7660 | 7667 | }; |
| 7661 | 7668 | if (maybe_inferred_error_set_node) |node| { |
| 7662 | 7669 | new_func.inferred_error_sets.prepend(node); |
| ... | ... | @@ -18443,6 +18450,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 18443 | 18450 | const is_var_args = extra.data.bits.is_var_args; |
| 18444 | 18451 | const is_inferred_error = extra.data.bits.is_inferred_error; |
| 18445 | 18452 | const is_extern = extra.data.bits.is_extern; |
| 18453 | const is_noinline = extra.data.bits.is_noinline; | |
| 18446 | 18454 | |
| 18447 | 18455 | return sema.funcCommon( |
| 18448 | 18456 | block, |
| ... | ... | @@ -18460,6 +18468,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 18460 | 18468 | src_locs, |
| 18461 | 18469 | lib_name, |
| 18462 | 18470 | noalias_bits, |
| 18471 | is_noinline, | |
| 18463 | 18472 | ); |
| 18464 | 18473 | } |
| 18465 | 18474 |
src/Zir.zig+2-1| ... | ... | @@ -2736,6 +2736,7 @@ pub const Inst = struct { |
| 2736 | 2736 | is_inferred_error: bool, |
| 2737 | 2737 | is_test: bool, |
| 2738 | 2738 | is_extern: bool, |
| 2739 | is_noinline: bool, | |
| 2739 | 2740 | has_align_ref: bool, |
| 2740 | 2741 | has_align_body: bool, |
| 2741 | 2742 | has_addrspace_ref: bool, |
| ... | ... | @@ -2748,7 +2749,7 @@ pub const Inst = struct { |
| 2748 | 2749 | has_ret_ty_body: bool, |
| 2749 | 2750 | has_lib_name: bool, |
| 2750 | 2751 | has_any_noalias: bool, |
| 2751 | _: u16 = undefined, | |
| 2752 | _: u15 = undefined, | |
| 2752 | 2753 | }; |
| 2753 | 2754 | }; |
| 2754 | 2755 |
src/codegen/llvm.zig+6| ... | ... | @@ -699,6 +699,12 @@ pub const Object = struct { |
| 699 | 699 | DeclGen.removeFnAttr(llvm_func, "cold"); |
| 700 | 700 | } |
| 701 | 701 | |
| 702 | if (func.is_noinline) { | |
| 703 | dg.addFnAttr(llvm_func, "noinline"); | |
| 704 | } else { | |
| 705 | DeclGen.removeFnAttr(llvm_func, "noinline"); | |
| 706 | } | |
| 707 | ||
| 702 | 708 | // Remove all the basic blocks of a function in order to start over, generating |
| 703 | 709 | // LLVM IR from an empty function body. |
| 704 | 710 | while (llvm_func.getFirstBasicBlock()) |bb| { |
src/print_zir.zig+4| ... | ... | @@ -1984,6 +1984,7 @@ const Writer = struct { |
| 1984 | 1984 | inferred_error_set, |
| 1985 | 1985 | false, |
| 1986 | 1986 | false, |
| 1987 | false, | |
| 1987 | 1988 | |
| 1988 | 1989 | .none, |
| 1989 | 1990 | &.{}, |
| ... | ... | @@ -2091,6 +2092,7 @@ const Writer = struct { |
| 2091 | 2092 | extra.data.bits.is_inferred_error, |
| 2092 | 2093 | extra.data.bits.is_var_args, |
| 2093 | 2094 | extra.data.bits.is_extern, |
| 2095 | extra.data.bits.is_noinline, | |
| 2094 | 2096 | align_ref, |
| 2095 | 2097 | align_body, |
| 2096 | 2098 | addrspace_ref, |
| ... | ... | @@ -2250,6 +2252,7 @@ const Writer = struct { |
| 2250 | 2252 | inferred_error_set: bool, |
| 2251 | 2253 | var_args: bool, |
| 2252 | 2254 | is_extern: bool, |
| 2255 | is_noinline: bool, | |
| 2253 | 2256 | align_ref: Zir.Inst.Ref, |
| 2254 | 2257 | align_body: []const Zir.Inst.Index, |
| 2255 | 2258 | addrspace_ref: Zir.Inst.Ref, |
| ... | ... | @@ -2273,6 +2276,7 @@ const Writer = struct { |
| 2273 | 2276 | try self.writeFlag(stream, "vargs, ", var_args); |
| 2274 | 2277 | try self.writeFlag(stream, "extern, ", is_extern); |
| 2275 | 2278 | try self.writeFlag(stream, "inferror, ", inferred_error_set); |
| 2279 | try self.writeFlag(stream, "noinline, ", is_noinline); | |
| 2276 | 2280 | |
| 2277 | 2281 | if (noalias_bits != 0) { |
| 2278 | 2282 | try stream.print("noalias=0b{b}, ", .{noalias_bits}); |
test/cases/compile_errors/noinline_fn_cc_inline.zig created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | const cc = .Inline; | |
| 2 | noinline fn foo() callconv(cc) void {} | |
| 3 | ||
| 4 | comptime { | |
| 5 | _ = foo; | |
| 6 | } | |
| 7 | ||
| 8 | // error | |
| 9 | // backend=stage2 | |
| 10 | // target=native | |
| 11 | // | |
| 12 | // :2:28: error: 'noinline' function cannot have callconv 'Inline' |