Fixes issue #1822.
DtoResolveFunction() explicitly excludes body-less abstract functions from
being automatically declared. If we want to emit linking errors like DMD,
we need a LL function for the call (we previously didn't for abstract
functions, so it was null and LDC crashed). Thus make sure the function is
resolved and declared by invoking DtoDeclareFunction().
The front-end fills in missing init expressions (except for the nested
context pointer in most cases), so there are no implicitly initialized
fields for dynamically initialized struct literals.
The front-end is also supposed to make sure there are no overlapping
initializers by using null-expressions for overridden fields, but doesn't
in some cases (DMD issue 16471).
Instead of preferring the first one in lexical field order, now use the
lexically last one to mimic DMD.
The previous code iterated over the fields in lexical order and ignored
the initializer for a field if there were earlier declared fields with
greater offset (and an initializer expression), which is wrong for
anonymous structs inside a union:
union {
struct { int i1; long l = 123; }
struct { int i2; int x = 1; }
}
`x` was previously initialized with 0 (treated as padding).
There's no <Type>_init type for aggregates (structs and classes) anymore,
effectively eliminating a *lot* of named LLVM types, some bitcasts as well
as replacements of globals etc.
To get there, it was even required to use the regular type for compatible
literals too, otherwise structs embedded as fields in other aggregates had
an anonymous type (well, the LLVM constant for the field initializer had)
and so the container initializer wasn't compatible with the regular type
anymore.
What was also necessary was a fix wrt. static arrays of bools (LLVM
constant of type `[N x i1]` vs. `[N x i8]` for regular type).
I also had to change the initializer for `char[2][3] x = 0xff` from
`[6 x i8]` to `[3 x [2 x i8]]`, i.e., NOT flattening multi-dimensional
inits from a scalar.
So only literals with overlapping (union) fields and an explicit
initializer initializing dominated non-alias union fields should still
have a mismatching anonymous type - i.e., very, very few cases.
By refactoring IrAggr::addFieldInitializers() and making it use an
extended and refactored AggrTypeBuilder::addAggregate().
AggrTypeBuilder::addAggregate() can now optionally detect alias fields
in unions (same offset and LL type as a dominant union field) and add
those to the variable-to-GEP-index mapping.
These alias fields can then be indexed directly with a GEP instead of
resorting to casting the pointer and applying the byte offset.
Approximate DMD behavior by naming the temporary object files uniquely
and, if successful, removing all generated object files.
Executables and shared libs imply -singleobj => no collisions.
Let LDC treat relative output paths as relative to the current working
directory again (as it always used to until a few weeks ago). It's more
intuitive and avoids breaking build systems/scripts using LDC directly.
Only LDMD continues to prepend the -od directory to the relative output
path, for DMD compatibility.
Fixes issue #1819.