Also adds the CMake infrastructure to compile and link the D source files.
The build is partially broken:
- A few files in Phobos and druntime do not build
- MSVC build is broken because of unresolved symbols involving reals
Now with *almost* working EH codegen. Does not compile Phobos yet
because we run into the "instruction does not dominate all uses"
issue when an r-value result of toElemDtor is used and we need to
run cleanups in between. Should easily be fixed by promoting those
values to allocas.
Most of the changes outside of ir/irfunction.{h, cpp} are just
because CreateCallOrInvoke moved locations. I took the
opportunity to also make use of the different arg count
overloads where possible.
Never generates any landing pads or invoke instructions right now
for simplicity. The code for emitting them will be added back in
the next step.
The "after..." blocks without any precedessors remain for now, as
we need a clean way to suppress any codegen for that block (but
not new blocks, which might resolve labels) before tackling that
one.
Builds druntime/Phobos on OS X x86_64 (albeit without EH, of course).
Specifying the basic block before which to insert the new one
is not mandatory when calling llvm::BasicBlock::Create. This
was the only use of the tracked "end" block. The concept was
phony anyway because there is no single "end" to a scope with
unwinding and so on.
For prettying up the IR, it is possible to change the order
of basic blocks using move{Before, After}().
A lot of system specific knowledge is already present in LLVM. This is used to populate several fields in global.params instead of hard coded values in main(). Ensures that the frontend and LLVM have always the same values.
This is based on Item 2 of "More Effective C++". In general, the C++ cast operators are more expressive and easy to find,
e.g. by grep. Using const_cast also shuts up some compiler warnings.
On OS X, there is an actual significance to the distinction, which before lead e.g. to exception throwing in the below example being broken:
---
import core.exception;
void main() {
asm {
jmp Lfoo;
Lfoo:
;
}
throw cast(OutOfMemoryError)cast(void*)OutOfMemoryError.classinfo.init;
assert(0);
}
---
1) The last parameter of getGetElementPtr() has type bool. In some instances, a 2 is used as parameter. This is converted to true.
2) Several loops use int instead of unsigned. This causes warning about signed/unsigned mismatch.
Curiously, only Visual C++ complains about this. Nevertheless I think that the warnings should be fixed.