From 9ab71aeac7b70c00e3bd8bc0859ddb94d0f78b7c Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Sun, 24 Jan 2016 23:55:40 +0200 Subject: [PATCH] Fixed the parsing of subclasses of dynamic template instantiations. Signed-off-by: Dimitar Dobrev --- src/Generator/AST/VTables.cs | 4 +++- src/Generator/Passes/DelegatesPass.cs | 30 +++++++++++++++++++++++++++ tests/Common/Common.Tests.cs | 3 +++ tests/Common/Common.cpp | 4 ++++ tests/Common/Common.h | 24 +++++++++++++++++++++ 5 files changed, 64 insertions(+), 1 deletion(-) diff --git a/src/Generator/AST/VTables.cs b/src/Generator/AST/VTables.cs index 9ba2d82d..bda144a4 100644 --- a/src/Generator/AST/VTables.cs +++ b/src/Generator/AST/VTables.cs @@ -73,7 +73,9 @@ namespace CppSharp.AST return entry.Method != null && (entry.Method.IsOperator || (!entry.Method.IsDeclared && - ((Class) entry.Method.Namespace).GetPropertyByConstituentMethod(entry.Method) == null)); + ((Class) entry.Method.Namespace).GetPropertyByConstituentMethod(entry.Method) == null) || + // virtuals defined in templates are not yet supported + entry.Method.Namespace is ClassTemplateSpecialization); } } } diff --git a/src/Generator/Passes/DelegatesPass.cs b/src/Generator/Passes/DelegatesPass.cs index a15cdbfd..d597f0c9 100644 --- a/src/Generator/Passes/DelegatesPass.cs +++ b/src/Generator/Passes/DelegatesPass.cs @@ -52,6 +52,36 @@ namespace CppSharp.Passes return result; } + public override bool VisitClassDecl(Class @class) + { + if (!base.VisitClassDecl(@class)) + return false; + + // dependent types with virtuals have no own virtual layouts + // so virtuals are considered different objects in template instantiations + // therefore the method itself won't be visited, so let's visit it through the v-table + if (Driver.Options.IsMicrosoftAbi) + { + foreach (var method in from vfTable in @class.Layout.VFTables + from component in vfTable.Layout.Components + where component.Method != null + select component.Method) + VisitMethodDecl(method); + } + else + { + if (@class.Layout.Layout == null) + return false; + + foreach (var method in from component in @class.Layout.Layout.Components + where component.Method != null + select component.Method) + VisitMethodDecl(method); + } + + return true; + } + public override bool VisitMethodDecl(Method method) { if (!base.VisitMethodDecl(method) || !method.IsVirtual || method.Ignore) diff --git a/tests/Common/Common.Tests.cs b/tests/Common/Common.Tests.cs index 49c33969..12fe26fd 100644 --- a/tests/Common/Common.Tests.cs +++ b/tests/Common/Common.Tests.cs @@ -22,6 +22,9 @@ public class CommonTests : GeneratorTestFixture { Assert.That(overridesNonDirectVirtual.retInt(), Is.EqualTo(3)); } + using (var derivedFromTemplateInstantiationWithVirtual = new DerivedFromTemplateInstantiationWithVirtual()) + { + } } [Test] diff --git a/tests/Common/Common.cpp b/tests/Common/Common.cpp index ded1bb3a..d68e59a5 100644 --- a/tests/Common/Common.cpp +++ b/tests/Common/Common.cpp @@ -602,3 +602,7 @@ NonTrivialDtor::~NonTrivialDtor() { dtorCalled = true; } + +DerivedFromTemplateInstantiationWithVirtual::DerivedFromTemplateInstantiationWithVirtual() +{ +} diff --git a/tests/Common/Common.h b/tests/Common/Common.h index 53641d2a..b356656e 100644 --- a/tests/Common/Common.h +++ b/tests/Common/Common.h @@ -1019,3 +1019,27 @@ ForwardedTemplate ForwardedTemplate::functionInForwardedTemplate() const { return ForwardedTemplate(); } + +template +class TemplateWithVirtual +{ +public: + TemplateWithVirtual(); + virtual void v(); +}; + +template +TemplateWithVirtual::TemplateWithVirtual() +{ +} + +template +void TemplateWithVirtual::v() +{ +} + +class DLL_API DerivedFromTemplateInstantiationWithVirtual : public TemplateWithVirtual +{ +public: + DerivedFromTemplateInstantiationWithVirtual(); +};