From 0950b869a19fe851803f4f594789dfc04d80c10d Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Mon, 12 Oct 2015 21:58:07 +0300 Subject: [PATCH] Fixed the offsets of fields when using multiple inheritance. Signed-off-by: Dimitar Dobrev --- .../Generators/CSharp/CSharpTextTemplate.cs | 19 +++++++++------- tests/CSharp/CSharp.Tests.cs | 15 ++++++++++++- tests/CSharp/CSharp.cpp | 12 ++++++++++ tests/CSharp/CSharp.h | 22 +++++++++++++++++++ 4 files changed, 59 insertions(+), 9 deletions(-) diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs index 6c48b367..96c06111 100644 --- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs +++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs @@ -515,7 +515,7 @@ namespace CppSharp.Generators.CSharp TypePrinter.PushContext(CSharpTypePrinterContextKind.Native); - GenerateClassFields(@class, GenerateClassInternalsField, true); + GenerateClassFields(@class, @class, GenerateClassInternalsField, true); if (@class.IsGenerated) { if (@class.IsDynamic) @@ -709,7 +709,8 @@ namespace CppSharp.Generators.CSharp Write(" : {0}", string.Join(", ", bases)); } - public void GenerateClassFields(Class @class, Action action, bool nativeFields = false) + public void GenerateClassFields(Class owner, Class @class, + Action action, bool nativeFields = false) { foreach (var @base in @class.Bases.Where(b => b.Class != null)) { @@ -718,17 +719,17 @@ namespace CppSharp.Generators.CSharp @base.Class.OriginalClass == @class) continue; - GenerateClassFields(@base.Class, action, nativeFields); + GenerateClassFields(owner, @base.Class, action, nativeFields); } foreach (var field in @class.Fields) { if (ASTUtils.CheckIgnoreField(field, nativeFields)) continue; - action(field); + action(owner, field); } } - private void GenerateClassInternalsField(Field field) + private void GenerateClassInternalsField(Class owner, Field field) { // we do not support dependent fields yet, see https://github.com/mono/CppSharp/issues/197 Class @class; @@ -746,7 +747,8 @@ namespace CppSharp.Generators.CSharp PushBlock(CSharpBlockKind.Field); - WriteLine("[FieldOffset({0})]", field.OffsetInBytes); + WriteLine("[FieldOffset({0})]", field.OffsetInBytes + + owner.ComputeNonVirtualBaseClassOffsetTo((Class) field.Namespace)); TypePrinter.PushMarshalKind(CSharpMarshalKind.NativeField); var fieldTypePrinted = field.QualifiedType.CSharpType(TypePrinter); @@ -782,10 +784,11 @@ namespace CppSharp.Generators.CSharp Name = string.Format("{0}_{1}_{2}", Helpers.DummyIdentifier, safeIdentifier, i), QualifiedType = new QualifiedType(arrayType.Type), - Offset = (uint)(field.Offset + (i * arrayType.ElementSize)) + Offset = (uint) (field.Offset + i * arrayType.ElementSize), + Namespace = owner }; - GenerateClassInternalsField(dummy); + GenerateClassInternalsField(owner, dummy); } } } diff --git a/tests/CSharp/CSharp.Tests.cs b/tests/CSharp/CSharp.Tests.cs index b6589334..d81230dd 100644 --- a/tests/CSharp/CSharp.Tests.cs +++ b/tests/CSharp/CSharp.Tests.cs @@ -479,7 +479,20 @@ public class CSharpTests : GeneratorTestFixture { using (new QApplication()) { - new QWidget(); + using (new QWidget()) + { + } + } + } + + [Test] + public void TestMultipleInheritanceFieldOffsets() + { + using (var multipleInheritanceFieldOffsets = new MultipleInheritanceFieldOffsets()) + { + Assert.That(multipleInheritanceFieldOffsets.Primary, Is.EqualTo(1)); + Assert.That(multipleInheritanceFieldOffsets.Secondary, Is.EqualTo(2)); + Assert.That(multipleInheritanceFieldOffsets.Own, Is.EqualTo(3)); } } } diff --git a/tests/CSharp/CSharp.cpp b/tests/CSharp/CSharp.cpp index de11fd66..7bc02705 100644 --- a/tests/CSharp/CSharp.cpp +++ b/tests/CSharp/CSharp.cpp @@ -894,3 +894,15 @@ char* HasSamePropertyInDerivedAbstractType::property() InheritsFromHasSamePropertyInDerivedAbstractType::InheritsFromHasSamePropertyInDerivedAbstractType() { } + +MultipleInheritanceFieldOffsetsSecondaryBase::MultipleInheritanceFieldOffsetsSecondaryBase() : secondary(2) +{ +} + +MultipleInheritanceFieldOffsetsPrimaryBase::MultipleInheritanceFieldOffsetsPrimaryBase() : primary(1) +{ +} + +MultipleInheritanceFieldOffsets::MultipleInheritanceFieldOffsets() : own(3) +{ +} diff --git a/tests/CSharp/CSharp.h b/tests/CSharp/CSharp.h index 32321527..d73e6654 100644 --- a/tests/CSharp/CSharp.h +++ b/tests/CSharp/CSharp.h @@ -806,3 +806,25 @@ public: InheritsFromHasSamePropertyInDerivedAbstractType(); virtual int property() = 0; }; + + +class DLL_API MultipleInheritanceFieldOffsetsSecondaryBase +{ +public: + MultipleInheritanceFieldOffsetsSecondaryBase(); + int secondary; +}; + +class DLL_API MultipleInheritanceFieldOffsetsPrimaryBase +{ +public: + MultipleInheritanceFieldOffsetsPrimaryBase(); + int primary; +}; + +class DLL_API MultipleInheritanceFieldOffsets : public MultipleInheritanceFieldOffsetsPrimaryBase, public MultipleInheritanceFieldOffsetsSecondaryBase +{ +public: + MultipleInheritanceFieldOffsets(); + int own; +};