From 6fe81fddccc620124ef011145daecd58d62db919 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Tue, 24 Mar 2020 23:39:06 +0200 Subject: [PATCH] Remove needless pointer offsets from generated C# Signed-off-by: Dimitar Dobrev --- src/AST/ClassLayout.cs | 5 ++++ .../Generators/CSharp/CSharpSources.cs | 25 ++++++++++--------- src/Generator/Generators/CodeGenerator.cs | 2 +- src/Parser/ASTConverter.cs | 8 ++++++ 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/AST/ClassLayout.cs b/src/AST/ClassLayout.cs index f1a20205..db58cfea 100644 --- a/src/AST/ClassLayout.cs +++ b/src/AST/ClassLayout.cs @@ -171,6 +171,11 @@ namespace CppSharp.AST } } + /// + /// Indicates whether this class layout has a subclass at a non-zero offset. + /// + public bool HasSubclassAtNonZeroOffset { get; set; } + private List vTablePointers; } } diff --git a/src/Generator/Generators/CSharp/CSharpSources.cs b/src/Generator/Generators/CSharp/CSharpSources.cs index c4e3c73b..04b0fa87 100644 --- a/src/Generator/Generators/CSharp/CSharpSources.cs +++ b/src/Generator/Generators/CSharp/CSharpSources.cs @@ -428,7 +428,8 @@ namespace CppSharp.Generators.CSharp PushBlock(BlockKind.Field); - WriteLine("protected int {0};", Helpers.PointerAdjustmentIdentifier); + if (@class.Layout.HasSubclassAtNonZeroOffset) + WriteLine($"protected int {Helpers.PrimaryBaseOffsetIdentifier};"); // use interfaces if any - derived types with a secondary base this class must be compatible with the map var @interface = @class.Namespace.Classes.FirstOrDefault( @@ -2183,8 +2184,8 @@ namespace CppSharp.Generators.CSharp if (@class.IsRefType) { - if (@class.HasBaseClass) - WriteLine("{0} = {1};", Helpers.PointerAdjustmentIdentifier, + if (@class.BaseClass?.Layout.HasSubclassAtNonZeroOffset == true) + WriteLine("{0} = {1};", Helpers.PrimaryBaseOffsetIdentifier, GetOffsetToBase(@class, @class.BaseClass)); if (!@class.IsAbstractImpl) { @@ -2945,17 +2946,17 @@ namespace CppSharp.Generators.CSharp to = to.OriginalClass ?? to; baseOffset = GetOffsetToBase(from, to); } - var isPrimaryBase = (from.BaseClass?.OriginalClass ?? from.BaseClass) == to; - if (isPrimaryBase) + bool isPrimaryBase = (from.BaseClass?.OriginalClass ?? from.BaseClass) == to; + bool isOrHasSubclassAtNonZeroOffset = + from.Layout.HasSubclassAtNonZeroOffset || + to?.Layout.HasSubclassAtNonZeroOffset == true; + if (isPrimaryBase && isOrHasSubclassAtNonZeroOffset) { - return string.Format("({0} + {1}{2})", - Helpers.InstanceIdentifier, - Helpers.PointerAdjustmentIdentifier, - baseOffset == 0 ? string.Empty : (" - " + baseOffset)); + return Helpers.InstanceIdentifier + + (baseOffset == 0 ? " + " + Helpers.PrimaryBaseOffsetIdentifier : string.Empty); } - return string.Format("({0}{1})", - Helpers.InstanceIdentifier, - baseOffset == 0 ? string.Empty : " + " + baseOffset); + return Helpers.InstanceIdentifier + + (baseOffset == 0 ? string.Empty : " + " + baseOffset); } private static uint GetOffsetToBase(Class from, Class to) diff --git a/src/Generator/Generators/CodeGenerator.cs b/src/Generator/Generators/CodeGenerator.cs index 9257a535..3159ae2d 100644 --- a/src/Generator/Generators/CodeGenerator.cs +++ b/src/Generator/Generators/CodeGenerator.cs @@ -1209,7 +1209,7 @@ namespace CppSharp.Generators public static readonly string InternalStruct = Generator.GeneratedIdentifier("Internal"); public static readonly string InstanceField = Generator.GeneratedIdentifier("instance"); public static readonly string InstanceIdentifier = Generator.GeneratedIdentifier("Instance"); - public static readonly string PointerAdjustmentIdentifier = Generator.GeneratedIdentifier("PointerAdjustment"); + public static readonly string PrimaryBaseOffsetIdentifier = Generator.GeneratedIdentifier("PrimaryBaseOffset"); public static readonly string ReturnIdentifier = Generator.GeneratedIdentifier("ret"); public static readonly string DummyIdentifier = Generator.GeneratedIdentifier("dummy"); public static readonly string TargetIdentifier = Generator.GeneratedIdentifier("target"); diff --git a/src/Parser/ASTConverter.cs b/src/Parser/ASTConverter.cs index 21519af3..4e0c3f45 100644 --- a/src/Parser/ASTConverter.cs +++ b/src/Parser/ASTConverter.cs @@ -1587,7 +1587,15 @@ namespace CppSharp _class.IsInjected = @class.IsInjected; if (@class.Layout != null) + { _class.Layout = VisitClassLayout(@class.Layout); + if (_class.BaseClass != null) + { + AST.LayoutBase @base = _class.Layout.Bases.Find( + b => b.Class == _class.BaseClass); + _class.BaseClass.Layout.HasSubclassAtNonZeroOffset = @base.Offset > 0; + } + } } public override AST.Declaration VisitClass(Class @class)