| ... | ... | @@ -712,7 +712,6 @@ pub const Object = struct { |
| 712 | 712 | .byval => { |
| 713 | 713 | const param_ty = fn_info.param_types[it.zig_index - 1]; |
| 714 | 714 | const param = llvm_func.getParam(llvm_arg_i); |
| 715 | | llvm_arg_i += 1; |
| 716 | 715 | |
| 717 | 716 | if (isByRef(param_ty)) { |
| 718 | 717 | const alignment = param_ty.abiAlignment(target); |
| ... | ... | @@ -724,11 +723,33 @@ pub const Object = struct { |
| 724 | 723 | try args.append(arg_ptr); |
| 725 | 724 | } else { |
| 726 | 725 | try args.append(param); |
| 726 | |
| 727 | if (param_ty.isPtrAtRuntime()) { |
| 728 | // TODO noalias attribute |
| 729 | const ptr_info = param_ty.ptrInfo().data; |
| 730 | if (!param_ty.isPtrLikeOptional() and !ptr_info.@"allowzero") { |
| 731 | dg.addArgAttr(llvm_func, llvm_arg_i, "nonnull"); |
| 732 | } |
| 733 | if (!ptr_info.mutable) { |
| 734 | dg.addArgAttr(llvm_func, llvm_arg_i, "readonly"); |
| 735 | } |
| 736 | if (ptr_info.@"align" != 0) { |
| 737 | dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align"); |
| 738 | } else { |
| 739 | dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.pointee_type.abiAlignment(target)); |
| 740 | } |
| 741 | } |
| 727 | 742 | } |
| 743 | llvm_arg_i += 1; |
| 728 | 744 | }, |
| 729 | 745 | .byref => { |
| 730 | 746 | const param_ty = fn_info.param_types[it.zig_index - 1]; |
| 731 | 747 | const param = llvm_func.getParam(llvm_arg_i); |
| 748 | |
| 749 | dg.addArgAttr(llvm_func, llvm_arg_i, "nonnull"); |
| 750 | dg.addArgAttr(llvm_func, llvm_arg_i, "readonly"); |
| 751 | dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", param_ty.abiAlignment(target)); |
| 752 | |
| 732 | 753 | llvm_arg_i += 1; |
| 733 | 754 | |
| 734 | 755 | if (isByRef(param_ty)) { |
| ... | ... | @@ -2213,20 +2234,8 @@ pub const DeclGen = struct { |
| 2213 | 2234 | dg.addArgAttr(llvm_fn, @boolToInt(sret), "nonnull"); |
| 2214 | 2235 | } |
| 2215 | 2236 | |
| 2216 | | // Set parameter attributes. |
| 2217 | | // TODO: more attributes. see codegen.cpp `make_fn_llvm_value`. |
| 2218 | 2237 | switch (fn_info.cc) { |
| 2219 | 2238 | .Unspecified, .Inline => { |
| 2220 | | var llvm_param_i: c_uint = @as(c_uint, @boolToInt(sret)) + @boolToInt(err_return_tracing); |
| 2221 | | for (fn_info.param_types) |param_ty| { |
| 2222 | | if (!param_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 2223 | | |
| 2224 | | if (isByRef(param_ty)) { |
| 2225 | | dg.addArgAttr(llvm_fn, llvm_param_i, "nonnull"); |
| 2226 | | // TODO readonly, noalias, align |
| 2227 | | } |
| 2228 | | llvm_param_i += 1; |
| 2229 | | } |
| 2230 | 2239 | llvm_fn.setFunctionCallConv(.Fast); |
| 2231 | 2240 | }, |
| 2232 | 2241 | .Naked => { |
| ... | ... | @@ -3705,6 +3714,10 @@ pub const DeclGen = struct { |
| 3705 | 3714 | return dg.addAttr(fn_val, param_index + 1, attr_name); |
| 3706 | 3715 | } |
| 3707 | 3716 | |
| 3717 | fn addArgAttrInt(dg: DeclGen, fn_val: *const llvm.Value, param_index: u32, attr_name: []const u8, int: u64) void { |
| 3718 | return dg.addAttrInt(fn_val, param_index + 1, attr_name, int); |
| 3719 | } |
| 3720 | |
| 3708 | 3721 | fn removeAttr(val: *const llvm.Value, index: llvm.AttributeIndex, name: []const u8) void { |
| 3709 | 3722 | const kind_id = llvm.getEnumAttributeKindForName(name.ptr, name.len); |
| 3710 | 3723 | assert(kind_id != 0); |