Init symbols, TypeInfos (classes only) & vtables - unless defined in a
root module. For explicitly exported aggregates, or, with
`-fvisibility=public`, all aggregates.
As *the* way to access the IrType associated with a Type via its `ctype`
field. Most importantly, it makes sure all access is redirected to the
*unqualified* type's `ctype`, which allows to get rid of the 'multiple
types' workaround for aggregates in DtoType(). Those were e.g. hit for
`shared struct SpinLock`, where the struct's type includes the `shared`
modifier...
As reported in https://github.com/ldc-developers/ldc/issues/3501#issuecomment-661551187.
Previously, LDC would simply override an existing TypeDescriptor global
with an equivalent definition if assertions were disabled.
Use different equivalent TypeDescriptors in this exotic case now, by
using proper mangling. [The linker can presumably still fold duplicates
via ICF.]
Ideally, these descriptors would be truly unique, but WinEH depends on
string comparisons to check for matching catch clauses, and currently
depends on TypeInfo_Class.name to generate these strings at runtime when
throwing an exception, see
19731a92a9/src/ldc/eh_msvc.d (L192-L211).
So if those names were fully qualified (`cd->toPrettyChars(*true*)`
during ClassInfo generation), we'd be fine, but that'd obviously be a
breaking change and diverge from upstream.
LLVM already provides suited RAII helper types to restore the IRBuilder
state. [They sadly aren't movable, so I've had to wrap them in a
unique_ptr.]
While at it, also minimally revise debuginfo generation for functions.
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.
Making it obvious which of the two operations is performed, reducing
call args and making sure a global isn't defined multiple times via
`defineGlobal()`.
The only [intended] functional change is in gen/trycatchfinally.cpp,
where I inserted a check for an existing __cpp_type_info_ptr global when
emitting a catch for C++ exceptions.
Not all type declarations yet (e.g., some TypeInfo subtypes are still
accessed directly), but those already wrapped as LazyType in the
gen/runtime.cpp module (with check and proper error msg in case object.d
doesn't contain a required declaration).
This fixes the 32-bit std.file unittests on Linux with enabled
optimizations. Quoting the SysV ABI docs:
> This is the only routine in the unwind library which is expected to be
> called directly by generated code: it will be called at the end of a
> landing pad in a "landing-pad" model.
The remaining LDC-specific ARM EABI wrapper (_d_eh_resume_unwind()) is
implemented in assembly (ldc/eh_asm.S), preserving registers apparently.
Previously assuming in the personality routine that encountering a C++ exception meant that catch clauses were raw std::type_info pointers was wrong in cases like:
try {
throwStdException(); // external C++ function throwing a std::exception
} catch (Throwable t) {
(...)
}
Generated __cpp_type_info_ptr constants receive the same mangling that they do within DMD.
Running a cleanup with a dummy target BB and later replacing all uses of
that dummy with the actual BB is buggy, as the cleanup keeps track of its
exit targets (via pointers) which aren't updated.