Instructions now use friend APIs to add themselves into a
BasicBlock, rather than a BasicBlock having an API to add
the instructions.
Signed-off-by: Ikey Doherty <ikey@serpentos.com>
Init symbols, TypeInfos (classes only) & vtables - unless defined in a
root module. For explicitly exported aggregates, or, with
`-fvisibility=public`, all aggregates.
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.
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.
See https://llvm.org/bugs/show_bug.cgi?id=25162
However LLVM inliner now knows not to inline functions inside cleanup pads and so this is no longer needed. I have tested with clang (trunk) and clang also no longer marks function calls explicitly with noinline: the inliner no longer tries to inline `alwaysinline` functions.
The change is necesary because setting `noinline` conflicts with functions that have `alwaysinline` attribute added (due to `pragma(inline, true)`).
- do not inline functions into the cleanup funclets, it can break exception handling
- even if no var given, retrieve the caught exception to pass it to _d_eh_enter_catch