| author | |
| committer | |
| log | 6b9dc82fa596ac2470810bfda53d61e2add93d33 |
| tree | 086194972af6204490b6f2604ef80a5e63232cbc |
| parent | 2b7781d82ad8d2234b89257676670957e005f214 |
| signature |
2 files changed, 72 insertions(+), 23 deletions(-)
src/stage1/analyze.cpp+55| ... | ... | @@ -1880,6 +1880,58 @@ ZigType *get_auto_err_set_type(CodeGen *g, ZigFn *fn_entry) { |
| 1880 | 1880 | return err_set_type; |
| 1881 | 1881 | } |
| 1882 | 1882 | |
| 1883 | // Sync this with get_llvm_cc in codegen.cpp | |
| 1884 | static Error emit_error_unless_callconv_allowed_for_target(CodeGen *g, AstNode *source_node, CallingConvention cc) { | |
| 1885 | Error ret = ErrorNone; | |
| 1886 | const char *allowed_platforms = nullptr; | |
| 1887 | switch (cc) { | |
| 1888 | case CallingConventionUnspecified: | |
| 1889 | case CallingConventionC: | |
| 1890 | case CallingConventionNaked: | |
| 1891 | case CallingConventionAsync: | |
| 1892 | break; | |
| 1893 | case CallingConventionInterrupt: | |
| 1894 | if (g->zig_target->arch != ZigLLVM_x86 | |
| 1895 | && g->zig_target->arch != ZigLLVM_x86_64 | |
| 1896 | && g->zig_target->arch != ZigLLVM_avr | |
| 1897 | && g->zig_target->arch != ZigLLVM_msp430) | |
| 1898 | { | |
| 1899 | allowed_platforms = "x86, x86_64, AVR, and MS430"; | |
| 1900 | } | |
| 1901 | break; | |
| 1902 | case CallingConventionSignal: | |
| 1903 | if (g->zig_target->arch != ZigLLVM_avr) | |
| 1904 | allowed_platforms = "AVR"; | |
| 1905 | break; | |
| 1906 | case CallingConventionStdcall: | |
| 1907 | case CallingConventionFastcall: | |
| 1908 | case CallingConventionThiscall: | |
| 1909 | if (g->zig_target->arch != ZigLLVM_x86) | |
| 1910 | allowed_platforms = "x86"; | |
| 1911 | break; | |
| 1912 | case CallingConventionVectorcall: | |
| 1913 | if (g->zig_target->arch != ZigLLVM_x86 | |
| 1914 | && !(target_is_arm(g->zig_target) && target_arch_pointer_bit_width(g->zig_target->arch) == 64)) | |
| 1915 | { | |
| 1916 | allowed_platforms = "x86 and AArch64"; | |
| 1917 | } | |
| 1918 | break; | |
| 1919 | case CallingConventionAPCS: | |
| 1920 | case CallingConventionAAPCS: | |
| 1921 | case CallingConventionAAPCSVFP: | |
| 1922 | if (!target_is_arm(g->zig_target)) | |
| 1923 | allowed_platforms = "ARM"; | |
| 1924 | } | |
| 1925 | if (allowed_platforms != nullptr) { | |
| 1926 | add_node_error(g, source_node, buf_sprintf( | |
| 1927 | "callconv '%s' is only available on %s, not %s", | |
| 1928 | calling_convention_name(cc), allowed_platforms, | |
| 1929 | target_arch_name(g->zig_target->arch))); | |
| 1930 | ret = ErrorSemanticAnalyzeFail; | |
| 1931 | } | |
| 1932 | return ret; | |
| 1933 | } | |
| 1934 | ||
| 1883 | 1935 | static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_scope, ZigFn *fn_entry, |
| 1884 | 1936 | CallingConvention cc) |
| 1885 | 1937 | { |
| ... | ... | @@ -2014,6 +2066,9 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc |
| 2014 | 2066 | fn_entry->align_bytes = fn_type_id.alignment; |
| 2015 | 2067 | } |
| 2016 | 2068 | |
| 2069 | if ((err = emit_error_unless_callconv_allowed_for_target(g, proto_node, cc))) | |
| 2070 | return g->builtin_types.entry_invalid; | |
| 2071 | ||
| 2017 | 2072 | if (fn_proto->return_anytype_token != nullptr) { |
| 2018 | 2073 | if (!calling_convention_allows_zig_types(fn_type_id.cc)) { |
| 2019 | 2074 | add_node_error(g, fn_proto->return_type, |
src/stage1/codegen.cpp+17-23| ... | ... | @@ -155,6 +155,7 @@ static const char *get_mangled_name(CodeGen *g, const char *original_name) { |
| 155 | 155 | } |
| 156 | 156 | } |
| 157 | 157 | |
| 158 | // Sync this with emit_error_unless_callconv_allowed_for_target in analyze.cpp | |
| 158 | 159 | static ZigLLVM_CallingConv get_llvm_cc(CodeGen *g, CallingConvention cc) { |
| 159 | 160 | switch (cc) { |
| 160 | 161 | case CallingConventionUnspecified: |
| ... | ... | @@ -164,38 +165,32 @@ static ZigLLVM_CallingConv get_llvm_cc(CodeGen *g, CallingConvention cc) { |
| 164 | 165 | case CallingConventionNaked: |
| 165 | 166 | zig_unreachable(); |
| 166 | 167 | case CallingConventionStdcall: |
| 167 | if (g->zig_target->arch == ZigLLVM_x86) | |
| 168 | return ZigLLVM_X86_StdCall; | |
| 169 | return ZigLLVM_C; | |
| 168 | assert(g->zig_target->arch == ZigLLVM_x86); | |
| 169 | return ZigLLVM_X86_StdCall; | |
| 170 | 170 | case CallingConventionFastcall: |
| 171 | if (g->zig_target->arch == ZigLLVM_x86) | |
| 172 | return ZigLLVM_X86_FastCall; | |
| 173 | return ZigLLVM_C; | |
| 171 | assert(g->zig_target->arch == ZigLLVM_x86); | |
| 172 | return ZigLLVM_X86_FastCall; | |
| 174 | 173 | case CallingConventionVectorcall: |
| 175 | 174 | if (g->zig_target->arch == ZigLLVM_x86) |
| 176 | 175 | return ZigLLVM_X86_VectorCall; |
| 177 | 176 | if (target_is_arm(g->zig_target) && |
| 178 | 177 | target_arch_pointer_bit_width(g->zig_target->arch) == 64) |
| 179 | 178 | return ZigLLVM_AArch64_VectorCall; |
| 180 | return ZigLLVM_C; | |
| 179 | zig_unreachable(); | |
| 181 | 180 | case CallingConventionThiscall: |
| 182 | if (g->zig_target->arch == ZigLLVM_x86) | |
| 183 | return ZigLLVM_X86_ThisCall; | |
| 184 | return ZigLLVM_C; | |
| 181 | assert(g->zig_target->arch == ZigLLVM_x86); | |
| 182 | return ZigLLVM_X86_ThisCall; | |
| 185 | 183 | case CallingConventionAsync: |
| 186 | 184 | return ZigLLVM_Fast; |
| 187 | 185 | case CallingConventionAPCS: |
| 188 | if (target_is_arm(g->zig_target)) | |
| 189 | return ZigLLVM_ARM_APCS; | |
| 190 | return ZigLLVM_C; | |
| 186 | assert(target_is_arm(g->zig_target)); | |
| 187 | return ZigLLVM_ARM_APCS; | |
| 191 | 188 | case CallingConventionAAPCS: |
| 192 | if (target_is_arm(g->zig_target)) | |
| 193 | return ZigLLVM_ARM_AAPCS; | |
| 194 | return ZigLLVM_C; | |
| 189 | assert(target_is_arm(g->zig_target)); | |
| 190 | return ZigLLVM_ARM_AAPCS; | |
| 195 | 191 | case CallingConventionAAPCSVFP: |
| 196 | if (target_is_arm(g->zig_target)) | |
| 197 | return ZigLLVM_ARM_AAPCS_VFP; | |
| 198 | return ZigLLVM_C; | |
| 192 | assert(target_is_arm(g->zig_target)); | |
| 193 | return ZigLLVM_ARM_AAPCS_VFP; | |
| 199 | 194 | case CallingConventionInterrupt: |
| 200 | 195 | if (g->zig_target->arch == ZigLLVM_x86 || |
| 201 | 196 | g->zig_target->arch == ZigLLVM_x86_64) |
| ... | ... | @@ -204,11 +199,10 @@ static ZigLLVM_CallingConv get_llvm_cc(CodeGen *g, CallingConvention cc) { |
| 204 | 199 | return ZigLLVM_AVR_INTR; |
| 205 | 200 | if (g->zig_target->arch == ZigLLVM_msp430) |
| 206 | 201 | return ZigLLVM_MSP430_INTR; |
| 207 | return ZigLLVM_C; | |
| 202 | zig_unreachable(); | |
| 208 | 203 | case CallingConventionSignal: |
| 209 | if (g->zig_target->arch == ZigLLVM_avr) | |
| 210 | return ZigLLVM_AVR_SIGNAL; | |
| 211 | return ZigLLVM_C; | |
| 204 | assert(g->zig_target->arch == ZigLLVM_avr); | |
| 205 | return ZigLLVM_AVR_SIGNAL; | |
| 212 | 206 | } |
| 213 | 207 | zig_unreachable(); |
| 214 | 208 | } |