On Wednesday, 27 March 2013 at 21:28:42 UTC, Moritz Maxeiner
wrote:
Yes it is intended to be that way. Regarding the reasons for
that decision:
Short answer:
Because in the case of the LLVM C API it makes things a lot
easier and simpler to maintain, as well as trivial to add new
parts for new LLVM versions.
Long answer:
1) The LLVM C API has headers which have very few lines of
actual code (e.g. Linker.h which only contains one enum and one
functions), making those into D modules seems wasteful.
2) Over versions of the LLVM C API headers appear and
dissappear (e.g. Linker.h exists since 3.2,
EnhancedDissassembly.h has been removed in trunk 3.3) and
having them all around as D modules makes maintenence a lot
more complicated.
3) Having all functions in a single compile time enum makes the
runtime loading process a lot easier as you can generate all
three steps ( 1. function pointer alias for every C function 2.
function pointer variable for every function pointer alias 3.
loading of the shared lib symbol into the function pointer for
every function pointer) with but a few lines of codes, instead
of having to write the names of all C functions three times.
And since you can encode more information in that enum (an
associative array in this case) adding more function is
trivial: Simply add the function to the array in this manner:
"NAME" : ["SIGNATURE", "+", "VERSION"] and that's it (and if
the function has been removed in said VERSION, change "+" into
"-"). Since the MixinMap template (a CTFE version of the map
function designed to get an array as its list and create D code
for each of the items of said array based on a delegate
function f) is used for the three steps described above no
further code is needed.
TLDR: Supporting different versions of the LLVM C API takes
considerably less effort this way and if there is a
disadvantage to this approach big enough to outweigh that I
can't see it.
Ok, that sound reasonable.
Second question, why do you do stuff like :
enum Foo {
FooA,
FooB,
FooC,
}
when you would do
enum Foo {
A,
B,
C,
}
?
D enums introduce a scope, when C's don't. So C need to prefix
enums entries manually, when in D it isn't required. The C to D
translation goes as follow : FooA => Foo.A instead of Foo.FooA .
If the goal isn't to follow LLVM's source as closely as possible,
I think this is the way to go.