@@ -852,6 +852,83 @@ private extern (C++) final class TypeSemanticVisitor : Visitor
852852
853853 override void visit (TypeDArray mtype)
854854 {
855+ /**
856+ * Returns a template declaration corresponding to the following code:
857+ *
858+ * ---
859+ * template __dslice(T) {}
860+ * ---
861+ *
862+ * Returns: a template declaration corresponding to the above code
863+ *
864+ * See_Also: `typeForCppMangling`
865+ */
866+ TemplateDeclaration dsliceTemplateDeclaration ()
867+ {
868+ __gshared TemplateDeclaration td;
869+
870+ if (td)
871+ return td;
872+
873+ auto ttp = new TemplateTypeParameter(loc, Id.p, null , null );
874+ auto parameters = new TemplateParameters(ttp);
875+
876+ return td = new TemplateDeclaration(loc, Id.__dslice, parameters,
877+ null , null );
878+ }
879+
880+ /**
881+ * Returns a template instantiation of the template declaration returned
882+ * by `dsliceTemplateDeclaration`.
883+ *
884+ * The template is instantiated with the element type of this array. For
885+ * an array of ints it would correspond to the following D code:
886+ * `__dslice!int`.
887+ *
888+ * Returns: a template instance
889+ *
890+ * See_Also: `dsliceTemplateDeclaration`
891+ * See_Also: `typeForCppMangling`
892+ */
893+ TemplateInstance dsliceTemplateInstance ()
894+ {
895+ auto tiargs = new Objects(mtype.next);
896+ auto ti = new TemplateInstance(loc, Id.__dslice, tiargs);
897+ ti.tempdecl = dsliceTemplateDeclaration();
898+
899+ return ti;
900+ }
901+
902+ /**
903+ * Returns the type that this array type should be treated as when it's
904+ * mangled as a C++ type.
905+ *
906+ * D arrays don't have any corresponding type in C++. Instead we mangle
907+ * it as a templated struct with the name `__dslice`, i.e.
908+ * `struct __dslice(T)`, where `T` is the element type of the array. For
909+ * an array of ints it would be mangled as the following type
910+ * `__dslice!int`.
911+ *
912+ * Returns: the type that this should be treated as when mangling as a
913+ * C++ type
914+ *
915+ * See_Also: `dsliceTemplateInstance`
916+ */
917+ Type typeForCppMangling ()
918+ {
919+ __gshared Type[char * ] cachedTypes;
920+ auto elementType = mtype.next;
921+
922+ if (auto type = elementType.deco in cachedTypes)
923+ return * type;
924+
925+ auto sd = new StructDeclaration(loc, Id.__dslice, false );
926+ sd.parent = dsliceTemplateInstance();
927+
928+ auto type = new TypeStruct(sd).typeSemantic(loc, sc);
929+ return cachedTypes[elementType.deco] = type;
930+ }
931+
855932 Type tn = mtype.next.typeSemantic(loc, sc);
856933 Type tbn = tn.toBasetype();
857934 switch (tbn.ty)
@@ -878,6 +955,8 @@ private extern (C++) final class TypeSemanticVisitor : Visitor
878955 }
879956 mtype.next = tn;
880957 mtype.transitive();
958+ mtype.typeForCppMangling = typeForCppMangling();
959+
881960 result = merge(mtype);
882961 }
883962
0 commit comments