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.

Reply via email to