From 06e69225b9e5a9ef3aaa7875e0b17bc10b8e8722 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Sat, 31 Aug 2013 22:04:01 +0300 Subject: [PATCH] Implemented the MS branch of the abstract implementations. Signed-off-by: Dimitar Dobrev --- .../Generators/CSharp/CSharpTextTemplate.cs | 6 +- .../Passes/AbstractImplementationsPass.cs | 79 +++++++++++++++---- tests/Basic/Basic.cpp | 7 +- tests/Basic/Basic.h | 7 +- 4 files changed, 81 insertions(+), 18 deletions(-) diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs index 3fcc8ec4..03230e20 100644 --- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs +++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs @@ -1564,7 +1564,11 @@ namespace CppSharp.Generators.CSharp switch (Driver.Options.Abi) { case CppAbi.Microsoft: - throw new NotImplementedException(); + i = (from table in @class.Layout.VFTables + let j = table.Layout.Components.FindIndex(m => m.Method == method) + where j > 0 + select j).First(); + break; default: i = @class.Layout.Layout.Components.FindIndex(m => m.Method == method); break; diff --git a/src/Generator/Passes/AbstractImplementationsPass.cs b/src/Generator/Passes/AbstractImplementationsPass.cs index 0a7aac7e..af8562f1 100644 --- a/src/Generator/Passes/AbstractImplementationsPass.cs +++ b/src/Generator/Passes/AbstractImplementationsPass.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using CppSharp.AST; using CppSharp.Utils; @@ -30,7 +31,7 @@ namespace CppSharp.Passes return base.VisitClassDecl(@class); } - private static Class AddInternalImplementation(Class @class) + private Class AddInternalImplementation(Class @class) { var internalImplementation = new Class(); internalImplementation.Name = @class.Name + "Internal"; @@ -68,19 +69,7 @@ namespace CppSharp.Passes internalImplementation.Typedefs.Add(@delegate); } internalImplementation.Layout = new ClassLayout(@class.Layout); - var vTableComponents = GetVTableComponents(@class); - for (int i = 0; i < abstractMethods.Count; i++) - { - var vTableComponent = vTableComponents.Find(v => v.Method == abstractMethods[i]); - VTableComponent copy = new VTableComponent(); - copy.Kind = vTableComponent.Kind; - copy.Offset = vTableComponent.Offset; - copy.Declaration = internalImplementation.Methods[i]; - vTableComponents[vTableComponents.IndexOf(vTableComponent)] = copy; - } - internalImplementation.Layout.Layout.Components.Clear(); - internalImplementation.Layout.Layout.Components.AddRange(vTableComponents); - internalImplementation.Layout.VFTables.AddRange(@class.Layout.VFTables); + FillVTable(@class, abstractMethods, internalImplementation); foreach (Method method in internalImplementation.Methods) { method.IsPure = false; @@ -106,6 +95,57 @@ namespace CppSharp.Passes return abstractMethods; } + private void FillVTable(Class @class, IList abstractMethods, Class internalImplementation) + { + switch (Driver.Options.Abi) + { + case CppAbi.Microsoft: + CreateVTableMS(@class, abstractMethods, internalImplementation); + break; + default: + CreateVTableItanium(@class, abstractMethods, internalImplementation); + break; + } + } + + private static void CreateVTableMS(Class @class, + IList abstractMethods, Class internalImplementation) + { + var vTables = GetVTables(@class); + for (int i = 0; i < abstractMethods.Count; i++) + { + for (int j = 0; j < vTables.Count; j++) + { + VFTableInfo vTable = vTables[j]; + var k = vTable.Layout.Components.FindIndex(v => v.Method == abstractMethods[i]); + if (k >= 0) + { + VTableComponent vTableComponent = vTable.Layout.Components[k]; + vTableComponent.Declaration = internalImplementation.Methods[i]; + vTable.Layout.Components[k] = vTableComponent; + vTables[j] = vTable; + } + } + } + internalImplementation.Layout.VFTables.Clear(); + internalImplementation.Layout.VFTables.AddRange(vTables); + } + + private static void CreateVTableItanium(Class @class, + IList abstractMethods, Class internalImplementation) + { + var vTableComponents = GetVTableComponents(@class); + for (int i = 0; i < abstractMethods.Count; i++) + { + var j = vTableComponents.FindIndex(v => v.Method == abstractMethods[i]); + VTableComponent vTableComponent = vTableComponents[j]; + vTableComponent.Declaration = internalImplementation.Methods[i]; + vTableComponents[j] = vTableComponent; + } + internalImplementation.Layout.Layout.Components.Clear(); + internalImplementation.Layout.Layout.Components.AddRange(vTableComponents); + } + private static List GetVTableComponents(Class @class) { List vTableComponents = new List( @@ -114,5 +154,14 @@ namespace CppSharp.Passes vTableComponents.AddRange(GetVTableComponents(@base.Class)); return vTableComponents; } + + private static List GetVTables(Class @class) + { + List vTables = new List( + @class.Layout.VFTables); + foreach (BaseClassSpecifier @base in @class.Bases) + vTables.AddRange(GetVTables(@base.Class)); + return vTables; + } } } diff --git a/tests/Basic/Basic.cpp b/tests/Basic/Basic.cpp index b19ccff5..de9ace33 100644 --- a/tests/Basic/Basic.cpp +++ b/tests/Basic/Basic.cpp @@ -121,6 +121,11 @@ Bar indirectReturn() return Bar(); } +int ImplementAbstractFoo::pureFunction() +{ + return 5; +} + void DefaultParameters::Foo(int a, int b) { } @@ -135,4 +140,4 @@ void DefaultParameters::Bar() const void DefaultParameters::Bar() { -} \ No newline at end of file +} diff --git a/tests/Basic/Basic.h b/tests/Basic/Basic.h index 2a5f4d2c..ee698006 100644 --- a/tests/Basic/Basic.h +++ b/tests/Basic/Basic.h @@ -83,8 +83,13 @@ public: class DLL_API AbstractFoo { public: + virtual int pureFunction() = 0; +}; - virtual void pureFunction() = 0; +class DLL_API ImplementAbstractFoo : public AbstractFoo +{ +public: + virtual int pureFunction(); }; DLL_API Bar operator-(const Bar &);