diff --git a/InteropGenerator/Generator/InteropGenerator.Rendering.Inheritance.cs b/InteropGenerator/Generator/InteropGenerator.Rendering.Inheritance.cs index 3667f7afbc..aa0fe43ae0 100644 --- a/InteropGenerator/Generator/InteropGenerator.Rendering.Inheritance.cs +++ b/InteropGenerator/Generator/InteropGenerator.Rendering.Inheritance.cs @@ -98,7 +98,7 @@ private static void RenderInheritance(StructInfo structInfo, ImmutableArray presentVfuncOffsets = new(); + foreach (var vfunc in structInfo.VirtualFunctions) { + presentVfuncOffsets.Add(vfunc.Index); + } using (writer.WriteBlock()) { foreach ((StructInfo inheritedStruct, _, int offset) in resolvedInheritanceOrder) { // only inherited structs at offset 0 are the primary inheritance chain that make up the main virtual table if (offset != 0) continue; foreach (VirtualFunctionInfo virtualFunctionInfo in inheritedStruct.VirtualFunctions) { + // if the inherited vfunc has been redefined, skip it + if (presentVfuncOffsets.Contains(virtualFunctionInfo.Index)) + continue; + else + presentVfuncOffsets.Add(virtualFunctionInfo.Index); var functionPointerType = $"delegate* unmanaged <{structInfo.Name}*, {virtualFunctionInfo.MethodInfo.GetParameterTypeStringWithTrailingTypeNoGenerics()}{virtualFunctionInfo.MethodInfo.ReturnTypeOrVoid}>"; foreach (string inheritedAttribute in virtualFunctionInfo.MethodInfo.InheritableAttributes) writer.WriteLine(inheritedAttribute); @@ -219,6 +228,10 @@ private static void RenderInheritedVirtualTable(StructInfo structInfo, Immutable } private static void RenderInheritedDelegateTypes(StructInfo structInfo, ImmutableArray<(StructInfo inheritedStruct, string path, int offset)> resolvedInheritanceOrder, IndentedTextWriter writer) { + HashSet presentVfuncOffsets = new(); + foreach (var vfunc in structInfo.VirtualFunctions) { + presentVfuncOffsets.Add(vfunc.Index); + } writer.WriteLine("public static partial class Delegates"); using (writer.WriteBlock()) { foreach ((StructInfo inheritedStruct, _, int offset) in resolvedInheritanceOrder) { @@ -226,14 +239,28 @@ private static void RenderInheritedDelegateTypes(StructInfo structInfo, Immutabl if (offset != 0) continue; foreach (VirtualFunctionInfo virtualFunctionInfo in inheritedStruct.VirtualFunctions) { + // if the inherited vfunc has been redefined, skip it + if (presentVfuncOffsets.Contains(virtualFunctionInfo.Index)) + continue; + else + presentVfuncOffsets.Add(virtualFunctionInfo.Index); RenderDelegateTypeForMethod(structInfo.Name, virtualFunctionInfo.MethodInfo, writer); } } } } - private static void RenderInheritedVirtualFunctions(string childTypeName, StructInfo inheritedStruct, string path, int offset, IndentedTextWriter writer) { + private static void RenderInheritedVirtualFunctions(StructInfo structInfo, StructInfo inheritedStruct, string path, int offset, IndentedTextWriter writer) { + HashSet presentVfuncOffsets = new(); + foreach (var vfunc in structInfo.VirtualFunctions) { + presentVfuncOffsets.Add(vfunc.Index); + } foreach (VirtualFunctionInfo virtualFunctionInfo in inheritedStruct.VirtualFunctions) { + // if the inherited vfunc has been redefined, skip it + if (presentVfuncOffsets.Contains(virtualFunctionInfo.Index)) + continue; + else + presentVfuncOffsets.Add(virtualFunctionInfo.Index); MethodInfo methodInfo = virtualFunctionInfo.MethodInfo; if (offset != 0 && methodInfo.Name == "Dtor") continue; writer.WriteLine($"""/// """); @@ -247,7 +274,7 @@ private static void RenderInheritedVirtualFunctions(string childTypeName, Struct var paramNames = string.Empty; if (methodInfo.Parameters.Any()) paramNames = ", " + methodInfo.GetParameterNamesString(); - writer.WriteLine($"{methodInfo.GetDeclarationStringWithoutPartial()} => {virtualFunctionInfo.MethodInfo.ReturnTypeCast}VirtualTable->{methodInfo.NameNonGeneric}(({childTypeName}*)global::System.Runtime.CompilerServices.Unsafe.AsPointer(ref this){paramNames});"); + writer.WriteLine($"{methodInfo.GetDeclarationStringWithoutPartial()} => {virtualFunctionInfo.MethodInfo.ReturnTypeCast}VirtualTable->{methodInfo.NameNonGeneric}(({structInfo.Name}*)global::System.Runtime.CompilerServices.Unsafe.AsPointer(ref this){paramNames});"); } else { writer.WriteLine($"{methodInfo.GetDeclarationStringWithoutPartial()} => {path}.{methodInfo.Name}({methodInfo.GetParameterNamesString()});"); }