| ... | ... | @@ -2214,16 +2214,31 @@ pub const DeclGen = struct { |
| 2214 | 2214 | } |
| 2215 | 2215 | |
| 2216 | 2216 | // Set parameter attributes. |
| 2217 | | // TODO: more attributes. see codegen.cpp `make_fn_llvm_value`. |
| 2218 | 2217 | switch (fn_info.cc) { |
| 2219 | 2218 | .Unspecified, .Inline => { |
| 2220 | 2219 | var llvm_param_i: c_uint = @as(c_uint, @boolToInt(sret)) + @boolToInt(err_return_tracing); |
| 2221 | 2220 | for (fn_info.param_types) |param_ty| { |
| 2222 | 2221 | if (!param_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 2223 | 2222 | |
| 2223 | // TODO: noalias attribute |
| 2224 | |
| 2224 | 2225 | if (isByRef(param_ty)) { |
| 2225 | 2226 | dg.addArgAttr(llvm_fn, llvm_param_i, "nonnull"); |
| 2226 | | // TODO readonly, noalias, align |
| 2227 | dg.addArgAttr(llvm_fn, llvm_param_i, "readonly"); |
| 2228 | dg.addArgAttrInt(llvm_fn, llvm_param_i, "align", param_ty.abiAlignment(target)); |
| 2229 | } else if (param_ty.isPtrAtRuntime()) { |
| 2230 | const ptr_info = param_ty.ptrInfo().data; |
| 2231 | if (!param_ty.isPtrLikeOptional() and !ptr_info.@"allowzero") { |
| 2232 | dg.addArgAttr(llvm_fn, llvm_param_i, "nonnull"); |
| 2233 | } |
| 2234 | if (!ptr_info.mutable) { |
| 2235 | dg.addArgAttr(llvm_fn, llvm_param_i, "readonly"); |
| 2236 | } |
| 2237 | if (ptr_info.@"align" != 0) { |
| 2238 | dg.addArgAttrInt(llvm_fn, llvm_param_i, "align", ptr_info.@"align"); |
| 2239 | } else { |
| 2240 | dg.addArgAttrInt(llvm_fn, llvm_param_i, "align", ptr_info.pointee_type.abiAlignment(target)); |
| 2241 | } |
| 2227 | 2242 | } |
| 2228 | 2243 | llvm_param_i += 1; |
| 2229 | 2244 | } |
| ... | ... | @@ -2237,6 +2252,12 @@ pub const DeclGen = struct { |
| 2237 | 2252 | @panic("TODO: LLVM backend lower async function"); |
| 2238 | 2253 | }, |
| 2239 | 2254 | else => { |
| 2255 | // TODO set attributes such as noalias, nonnull, readonly, and align |
| 2256 | // Note that there is not a one to one correspondence between fn_info.param_types |
| 2257 | // and llvm parameters due to C ABI lowering. This will need to involve |
| 2258 | // iterateParamTypes which is currently happening over in updateFunc. |
| 2259 | // Probably this whole "set parameter attributes" section of code should |
| 2260 | // move there and integrate with this abstraction. |
| 2240 | 2261 | llvm_fn.setFunctionCallConv(toLlvmCallConv(fn_info.cc, target)); |
| 2241 | 2262 | }, |
| 2242 | 2263 | } |
| ... | ... | @@ -3705,6 +3726,10 @@ pub const DeclGen = struct { |
| 3705 | 3726 | return dg.addAttr(fn_val, param_index + 1, attr_name); |
| 3706 | 3727 | } |
| 3707 | 3728 | |
| 3729 | fn addArgAttrInt(dg: DeclGen, fn_val: *const llvm.Value, param_index: u32, attr_name: []const u8, int: u64) void { |
| 3730 | return dg.addAttrInt(fn_val, param_index + 1, attr_name, int); |
| 3731 | } |
| 3732 | |
| 3708 | 3733 | fn removeAttr(val: *const llvm.Value, index: llvm.AttributeIndex, name: []const u8) void { |
| 3709 | 3734 | const kind_id = llvm.getEnumAttributeKindForName(name.ptr, name.len); |
| 3710 | 3735 | assert(kind_id != 0); |