This fixes an issue where any instantiation of TypeInfo in the final
output would lead to a cryptic error with no file or line information.
This change brings ldc in line with dmd's reporting of the same error,
which at least gives file and line information to discover the problem.
Replace the stack of IRScopes, each with its own IRBuilder, by directly
tampering with the state of a single IRBuilder.
This seems like the most feasible way to account for a breaking change
in LLVM 11, disallowing IRBuilder from being copied.
Fixes#3400. The frontend pre-casts the static array operand to the
slice type for cases like `bool[4] == bool[]`, but that's not possible
in case the static array is non-mutable but the slice type is mutable.
So check the element types for equivalence, not the array types, as
static arrays and slices are NOT equivalent.
This may negatively impact performance, as the (final, i.e.,
non-virtual) Expression::is... family is implemented in D and not
available inline in the C++ headers.
The `__ArrayCast` lowering isn't (always?) done when casting a static
array to a slice with different element size.
So exploit constant source lengths and compute the target length at
compile-time.
This fixes compilable/ldc_github_421.d - a float[16] can be cast to a
float4[] with constant length 4.
Cache length & ptr in DSliceValue, so that e.g. a pair constructed from
a constant length and some ptr keeps returning a constant length instead
of an extractvalue instruction every time the length is needed.
This enables checking for matching constant lengths when copying slices
and makes `test1()` in runnable/betterc.d work (memcpy instead of
_d_array_slice_copy call):
```
int[10] a1 = void;
int[10] a2 = void;
a1[] = a2[];
```
(more or less equivalent to `a1 = a2`, which is already optimized)
I.e., this fixes#2588.
To fix the index of the new array element to be assigned to, I went for
decrementing the new length instead of saving the old length directly
before the druntime call (i.e., after evaluating the rhs expression due
to its potential side effects). The IR seems more intuitive to me this
way - load both new length+ptr directly after the druntime call and then
decrement the length by 1.