I would never (ever) do this myself, but trying to understand
dmd, the code is absolutely packed with things like this:
extern(C++) class Package : ScopeDSymbol
{
...
override const(char)* kind() const
{
return "package";
}
...
override final inout(Package) isPackage() inout
{
return this;
}
...etc...
}
How exactly does that... work? Is the body of such a member
function written in the D Programming Language? Or is it some
weird hybrid of D and C++ that just has a human programmer brain
taking into account all the times that differing name mangling
might produce different code? I mean, Package.resolve for
instance is a non-trivial function. Can you not use templates
inside such a function? Can you only use other "extern(C++)"
types? Can you import from other modules, inside such a function?
The documents say nothing about this, only defining their
examples as stubs, like
extern(C++) class Foo {
void bar();
}
The documentation also avoids any memory allocation in D, instead
assuming C++ routines like createInstance to use malloc to
allocate the classes. But the code in dmd makes extensive use of
things like this:
extern(C++) ... {
final extern(D) this(...) { ... }
}
How would you create new objects of types that are declared
extern(C++)? Just new, and mark the constructor as extern(D)?
I realize DMD is a horrible program that was Frankensteined from
C++ code ages ago and is practically still C++ itself, and that
DMD has to have /full/ control of symbol mangling, but it is also
sort of important, not just as a D compiler, but as one of the
only programs left in the world that produces optimized assembly,
rather than passing it on to gcc or LLVM. So, understanding it is
kind of an interest of mine.