And use `IrTypeClass::getVtblType()` to get the vtable LLVM array
type, instead of deriving it from the `IrClass::getVtblSymbol()`
global (invoking that function may define the vtable!).
I've hit some compiler crashes for the Symmetry code base, on
Windows only. I guess the problem surfaced due to
`-link-defaultlib-shared`, which on Windows causes some vtables of
instantiated classes to be defined whenever accessing the vtable
symbol. I don't have a reduced test case unfortunately.
Augment the type info for arrays to include the element type in addition to the array type as a second type-as-metadata MDNode.
Use this in place of looking up the element type from the array type
* Newly require `-link-defaultlib-shared` for implicit dllimport.
E.g., this enables to compile druntime DLL with `-fvisibility=public`
for pure exports and no (local) imports (such as builtin TypeInfos).
* `-link-defaultlib-shared` alone now only implicitly imports symbols
from druntime/Phobos.
This simplifies building complex DLLs linked against a bunch of
static libs (dub only supports static lib dependencies!); the static
libs don't need to be compiled with `-fvisibility=public` anymore
(if the DLL itself isn't either), `-link-defaultlib-shared` is
sufficient.
This is mainly useful for existing DLLs with explicit exports, to make
them link against *shared* druntime/Phobos and so end up with a single
druntime/Phobos for the whole process.
Init symbols, TypeInfos (classes only) & vtables - unless defined in a
root module. For explicitly exported aggregates, or, with
`-fvisibility=public`, all aggregates.
This fixes a new object.d unittest showing this pretty severe bug, which
appears to be a v1.25 regression. The `TypeInfo_Interface.info` field (a
TypeInfo_Class ref) pointed to its own TypeInfo_Interface (not derived
from TypeInfo_Class; simply bitcast) instead of the interface's
__InterfaceZ symbol.
I.e., *define* templated symbols in each referencing compilation unit
when using discardable linkonce_odr linkage, analogous to C++.
This makes each compilation unit self-sufficient wrt. templated symbols,
which also means increased opportunity for inlining and less need for
LTO. There should be no more undefined symbol issues caused by buggy
template culling.
The biggest advantage is that the optimizer can discard unused
linkonce_odr symbols early instead of optimizing and forwarding to the
assembler. So this is especially useful with -O to decrease compilation
times and can at least in some scenarios greatly outweigh the
(potentially very much) higher number of symbols defined by the glue
layer.
Libraries compiled with -linkonce-templates can generally not be linked
against dependent code compiled without -linkonce-templates; the other
way around works.
Don't store and check a back reference to the TypeInfo global.
The association is already unambiguously expressed by the metadata name
ending with the mangled name of the TypeInfo global.
Removing this check fixes a problem when replacing a TypeInfo global at
some point via IRState::setGlobalVarInitializer() (e.g., for the
rt.util.typeinfo unittests), because llvm::ValueAsMetadata doesn't fully
support LLVM's replace-all-uses-with.
Compiling the rt.util.typeinfo unittests leads to base-typed forward
declarations of built-in TypeInfos colliding with the init symbols for
their TypeInfo_* classes in rt.util.typeinfo.
We've already had a workaround for this in one place (typinf.cpp);
extend it to the other side as well (iraggr.cpp).
Also make sure to emit the TypeInfo metadata even if the IR symbol
already exists as init symbol.
And finally, keep init symbols of built-in TypeInfo classes mutable just
like any other TypeInfo, so that e.g. synchronized() can be used on the
implicit monitor.
I.e., not in their owning CU if unused therein, but in all referencing
CUs instead, as linkonce_odr. The special member functions are still
only and unconditionally emitted in the owning CU.
Analogous to ClassInfos, incl. normal linkage (external for non-
templates, weak_odr for templates).
This enables to get rid of frontend logic wrt. whether to add
TypeInfoStructDeclarations to a module's members tree - previously,
it was defined as linkonce_odr in the owning module and each referencing
module (unless speculative) - and related extra semantic and codegen for
the special member functions.
I've gone a bit further and moved the entire TypeInfo emission for LDC
to the codegen layer; no TypeInfoDeclarations are added to the module
members anymore. Whenever we need a TypeInfo symbol during codegen, it
is declared or defined, and we don't need to rely on brittle frontend
logic with speculative-ness complications.
This might slightly increase compilation speed due to less emitted
TypeInfos and functions (possibly less work for the linker too).
A slight drawback is that the job of stripping unused struct TypeInfos
is fully delegated to the linker, as the TypeInfo is guaranteed to end
up in the owning object file due to no linkonce_odr.
Another theoretical drawback is that the optimizer can definitely not
inline xtoHash/xopEquals/xopCmp/xtoString/xdtor[ti]/xpostblit function
pointer indirections in non-owning CUs without LTO (neither the pointers
nor the special member functions are defined anymore).
These (public) members are probably hardly used directly though, and
instead used by the virtual TypeInfo_Struct methods equals/compare/
getHash/destroy/postblit, which are exclusively defined in druntime's
object.o (incl. the TypeInfo_Struct vtable) and aren't cross-module-
inlined anyway (without LTO).
Re-emitting the struct TypeInfos (and optionally the special member
functions too) into each referencing CU could be handled in our codegen
layer, which should be much simpler and more robust than the upstream
scheme.
Surfacing now as #3486 added a corresponding assertion.
I've tested this with an older vibe-d v0.8.6 lying around on my box.
The assertion was hit for the TypeInfo of a nested struct:
3c7ae13989/http/vibe/http/router.d (L570-L574)
I wasn't able to quickly reduce it to a stand-alone testcase and am
reluctant to put any more effort into this.
I've also compared against the current DMD implementations, to make sure
we are in sync.
DMD doesn't populate `TypeInfo_Class.m_offTi` either. This seems like a
leftover of some unimplemented idea (the LDC commit introducing the
CMake option is from 2008); the normal `TypeInfo_Class.interfaces` array
contains the offsets nowadays.
Incl. getting rid of the dependence on an associated
TypeInfoStructDeclaration, which was only really needed for the mangled
name of the global.
Also slightly revise metadata generation.
Emulation for @weak global variables is still left out but should be
analogous.
The test adaptations are mostly a revert of 3893840f. The testcase has
shown that @weak hasn't worked properly for ELF (linker apparently
prefers the version in the 1st object file, independent of whether it's
weak or not), because the functions are emitted in COMDATs.
clang emits COMDATs for templates and inline functions only, not for
regular functions.
The TypeInfo may need an extern(D) wrapper accounting for ABI
differences wrt. extern(C++) dtor implementations.
This fixes `runnable/cppa.d` for 32-bit x86 targets.
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).
Use the real LL type representing the TypeInfo (sub)class directly and
from the beginning, i.e., already for the declaration, instead of
building an extra LL struct type (firstly opaque, then finalized when
defining the TypeInfo via RTTIBuilder).
To get this to work in all cases, the dummy TypeInfo for opaque structs
is now a complete TypeInfo_Struct, with all 11/13 fields zero-
initialized. Previously, it was a special TypeInfo (no extra
TypeInfo_Struct fields) with TypeInfo_Struct vtable, something which DMD
also emits.
Also refactor the RTTIBuilder finalize() interface - e.g., don't set the
linkage there (had to be reverted for ModuleInfos) and only take the
global variable to be defined. Cast the field initializers if required,
e.g., null pointers to appropriately typed function pointers for
TypeInfo_Struct etc.
Improve robustness for TypeInfos of speculative types by only eliding
their TypeInfo definition, not the declaration of the LL global
altogether.
`DtoTypeInfoOf()` expects the LL global to be created and otherwise
fails with an assertion or segfault (e.g., issue #2357). So now only
linker errors should result in case the TypeInfo definition is missing.
Also normalize the calls to `DtoTypeInfoOf()` and revise the following
pointer bitcasts, as the LL type of forward-declared TypeInfo globals
may be opaque.