Skip to content

Commit 5e0e19e

Browse files
ddobrevtritao
authored andcommitted
Fixed the generation of dependent virtual methods.
Signed-off-by: Dimitar Dobrev <[email protected]>
1 parent a430d19 commit 5e0e19e

File tree

3 files changed

+32
-9
lines changed

3 files changed

+32
-9
lines changed

src/Generator/Generators/CSharp/CSharpSources.cs

+15-4
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ public override bool VisitClassDecl(Class @class)
424424
var dict = $@"global::System.Collections.Concurrent.ConcurrentDictionary<IntPtr, {
425425
printedClass}>";
426426
WriteLine("internal static readonly {0} NativeToManagedMap = new {0}();", dict);
427-
WriteLine("protected void*[] __OriginalVTables;");
427+
WriteLine("protected internal void*[] __OriginalVTables;");
428428
}
429429
PopBlock(NewLineKind.BeforeNextBlock);
430430
}
@@ -2272,7 +2272,10 @@ public void GenerateFunction(Function function, string parentName)
22722272

22732273
public override void GenerateMethodSpecifier(Method method, Class @class)
22742274
{
2275-
if (method.IsVirtual && !method.IsGeneratedOverride() && !method.IsOperator && !method.IsPure)
2275+
bool isTemplateMethod = method.Parameters.Any(
2276+
p => p.Kind == ParameterKind.Extension);
2277+
if (method.IsVirtual && !method.IsGeneratedOverride() &&
2278+
!method.IsOperator && !method.IsPure && !isTemplateMethod)
22762279
Write("virtual ");
22772280

22782281
var isBuiltinOperator = method.IsOperator &&
@@ -2573,11 +2576,19 @@ private string GetVirtualCallDelegate(Method method)
25732576
var i = VTables.GetVTableIndex(@virtual);
25742577
int vtableIndex = 0;
25752578
var @class = (Class) method.Namespace;
2579+
var thisParam = method.Parameters.Find(
2580+
p => p.Kind == ParameterKind.Extension);
2581+
if (thisParam != null)
2582+
@class = (Class) method.OriginalFunction.Namespace;
2583+
25762584
if (Context.ParserOptions.IsMicrosoftAbi)
25772585
vtableIndex = @class.Layout.VFTables.IndexOf(@class.Layout.VFTables.Where(
25782586
v => v.Layout.Components.Any(c => c.Method == @virtual)).First());
2579-
WriteLine("var {0} = *(void**) ((IntPtr) __OriginalVTables[{1}] + {2} * {3});",
2580-
Helpers.SlotIdentifier, vtableIndex, i, Context.TargetInfo.PointerWidth / 8);
2587+
2588+
WriteLine($@"var {Helpers.SlotIdentifier} = *(void**) ((IntPtr) {
2589+
(thisParam != null ? $"{thisParam.Name}."
2590+
: string.Empty)}__OriginalVTables[{vtableIndex}] + {i} * {
2591+
Context.TargetInfo.PointerWidth / 8});");
25812592
if (method.IsDestructor && @class.IsAbstract)
25822593
{
25832594
WriteLine("if ({0} != null)", Helpers.SlotIdentifier);

tests/CSharp/CSharp.Tests.cs

+10-5
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,15 @@ public void TestVirtualTemplate()
736736
{
737737
using (var virtualTemplate = new VirtualTemplate<int>())
738738
{
739-
Assert.That(virtualTemplate.Function, Is.EqualTo(5));
739+
Assert.That(virtualTemplate.Function(), Is.EqualTo(5));
740+
int i = 15;
741+
Assert.That(*virtualTemplate.Function(ref i), Is.EqualTo(15));
742+
}
743+
using (var virtualTemplate = new VirtualTemplate<bool>())
744+
{
745+
Assert.That(virtualTemplate.Function(), Is.EqualTo(5));
746+
bool b = true;
747+
Assert.That(*virtualTemplate.Function(ref b), Is.EqualTo(true));
740748
}
741749
}
742750

@@ -1240,9 +1248,6 @@ public class Inter : SimpleInterface
12401248

12411249
private class OverrideVirtualTemplate : VirtualTemplate<int>
12421250
{
1243-
public override int Function
1244-
{
1245-
get { return 10; }
1246-
}
1251+
public override int Function() => 10;
12471252
}
12481253
}

tests/CSharp/CSharpTemplates.h

+7
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,7 @@ class VirtualTemplate
442442
VirtualTemplate(OptionalTemplateArgs<T> optionalTemplateArgs);
443443
virtual ~VirtualTemplate();
444444
virtual int function();
445+
virtual T* function(T* t);
445446
DependentValueFields<float> fieldWithSpecializationType;
446447
};
447448

@@ -471,6 +472,12 @@ int VirtualTemplate<T>::function()
471472
return 5;
472473
}
473474

475+
template <typename T>
476+
T* VirtualTemplate<T>::function(T* t)
477+
{
478+
return t;
479+
}
480+
474481
class DLL_API HasVirtualTemplate
475482
{
476483
public:

0 commit comments

Comments
 (0)