This patch introduces the "darwin_abi" function attribute, to be able to compile functions for the Apple ARM64 ABI when targeting other ARM64 OSes. For now, only Linux/ARM64 is supported/tested.
I explained the motivation behind this and some limitations in this mail on llvm-dev: http://lists.llvm.org/pipermail/llvm-dev/2020-October/145680.html . Please note that, in this mail, I call this attribute "apple_abi". I decided to change it to "darwin_abi", because everything Apple-related is called "darwin" in clang/llvm. That being said, I don't have any strong opinion on this, and will be willing to hear any argument in favoir of one or the other.
It does not allow to target all the differences that exist in the Darwin ARM64 ABI against the standard AAPCS one (see [1] for the exhaustive list).
What I beleive is implemented:
- targeting the Darwin AAPCS ABI for C functions, especially those with variadic arguments. This means everything in section "Pass Arguments to Functions Correctly" and "Update Code that Passes Arguments to Variadic Functions" in [1].
- "The ABI requires the complete object (C1) and base-object (C2) constructors to return this to their callers. Similarly, the complete object (D1) and base-object (D2) destructors return this. This behavior matches the ARM 32-bit C++ ABI." (quoting [1]). I am not sure this would be useful to anyone, but that was not that hard to implement it, so I put it. The C++ support isn't complete in this patch though (see below), so maybe it's better to remove it.
- "When passing parameters to a function, Apple platforms ignore empty structures unless those structures have a nontrivial destructor or copy constructor. When passing such nontrivial structures, treat them as aggregates with one byte member in the generic manner." (quoting [1])
- properly forwarding variadic arguments from a "darwin_abi function" to a linux one using va_list, by zeroing the relevant fields in the linux va_list structure to make sure only stack arguments will be used (cf. discussions in the aforementioned ML thread)
What isn't implemented and isn't supported (quoting [1]):
- "The ABI provides a fixed layout of two size_t words for array cookies, with no extra alignment requirements. This behavior matches the ARM 32-bit C++ ABI." => this would require allowing the "darwin_abi" to be set on class types, and I think the overall feature would make a non-trivial patch. I prefer doing the C ABI right and eventually implement this afterwards.
- "A pointer to a function declared as extern “C” isn’t interchangeable with a function declared as extern “c++”. This behavior differs from the ARM64 ABI, in which the functions are interchangeable." => I'm not sure to find where this is tested in clang, let alone this would be possible to be tested.
- My understanding is that we should keep the Itanium mangling, even for functions with the "darwin_abi" attributes, so I didn't implemented the mangling differences. For instance, if I understood correctly, setting the "ms_abi" on a C++ function doesn't use the MSVC mangling.
- Everything remaining in the "Handle C++ Differences" section in [1]
[1] https://developer.apple.com/documentation/xcode/writing_arm64_code_for_apple_platforms for reference
I suspect this should be using the Clang spelling as I don't believe GCC supports this attribute.