I've started digging at some surfac-ey extern(C++) issues. First up, I desperately want a document that describes D's precise construction/destruction rules; there are a bunch of generated functions, they get called, in what order, and under what conditions?
Construction: What is the order of operations? Where and when is init applied before calling constructors? What about super-constructors? Aggregate member constructors? When are where-from are they called? Is this all wrapped in an outer '__xctor' function that does the whole job? Is it all rolled into __ctor? Or is it just a bunch of loose operations that appear at the call-site? I want a function that wraps initialisation, super construction, aggregate construction, and local construction; similar to __xdtor is for destruction. That function would match C++, and that would be the logical point of interaction with C++ (mangling). Destruction: What's the precise story with __dtor, __xdtor, __fieldDtor? Is __xdtor **always** present? extern(C++) seems to have bugs(?) with __xdtor... Is re-initialisation to 'init' part of destruction, or is it a separate post-process? (I feel it's a post-process) Regarding extern(C++), I've started with trying to mangle correctly, but then next will come trying to match C++ semantics. Issue 1: extern(C++) classes have broken __xdtor. I observe extern(C++) classes with no destructor will generate an __xdtor that correctly calls aggregate destruction. If you then add a destructor (__dtor), __xdtor will call that function directly (or maybe it just becomes an alias?), and aggregate destruction will no longer occur. Issue 2: assuming the above is fixed, __xdtor matches C++ expectation for destruction. I intend to change the mangling such that __xdtor mangles as the C++ symbol, and not __dtor. Issue 3: If the user specifies an extern(C++) destructor *prototype* with no implementation (ie, extern link to C++ destructor), it needs a hack to re-interpret as a prototype for an extern __xdtor, rather than __dtor (and __dtor can happily not exist, or just alias). C++ destructors perform a full-destruction, which is equivalent to __xdtor from D's perspective. That should lead to destruction semantics matching C++. Matching construction semantics is a little bit fiddly too. It might need special-casing. D doesn't seem to wrap up a full construction into a single nice function like C++ does... or does it? I'm struggling to understand D construction from end-to-end. Let's not talk about passing by-val... yet.