@@ -524,6 +524,24 @@ extern (C++) abstract class Type : RootObject
524524 return DYNCAST .type;
525525 }
526526
527+ /**
528+ * Returns the type the receiver should be treated as during mangling.
529+ *
530+ * This allows for a type to be treated as a different type during mangling.
531+ * This is useful, for example, when interfacing with C++, for D types that
532+ * don't have a corresponding C++ type. This can allow `int[]` to be
533+ * mangled as `__dslice!int` during C++ mangling.
534+ *
535+ * Params:
536+ * linkage = the type of mangling that is requested
537+ *
538+ * Returns: the type the receiver should be treated as during mangling
539+ */
540+ Type typeForMangling (LINK linkage)
541+ {
542+ return this ;
543+ }
544+
527545 /* ******************************
528546 * Covariant means that 'this' can substitute for 't',
529547 * i.e. a pure function is a match for an impure type.
@@ -3728,6 +3746,9 @@ extern (C++) final class TypeSArray : TypeArray
37283746 */
37293747extern (C++ ) final class TypeDArray : TypeArray
37303748{
3749+ // / Mangle D array as this type when mangling for C++.
3750+ private Type typeForCppMangling;
3751+
37313752 extern (D ) this (Type t)
37323753 {
37333754 super (Tarray, t);
@@ -3752,6 +3773,88 @@ extern (C++) final class TypeDArray : TypeArray
37523773 return t;
37533774 }
37543775
3776+ override Type typeForMangling (LINK linkage)
3777+ {
3778+ /**
3779+ * Returns a template declaration corresponding to the following code:
3780+ *
3781+ * ---
3782+ * template __dslice(T) {}
3783+ * ---
3784+ *
3785+ * Returns: a template declaration corresponding to the above code
3786+ *
3787+ * See_Also: `typeForCppMangling`
3788+ */
3789+ static TemplateDeclaration dsliceTemplateDeclaration ()
3790+ {
3791+ __gshared TemplateDeclaration td;
3792+
3793+ if (td)
3794+ return td;
3795+
3796+ auto ttp = new TemplateTypeParameter(Loc.initial, Id.p, null , null );
3797+ auto parameters = new TemplateParameters(ttp);
3798+
3799+ return td = new TemplateDeclaration(Loc.initial, Id.__dslice, parameters,
3800+ null , null );
3801+ }
3802+
3803+ /**
3804+ * Returns a template instantiation of the template declaration returned
3805+ * by `dsliceTemplateDeclaration`.
3806+ *
3807+ * The template is instantiated with the element type of this array. For
3808+ * an array of ints it would correspond to the following D code:
3809+ * `__dslice!int`.
3810+ *
3811+ * Returns: a template instance
3812+ *
3813+ * See_Also: `dsliceTemplateDeclaration`
3814+ * See_Also: `typeForCppMangling`
3815+ */
3816+ TemplateInstance dsliceTemplateInstance ()
3817+ {
3818+ auto tiargs = new Objects(next);
3819+ auto ti = new TemplateInstance(Loc.initial, Id.__dslice, tiargs);
3820+ ti.tempdecl = dsliceTemplateDeclaration();
3821+
3822+ return ti;
3823+ }
3824+
3825+ /**
3826+ * Returns the type that this array type should be treated as when it's
3827+ * mangled as a C++ type.
3828+ *
3829+ * D arrays don't have any corresponding type in C++. Instead we mangle
3830+ * it as a templated struct with the name `__dslice`, i.e.
3831+ * `struct __dslice(T)`, where `T` is the element type of the array. For
3832+ * an array of ints it would be mangled as the following type
3833+ * `__dslice!int`.
3834+ *
3835+ * Returns: the type that this should be treated as when mangling as a
3836+ * C++ type
3837+ *
3838+ * See_Also: `dsliceTemplateInstance`
3839+ */
3840+ Type typeForCppMangling ()
3841+ {
3842+ __gshared Type[char * ] cachedTypes;
3843+ auto elementType = next;
3844+
3845+ if (auto type = elementType.deco in cachedTypes)
3846+ return * type;
3847+
3848+ auto sd = new StructDeclaration(Loc.initial, Id.__dslice, false );
3849+ sd.parent = dsliceTemplateInstance();
3850+
3851+ auto type = new TypeStruct(sd).typeSemantic(Loc.initial, null );
3852+ return cachedTypes[elementType.deco] = type;
3853+ }
3854+
3855+ return linkage == LINK .cpp ? typeForCppMangling() : this ;
3856+ }
3857+
37553858 override d_uns64 size (const ref Loc loc) const
37563859 {
37573860 // printf("TypeDArray::size()\n");
0 commit comments