The semantics were almost identical, except for DtoIsTemplateInstance()
checking the specified Dsymbol and its parents, while isInstantiated()
starts from its parent and ignores the symbol itself.
After a quick glance, we seem to have fed it with {Aggregate,Func,Var}
Declarations only, so should be fine with the default front-end variant.
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.
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.
Which supports more cmdline options in the meantime than what we have
been supporting manually, and should be future-proof, similar to
InitTargetOptionsFromCodeGenFlags().
Attributes are only set if explicitly specified in the cmdline (and not
already present in the function's existing attributes).
This started out as a workaround for not being able to determine whether
the user has explicitly set -frame-pointer in the cmdline with LLVM 11,
and ended with having to touch more than I wanted. An *enabled*
-ffast-math flag (from us, not LLVM) overriding LLVM's
-enable-unsafe-fp-math, but e.g. -ffast-math=false NOT overriding was/is
one of the quirks.
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.
This is exactly what happened for the 4 problematic delegate literals
for the Phobos unittests - DtoDefineFunction(fd) could result in that
definition ending up as available_externally - all done as part of
DtoResolveFunction(), which declared it, and DtoDeclareFunction()
defined it as available_externally, and the outer DtoDefineFunction()
returned early in that case without fixing up the linkage.
Previously, the logic gave up early if semantic3 was run for the
function to be inlined, either because the function is going to be
codegen'd in some root module, or because sema3 was already run for an
available_externally 'copy' in a previous compilation unit.
This restricted a function to being defined in at most one compilation
unit per ldc2 invocation.
So e.g. a little `pragma(inline, true)` wrapper in druntime wasn't
inlined into other druntime modules, because the whole lib is built in a
single cmdline by default, and sema3 was obviously run for the actual
emission in the corresponding object file.
When later compiling Phobos in a single cmdline, only the first object
file referencing the wrapper got lucky, running sema3 manually and
getting an available_externally 'copy'.
This patch gives new option which avoids the PLT and lazy binding while
making external calls.
Implementation inspired by `-fno-plt` support to Clang.
Clang's patch: https://reviews.llvm.org/D39079
Their IrParameter isn't created as part of DtoDeclareFunction(). Before
being able to handle that later in defineParameters() (as part of
defining the function), DtoCreateNestedContextType() steps in and
creates an IrLocal if not already created.
1) Create an IrParameter in that case in DtoCreateNestedContextType().
2) Handle these new value-less (no LL param) IrParameters in
defineParameters().
3) Fix the iOS AArch64 ABI, as apparently not all empty structs are
ignored for parameter passing, but only POD ones.
Also don't ignore anything passed by reference.
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.
* Extend the error message, closely following DMD. Tested by
fail_compilation/fail5634.d.
* Check across all compiled modules, not on a per-object-file basis.
That's what DMD does too.
* Apply the implicit `return 0` / void -> int return type promotion to
all D/C main functions, not just the first one. This prevents some
potential follow-up crashes.
E.g., this disables it for __entrypoint.d (the C main function(s) in
there), which is required.
A wmain on Windows is not detected as FuncDeclaration.isCMain() yet,
that should be fixed too.