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.
With the new available_externally emission into each referencing CU, the
enforced regular emission from the module members tree shouldn't be
required anymore.
After adapting the codegen/inlining_templates.d lit-test accordingly (no
IR definitions anymore in .ll file, because available_externally doesn't
make it there), I've noticed that a lambda in imported and inlined
call_enforce_with_default_template_params() wasn't emitted - it got
culled by alreadyOrWillBeDefined().
Function/delegate literals aren't culled anymore.
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.
Resolves#3245 by adding `pragma(lib, <name>)` library names to
`llvm.dependent-libraries` for ELF object files.
For Mach-O, embed appropriate linker options for `pragma(lib)` and
support generic `pragma(linkerDirective, <flag>, ...)` as well.
As RTInfoImpl contains unsupported global variables.
`object.RTInfo` is automatically instantiated by the front-end for each
aggregate starting with v2.085, incl. the special structs in the
`ldc.dcompute` module (representing pointers), so that dcompute was
basically totally broken.
Resolves#3009.
For -betterC and/or a minimal object.d without TypeInfo:
* Skip TypeInfo emission for classes and interfaces.
* Emit null as first vtable member.
Makes dmd-testsuite's {compilable,runnable}/minimal2.d work.
Don't attempt to emit the TypeInfo for each struct declaration. We skip
the IR emission later on for betterC anyway, but starting with 2.079,
the frontend emits an error when invoking genTypeInfo() in betterC mode.
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.
Postpone the destruction of replaced global variables, register them in
`IRState::globalsToReplace` and perform a second replacement pass when
finalizing the IR module. The globals will be destroyed in that 2nd pass,
so there may still be dangling pointers in `IrGlobal::value`, but now only
after writing the module.
The nicer thing would be replacing IrGlobal::value by IrGlobal::getValue()
which could look it up in IRState, but that's not feasible due to the
field being inherited from IrVar and IrGlobal apparently quite often being
used as IrVar (via pointers union), so the cached field is currently
required.
So the feasible options to me were either registering each IrGlobal with
its mangled name and replacing their values when swapping out the global
variable, or performing this second replacement pass right before
finalizing the IR module to make sure we really replace all occurrences.
I went for the latter as it's both easier and safer (from the LL
perspective as the old global might be cached somewhere else too).
Instead of letting our old copy silently go more and more out-of-sync.
In this case, we missed the upstream fix wrt. skipping the declaration of
ClassInfos for speculative class types.
There are 2 noteworthy functional changes for function
`getOrCreateTypeInfoDeclaration()`:
1) The old version always overwrote `torig->vtinfo` with `t->vtinfo` when
declaring a new TypeInfo, whereas upstream's `genTypeInfo()` only sets
it if it was null before.
2) The old version called `semanticTypeInfo()` during a semantic pass,
upstream doesn't.
The LDC-specific exception for class types in `builtinTypeInfo()` is still
required.
Fixes dmd-testsuite's runnable/b16278.d.
The part needing most attention was ddmd.root.ctfloat, ddmd.target (incl.
gen/target.cpp) and ddmd.builtin. The front-end is now prepared for
elaborate compile-time floating-point types to allow for proper cross-
compilation.
This version still uses the host's `real` type for compile-time reals,
except for MSVC hosts, which still use 64-bit doubles (when compiled with
DMD host compiler too).
Some other changes:
* semantic*() of Statements extracted from statement.d to statementsem.d
* mangle() -> mangleToBuffer()
* Identifier::string -> toChars()
* Token::float80value => floatvalue
* Dsymbol::isAggregateMember() => isMember()
* BoolExp is no more
* ddmd.root.ctfloat: LDC-specific CTFE builtins
Compatible with DMD, but restricted to Windows and functions only.
`export` functions with bodies get the dllexport attribute and will be
exported if the containing object is pulled in when linking.
Body-less `export` functions get the dllimport attribute and will be
accessed via an import table indirection, set up at runtime by the OS.
This is a temporary solution, the proper fix is a pending DMD PR, after
which LDC will need to be adapted.