Don't attempt to store past the end of alloca()ted memory.
This is important for structs passed in registers whose size
is not a power of 2.
Fix: alloca()te another sufficiently sized chunk, store into
it and then memcpy() the relevant bytes to the target chunk.
Ignore pointer type mismatches as long as both types are pointers;
the element type has no effect on the memory layout.
The RegCount constructor had to be improved to handle more complex
types correctly (e.g., nested structs such as { { i64, i32* } }) as
these are not rewritten anymore.
Debug unittests: only std.range-debug failing.
Not allowing dynamic arrays to be split seems to have fixed
std.stream-debug and also works for dynamic-array varargs crossing the
registers/stack boundary and extracted using core.vararg.va_arg!T().
Not sure about associative arrays and delegates yet. Delegates cannot
be rewritten using ExplicitByvalRewrite; that triggers type mismatches
somewhere.
I had another look at the official ABI specs and fixed some issues of
our classify()-based version, e.g.:
* upper half X87Up, but lower half not X87
=> pass whole argument in memory
* choose a fitting (integer/struct) type for structs/static arrays of
sizes 3,5,6,7,11,13,14,15 bytes
In case of a ctor `this` is passed to the function and is also the
return value. This is the perfect case for the `Returned` attribute.
But the x86_64 ABI missed the fact that the return value was a pointer
to a struct and did a struct rewrite, resulting in an bitcast
incompatible type.
1. Main include corresponding to .cpp file, if any.
2. DMD and LDC includes.
3. LLVM includes.
4. System includes.
Also updated a few include guards to match the default format.
On x86_64, a proper solution (see GitHub #120) is still needed,
but this will have to wait until the special case for extern(D)
is gone from the implementation.
We need this right now as std.digest.md in 2.061 triggers a
miscompilation issue in the LLVM x86 backend (not the optimizer!)
when returning them directly as LLVM arrays.
The solution is to replace Attribute with AttrBuilder in IrFuncTyArg.
Then the argument attributes can be easily manipulated and transformed
into the final AttributeSet.
This is based on Item 2 of "More Effective C++". In general, the C++ cast operators are more expressive and easy to find,
e.g. by grep. Using const_cast also shuts up some compiler warnings.