@@ -497,6 +497,83 @@ private extern (C++) final class TypeSemanticVisitor : Visitor
497497
498498 override void visit (TypeDArray mtype)
499499 {
500+ /**
501+ * Returns a template declaration corresponding to the following code:
502+ *
503+ * ---
504+ * template __dslice(T) {}
505+ * ---
506+ *
507+ * Returns: a template declaration corresponding to the above code
508+ *
509+ * See_Also: `typeForCppMangling`
510+ */
511+ TemplateDeclaration dsliceTemplateDeclaration ()
512+ {
513+ __gshared TemplateDeclaration td;
514+
515+ if (td)
516+ return td;
517+
518+ auto ttp = new TemplateTypeParameter(loc, Id.p, null , null );
519+ auto parameters = new TemplateParameters(ttp);
520+
521+ return td = new TemplateDeclaration(loc, Id.__dslice, parameters,
522+ null , null );
523+ }
524+
525+ /**
526+ * Returns a template instantiation of the template declaration returned
527+ * by `dsliceTemplateDeclaration`.
528+ *
529+ * The template is instantiated with the element type of this array. For
530+ * an array of ints it would correspond to the following D code:
531+ * `__dslice!int`.
532+ *
533+ * Returns: a template instance
534+ *
535+ * See_Also: `dsliceTemplateDeclaration`
536+ * See_Also: `typeForCppMangling`
537+ */
538+ TemplateInstance dsliceTemplateInstance ()
539+ {
540+ auto tiargs = new Objects(mtype.next);
541+ auto ti = new TemplateInstance(loc, Id.__dslice, tiargs);
542+ ti.tempdecl = dsliceTemplateDeclaration();
543+
544+ return ti;
545+ }
546+
547+ /**
548+ * Returns the type that this array type should be treated as when it's
549+ * mangled as a C++ type.
550+ *
551+ * D arrays don't have any corresponding type in C++. Instead we mangle
552+ * it as a templated struct with the name `__dslice`, i.e.
553+ * `struct __dslice(T)`, where `T` is the element type of the array. For
554+ * an array of ints it would be mangled as the following type
555+ * `__dslice!int`.
556+ *
557+ * Returns: the type that this should be treated as when mangling as a
558+ * C++ type
559+ *
560+ * See_Also: `dsliceTemplateInstance`
561+ */
562+ Type typeForCppMangling ()
563+ {
564+ __gshared Type[char * ] cachedTypes;
565+ auto elementType = mtype.next;
566+
567+ if (auto type = elementType.deco in cachedTypes)
568+ return * type;
569+
570+ auto sd = new StructDeclaration(loc, Id.__dslice, false );
571+ sd.parent = dsliceTemplateInstance();
572+
573+ auto type = new TypeStruct(sd).typeSemantic(loc, sc);
574+ return cachedTypes[elementType.deco] = type;
575+ }
576+
500577 Type tn = mtype.next.typeSemantic(loc, sc);
501578 Type tbn = tn.toBasetype();
502579 switch (tbn.ty)
@@ -523,6 +600,8 @@ private extern (C++) final class TypeSemanticVisitor : Visitor
523600 }
524601 mtype.next = tn;
525602 mtype.transitive();
603+ mtype.typeForCppMangling = typeForCppMangling();
604+
526605 result = merge(mtype);
527606 }
528607
0 commit comments