Whenever we need an IR function, we'd better make sure it exists. Handle
that in DtoCallee(), by invoking DtoDeclareFunction() by default,
instead of the previous DtoResolveFunction() + DtoCallee() combo.
DtoResolveFunction() usually declares the function, but somehow doesn't
for abstract and body-less functions.
Fixes#3490 by avoiding unnecessary extra key allocations for the literals cache etc.
Also gets rid of code duplication and improves IRState encapsulation.
It may likely show up as garbage, as it's not a real local variable
(allocated by caller, address mostly passed in a register); e.g., this
happens on Win64 with the VS debugger ('expression is not an address' or
something along these lines), but at least output *some* DI.
We may be able to fix this and similar issues with LLVM 7 and new
intrinsic llvm.dbg.addr().
There's a new need to access a class' vtable symbol, see dlang/dmd#8362.
Use it as alias to the actual vtable symbol with different type (dummy:
`i8*`, actual: `[N x i8*]`) and mangled name.
I tried matching the special symbol's mangled name and using an
appropriate static array front-end type for it, but then casting the
symbol address for the assignment leads to issues if the ctor is @safe.
So I decided to handle it in DtoSymbolAddress().
Unfortunately, this seems not to solve the extern(C++) issues exposed by
LDC self-compilation yet.
The AST now features special-ref result variables (storage classes:
ref, temp, result) after rewriting out contracts; from dmd/func.d:
/* out(id1) { statements1... }
* out(id2) { statements2... }
* ...
* becomes:
* out(__result) { { ref id1 = __result; { statements1... } }
* { ref id2 = __result; { statements2... } } ... }
*/
We are talking about the `id1` and `id2` variables here.
There's an existing assertion that we don't set a special-ref variable's
lvalue (T**) to the sret pointer (T*) which was already triggered when
compiling Phobos without unittests.
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).