Introduce callconv annotation#3977
Conversation
| else if (builtin.os == .windows) | ||
| // https://locklessinc.com/articles/keyed_events/ | ||
| else if (builtin.os == .windows) | ||
| // https://locklessinc.com/articles/keyed_events/ |
63252ce to
4fbe848
Compare
andrewrk
left a comment
There was a problem hiding this comment.
Some CCs are architecture specific, do we want to add a prefix to those (eg.
Fastcall->X86_Fastcall) ?
Makes sense to me, let's do it. For "fastcall" it is especially nice because I don't want people to be confused and think "fastcall" is actually somehow "faster", it's more like "quicksort" is to sorting. So it's nice to have the architecture there to imply that this is a calling convention, not a performance thing.
Right now we "group" all the CCs under the same name (eg. AVR interrupt & X86 interrupt are both under the
Interruptentry) and are chosen according to the target architecture. Is this ok or do we want to split them into independent entities?
Hmm, good question. I really can't think of a reason to favor one or the other. With "C calling convention" we already have precedent for a calling convention that means different things on different architecture, so "interrupt" meaning "the architecture's native interrupt calling convention" seems reasonable to me. I defer to your judgment on this one.
This PR is already close enough to mergeable that I would feel comfortable with a hand-off. So let me know when you're done with it, and I'll make sure it lands swiftly in master branch.
| const char *cc_str = calling_convention_fn_type_str(fn_type->data.fn.fn_type_id.cc); | ||
| buf_appendf(&fn_type->name, "%s", cc_str); | ||
| if (fn_type->data.fn.fn_type_id.cc == CallingConventionC) | ||
| buf_append_str(&fn_type->name, "extern "); |
There was a problem hiding this comment.
I was thinking we could drop extern for the C calling convention, once we have callconv. Any reason to keep using extern for C calling convention functions?
There was a problem hiding this comment.
Decoupling extern from the CC is definitely a good idea, I tried not to change the status quo too much in this PR so I think I'll leave the breaking changes to you :)
| bool is_nakedcc; | ||
| bool is_stdcallcc; | ||
| bool is_async; |
There was a problem hiding this comment.
Feel free to delete nakedcc and stdcallcc keywords from stage1. (If you don't do it, I'll do it.) I'm happy to tell people to use the auto-fixing you added to zig fmt in order to upgrade code to the latest version.
I'll open a separate proposal to remove support for async fn in favor of callconv(.Async) for uniformity.
There was a problem hiding this comment.
Ditto, if you want to drop nakedcc and stdcallcc in this release cycle go for it! The less legacy cruft the better.
| if (field_type == nullptr) { | ||
| struct_type->data.structure.resolve_status = ResolveStatusInvalid; | ||
| return err; | ||
| return ErrorSemanticAnalyzeFail; |
src/codegen.cpp
Outdated
| case CallingConventionVectorcall: | ||
| if (g->zig_target->arch == ZigLLVM_x86) | ||
| return LLVMX86VectorCallCallConv; | ||
| // XXX Enable this when the C API exports this enum member too |
There was a problem hiding this comment.
We should work around this with zig_llvm.h/zig_llvm.cpp. The official LLVM C API always lags behind the C++ API.
In fact:
Lines 74 to 75 in 86ba8c0
Lines 275 to 297 in 86ba8c0
Looks like all we're missing is a copy-paste of LLVM's calling convention enum, with some static_asserts in zig_llvm.cpp to make sure the values don't change. See src/zig_clang.cpp for inspiration.
There was a problem hiding this comment.
I've sent a patch that hopefully will get in by the time LLVM 10 is out. But moving away from the C API is also a good idea.
LemonBoy
left a comment
There was a problem hiding this comment.
Makes sense to me, let's do it. For "fastcall" it is especially nice because I don't want people to be confused and think "fastcall" is actually somehow "faster", it's more like "quicksort" is to sorting. So it's nice to have the architecture there to imply that this is a calling convention, not a performance thing.
If we go for the prefix route then we should also split the common CCs (Vectorcall becomes X86_Vectorcall and AArch64_Vectorcall, same for Interrupt and so on). IMO it's fine to leave the enums un-prefixed and merged with some hints in the documentation about what to expect.
👍 |
|
This is ready to go on my end, I'll send a follow-up PR to make |
Returning the uninitialized/stale error condition made the compiler turn a blind eye to some problems.
Done according to the accepted proposal,
zig fmthas been patched up to use the new notation when possible and the whole stdlib has been already updated.A few new calling conventions have been introduced, you can now write your interrupt handlers (for x86 & AVR) with pure Zig code.
Missing:
translate-c-2Not critical but possibly wanted:
export/extern/callconvcombinationsA few open questions:
Fastcall->X86_Fastcall) ?Interruptentry) and are chosen according to the target architecture. Is this ok or do we want to split them into independent entities?I'm submitting this as-is to see if the CI is green,
in case this is merged please rebase it.Closes #661