| ... | @@ -1847,51 +1847,64 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_ | ... | @@ -1847,51 +1847,64 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_ |
| 1847 | return true; | 1847 | return true; |
| 1848 | } | 1848 | } |
| 1849 | | 1849 | |
| 1850 | // Arrays are just pointers | 1850 | { |
| 1851 | if (ty->id == ZigTypeIdArray) { | 1851 | // Arrays are just pointers |
| 1852 | assert(handle_is_ptr(ty)); | 1852 | if (ty->id == ZigTypeIdArray) { |
| 1853 | switch (fn_walk->id) { | 1853 | assert(handle_is_ptr(ty)); |
| 1854 | case FnWalkIdAttrs: | 1854 | switch (fn_walk->id) { |
| 1855 | // arrays passed to C ABI functions may not be at address 0 | 1855 | case FnWalkIdAttrs: |
| 1856 | addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull"); | 1856 | // arrays passed to C ABI functions may not be at address 0 |
| 1857 | addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty)); | 1857 | addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull"); |
| 1858 | fn_walk->data.attrs.gen_i += 1; | 1858 | addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty)); |
| 1859 | break; | 1859 | fn_walk->data.attrs.gen_i += 1; |
| 1860 | case FnWalkIdCall: | 1860 | break; |
| 1861 | fn_walk->data.call.gen_param_values->append(val); | 1861 | case FnWalkIdCall: |
| 1862 | break; | 1862 | fn_walk->data.call.gen_param_values->append(val); |
| 1863 | case FnWalkIdTypes: { | 1863 | break; |
| 1864 | ZigType *gen_type = get_pointer_to_type(g, ty, true); | 1864 | case FnWalkIdTypes: { |
| 1865 | fn_walk->data.types.gen_param_types->append(get_llvm_type(g, gen_type)); | 1865 | ZigType *gen_type = get_pointer_to_type(g, ty, true); |
| 1866 | fn_walk->data.types.param_di_types->append(get_llvm_di_type(g, gen_type)); | 1866 | fn_walk->data.types.gen_param_types->append(get_llvm_type(g, gen_type)); |
| 1867 | break; | 1867 | fn_walk->data.types.param_di_types->append(get_llvm_di_type(g, gen_type)); |
| 1868 | } | 1868 | break; |
| 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); | | |
| 1879 | } | 1869 | } |
| 1880 | fn_walk->data.inits.gen_i += 1; | 1870 | case FnWalkIdVars: { |
| 1881 | break; | 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 | X64CABIClass abi_class = type_c_abi_x86_64_class(g, ty); | 1887 | X64CABIClass abi_class = type_c_abi_x86_64_class(g, ty); |
| 1888 | size_t ty_size = type_size(g, ty); | 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 | assert(handle_is_ptr(ty)); | 1890 | assert(handle_is_ptr(ty)); |
| 1891 | switch (fn_walk->id) { | 1891 | switch (fn_walk->id) { |
| 1892 | case FnWalkIdAttrs: | 1892 | case FnWalkIdAttrs: |
| 1893 | ZigLLVMAddByValAttr(llvm_fn, fn_walk->data.attrs.gen_i + 1, get_llvm_type(g, ty)); | 1893 | if (abi_class != X64CABIClass_MEMORY_nobyval) { |
| 1894 | addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty)); | 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 | // Byvalue parameters must not have address 0 | 1908 | // Byvalue parameters must not have address 0 |
| 1896 | addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull"); | 1909 | addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull"); |
| 1897 | fn_walk->data.attrs.gen_i += 1; | 1910 | fn_walk->data.attrs.gen_i += 1; |