From 5e0e19ea18a13d0c6fccff901fc10624ff8e0801 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Wed, 23 Jan 2019 00:03:25 +0200 Subject: [PATCH] Fixed the generation of dependent virtual methods. Signed-off-by: Dimitar Dobrev --- .../Generators/CSharp/CSharpSources.cs | 19 +++++++++++++++---- tests/CSharp/CSharp.Tests.cs | 15 ++++++++++----- tests/CSharp/CSharpTemplates.h | 7 +++++++ 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/Generator/Generators/CSharp/CSharpSources.cs b/src/Generator/Generators/CSharp/CSharpSources.cs index 42ebeb36..ea56bb16 100644 --- a/src/Generator/Generators/CSharp/CSharpSources.cs +++ b/src/Generator/Generators/CSharp/CSharpSources.cs @@ -424,7 +424,7 @@ namespace CppSharp.Generators.CSharp var dict = $@"global::System.Collections.Concurrent.ConcurrentDictionary"; WriteLine("internal static readonly {0} NativeToManagedMap = new {0}();", dict); - WriteLine("protected void*[] __OriginalVTables;"); + WriteLine("protected internal void*[] __OriginalVTables;"); } PopBlock(NewLineKind.BeforeNextBlock); } @@ -2272,7 +2272,10 @@ namespace CppSharp.Generators.CSharp public override void GenerateMethodSpecifier(Method method, Class @class) { - if (method.IsVirtual && !method.IsGeneratedOverride() && !method.IsOperator && !method.IsPure) + bool isTemplateMethod = method.Parameters.Any( + p => p.Kind == ParameterKind.Extension); + if (method.IsVirtual && !method.IsGeneratedOverride() && + !method.IsOperator && !method.IsPure && !isTemplateMethod) Write("virtual "); var isBuiltinOperator = method.IsOperator && @@ -2573,11 +2576,19 @@ namespace CppSharp.Generators.CSharp var i = VTables.GetVTableIndex(@virtual); int vtableIndex = 0; var @class = (Class) method.Namespace; + var thisParam = method.Parameters.Find( + p => p.Kind == ParameterKind.Extension); + if (thisParam != null) + @class = (Class) method.OriginalFunction.Namespace; + if (Context.ParserOptions.IsMicrosoftAbi) vtableIndex = @class.Layout.VFTables.IndexOf(@class.Layout.VFTables.Where( v => v.Layout.Components.Any(c => c.Method == @virtual)).First()); - WriteLine("var {0} = *(void**) ((IntPtr) __OriginalVTables[{1}] + {2} * {3});", - Helpers.SlotIdentifier, vtableIndex, i, Context.TargetInfo.PointerWidth / 8); + + WriteLine($@"var {Helpers.SlotIdentifier} = *(void**) ((IntPtr) { + (thisParam != null ? $"{thisParam.Name}." + : string.Empty)}__OriginalVTables[{vtableIndex}] + {i} * { + Context.TargetInfo.PointerWidth / 8});"); if (method.IsDestructor && @class.IsAbstract) { WriteLine("if ({0} != null)", Helpers.SlotIdentifier); diff --git a/tests/CSharp/CSharp.Tests.cs b/tests/CSharp/CSharp.Tests.cs index d2d64a60..41411a1d 100644 --- a/tests/CSharp/CSharp.Tests.cs +++ b/tests/CSharp/CSharp.Tests.cs @@ -736,7 +736,15 @@ public unsafe class CSharpTests : GeneratorTestFixture { using (var virtualTemplate = new VirtualTemplate()) { - Assert.That(virtualTemplate.Function, Is.EqualTo(5)); + Assert.That(virtualTemplate.Function(), Is.EqualTo(5)); + int i = 15; + Assert.That(*virtualTemplate.Function(ref i), Is.EqualTo(15)); + } + using (var virtualTemplate = new VirtualTemplate()) + { + Assert.That(virtualTemplate.Function(), Is.EqualTo(5)); + bool b = true; + Assert.That(*virtualTemplate.Function(ref b), Is.EqualTo(true)); } } @@ -1240,9 +1248,6 @@ public unsafe class CSharpTests : GeneratorTestFixture private class OverrideVirtualTemplate : VirtualTemplate { - public override int Function - { - get { return 10; } - } + public override int Function() => 10; } } diff --git a/tests/CSharp/CSharpTemplates.h b/tests/CSharp/CSharpTemplates.h index 16932e22..10dfbf71 100644 --- a/tests/CSharp/CSharpTemplates.h +++ b/tests/CSharp/CSharpTemplates.h @@ -442,6 +442,7 @@ public: VirtualTemplate(OptionalTemplateArgs optionalTemplateArgs); virtual ~VirtualTemplate(); virtual int function(); + virtual T* function(T* t); DependentValueFields fieldWithSpecializationType; }; @@ -471,6 +472,12 @@ int VirtualTemplate::function() return 5; } +template +T* VirtualTemplate::function(T* t) +{ + return t; +} + class DLL_API HasVirtualTemplate { public: