| ... | ... | @@ -1847,51 +1847,64 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_ |
| 1847 | 1847 | return true; |
| 1848 | 1848 | } |
| 1849 | 1849 | |
| 1850 | | // Arrays are just pointers |
| 1851 | | if (ty->id == ZigTypeIdArray) { |
| 1852 | | assert(handle_is_ptr(ty)); |
| 1853 | | switch (fn_walk->id) { |
| 1854 | | case FnWalkIdAttrs: |
| 1855 | | // arrays passed to C ABI functions may not be at address 0 |
| 1856 | | addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull"); |
| 1857 | | addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty)); |
| 1858 | | fn_walk->data.attrs.gen_i += 1; |
| 1859 | | break; |
| 1860 | | case FnWalkIdCall: |
| 1861 | | fn_walk->data.call.gen_param_values->append(val); |
| 1862 | | break; |
| 1863 | | case FnWalkIdTypes: { |
| 1864 | | ZigType *gen_type = get_pointer_to_type(g, ty, true); |
| 1865 | | fn_walk->data.types.gen_param_types->append(get_llvm_type(g, gen_type)); |
| 1866 | | fn_walk->data.types.param_di_types->append(get_llvm_di_type(g, gen_type)); |
| 1867 | | break; |
| 1868 | | } |
| 1869 | | case FnWalkIdVars: { |
| 1870 | | var->value_ref = LLVMGetParam(llvm_fn, fn_walk->data.vars.gen_i); |
| 1871 | | di_arg_index = fn_walk->data.vars.gen_i; |
| 1872 | | dest_ty = get_pointer_to_type(g, ty, false); |
| 1873 | | fn_walk->data.vars.gen_i += 1; |
| 1874 | | goto var_ok; |
| 1875 | | } |
| 1876 | | case FnWalkIdInits: |
| 1877 | | if (var->decl_node) { |
| 1878 | | gen_var_debug_decl(g, var); |
| 1850 | { |
| 1851 | // Arrays are just pointers |
| 1852 | if (ty->id == ZigTypeIdArray) { |
| 1853 | assert(handle_is_ptr(ty)); |
| 1854 | switch (fn_walk->id) { |
| 1855 | case FnWalkIdAttrs: |
| 1856 | // arrays passed to C ABI functions may not be at address 0 |
| 1857 | addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull"); |
| 1858 | addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty)); |
| 1859 | fn_walk->data.attrs.gen_i += 1; |
| 1860 | break; |
| 1861 | case FnWalkIdCall: |
| 1862 | fn_walk->data.call.gen_param_values->append(val); |
| 1863 | break; |
| 1864 | case FnWalkIdTypes: { |
| 1865 | ZigType *gen_type = get_pointer_to_type(g, ty, true); |
| 1866 | fn_walk->data.types.gen_param_types->append(get_llvm_type(g, gen_type)); |
| 1867 | fn_walk->data.types.param_di_types->append(get_llvm_di_type(g, gen_type)); |
| 1868 | break; |
| 1879 | 1869 | } |
| 1880 | | fn_walk->data.inits.gen_i += 1; |
| 1881 | | break; |
| 1870 | case FnWalkIdVars: { |
| 1871 | var->value_ref = LLVMGetParam(llvm_fn, fn_walk->data.vars.gen_i); |
| 1872 | di_arg_index = fn_walk->data.vars.gen_i; |
| 1873 | dest_ty = get_pointer_to_type(g, ty, false); |
| 1874 | fn_walk->data.vars.gen_i += 1; |
| 1875 | goto var_ok; |
| 1876 | } |
| 1877 | case FnWalkIdInits: |
| 1878 | if (var->decl_node) { |
| 1879 | gen_var_debug_decl(g, var); |
| 1880 | } |
| 1881 | fn_walk->data.inits.gen_i += 1; |
| 1882 | break; |
| 1883 | } |
| 1884 | return true; |
| 1882 | 1885 | } |
| 1883 | | return true; |
| 1884 | | } |
| 1885 | 1886 | |
| 1886 | | if (g->zig_target->arch == ZigLLVM_x86_64) { |
| 1887 | 1887 | X64CABIClass abi_class = type_c_abi_x86_64_class(g, ty); |
| 1888 | 1888 | size_t ty_size = type_size(g, ty); |
| 1889 | | if (abi_class == X64CABIClass_MEMORY) { |
| 1889 | if (abi_class == X64CABIClass_MEMORY || abi_class == X64CABIClass_MEMORY_nobyval) { |
| 1890 | 1890 | assert(handle_is_ptr(ty)); |
| 1891 | 1891 | switch (fn_walk->id) { |
| 1892 | 1892 | case FnWalkIdAttrs: |
| 1893 | | ZigLLVMAddByValAttr(llvm_fn, fn_walk->data.attrs.gen_i + 1, get_llvm_type(g, ty)); |
| 1894 | | addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty)); |
| 1893 | if (abi_class != X64CABIClass_MEMORY_nobyval) { |
| 1894 | ZigLLVMAddByValAttr(llvm_fn, fn_walk->data.attrs.gen_i + 1, get_llvm_type(g, ty)); |
| 1895 | addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty)); |
| 1896 | } else if (g->zig_target->arch == ZigLLVM_aarch64 || |
| 1897 | g->zig_target->arch == ZigLLVM_aarch64_be) |
| 1898 | { |
| 1899 | // no attrs needed |
| 1900 | } else { |
| 1901 | if (source_node != nullptr) { |
| 1902 | give_up_with_c_abi_error(g, source_node); |
| 1903 | } |
| 1904 | // otherwise allow codegen code to report a compile error |
| 1905 | return false; |
| 1906 | } |
| 1907 | |
| 1895 | 1908 | // Byvalue parameters must not have address 0 |
| 1896 | 1909 | addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull"); |
| 1897 | 1910 | fn_walk->data.attrs.gen_i += 1; |