public override bool VisitClassDecl(Class @class) { var originalClass = @class.OriginalClass ?? @class; Type returnType = Context.ReturnType.Type.Desugar(); // if the class is an abstract impl, use the original for the object map var qualifiedClass = originalClass.Visit(typePrinter); var finalType = (returnType.GetFinalPointee() ?? returnType).Desugar(); Class returnedClass; if (finalType.TryGetClass(out returnedClass) && returnedClass.IsDependent) { Context.Return.Write($"({returnType.Visit(typePrinter)}) (object) "); } // these two aren't the same for members of templates if (Context.Function?.OriginalReturnType.Type.Desugar().IsAddress() == true || returnType.IsAddress()) { Context.Return.Write(HandleReturnedPointer(@class, qualifiedClass)); } else { if (Context.MarshalKind == MarshalKind.NativeField || Context.MarshalKind == MarshalKind.Variable || Context.MarshalKind == MarshalKind.ReturnVariableArray || !originalClass.HasNonTrivialDestructor) { Context.Return.Write($"{qualifiedClass}.{Helpers.CreateInstanceIdentifier}({Context.ReturnVarName})"); } else { Context.Before.WriteLine($@"var __{Context.ReturnVarName} = { qualifiedClass}.{Helpers.CreateInstanceIdentifier}({Context.ReturnVarName});"); Method dtor = originalClass.Destructors.First(); if (dtor.IsVirtual) { var i = VTables.GetVTableIndex(dtor); int vtableIndex = 0; if (Context.Context.ParserOptions.IsMicrosoftAbi) { vtableIndex = @class.Layout.VFTables.IndexOf(@class.Layout.VFTables.First( v => v.Layout.Components.Any(c => c.Method == dtor))); } string instance = $"new {typePrinter.IntPtrType}(&{Context.ReturnVarName})"; Context.Before.WriteLine($@"var __vtables = new IntPtr[] {{ { string.Join(", ", originalClass.Layout.VTablePointers.Select( x => $"*({typePrinter.IntPtrType}*) ({instance} + {x.Offset})"))} }};"); Context.Before.WriteLine($@"var __slot = *({typePrinter.IntPtrType}*) (__vtables[{ vtableIndex}] + {i} * sizeof({typePrinter.IntPtrType}));"); Context.Before.Write($"Marshal.GetDelegateForFunctionPointer<{dtor.FunctionType}>(__slot)({instance}"); if (dtor.GatherInternalParams(Context.Context.ParserOptions.IsItaniumLikeAbi).Count > 1) { Context.Before.Write(", 0"); } Context.Before.WriteLine(");"); } else { string suffix = string.Empty; var specialization = @class as ClassTemplateSpecialization; if (specialization != null) { suffix = Helpers.GetSuffixFor(specialization); } Context.Before.WriteLine($@"{typePrinter.PrintNative(originalClass)}.dtor{ suffix}(new {typePrinter.IntPtrType}(&{Context.ReturnVarName}));"); } Context.Return.Write($"__{Context.ReturnVarName}"); } } return(true); }