Browse Source

Called virtual destructors through the virtual table.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/551/head
Dimitar Dobrev 11 years ago
parent
commit
d769a81ade
  1. 6
      src/AST/ClassExtensions.cs
  2. 31
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  3. 9
      tests/CSharp/CSharp.Tests.cs
  4. 16
      tests/CSharp/CSharp.cpp
  5. 9
      tests/CSharp/CSharp.h

6
src/AST/ClassExtensions.cs

@ -61,10 +61,10 @@ namespace CppSharp.AST
let baseMethod = ( let baseMethod = (
from method in @base.Class.Methods from method in @base.Class.Methods
where where
method.OriginalName == @override.OriginalName && (method.OriginalName == @override.OriginalName &&
method.ReturnType == @override.ReturnType && method.ReturnType == @override.ReturnType &&
method.Parameters.SequenceEqual(@override.Parameters, method.Parameters.SequenceEqual(@override.Parameters, new ParameterTypeComparer())) ||
new ParameterTypeComparer()) (@override.IsDestructor && method.IsDestructor && method.IsVirtual)
select method).FirstOrDefault() select method).FirstOrDefault()
let rootBaseMethod = @base.Class.GetRootBaseMethod(@override, onlyFirstBase) ?? baseMethod let rootBaseMethod = @base.Class.GetRootBaseMethod(@override, onlyFirstBase) ?? baseMethod
where rootBaseMethod != null || onlyFirstBase where rootBaseMethod != null || onlyFirstBase

31
src/Generator/Generators/CSharp/CSharpTextTemplate.cs

@ -1889,12 +1889,16 @@ namespace CppSharp.Generators.CSharp
{ {
WriteLine("if ({0} || force)", Helpers.OwnsNativeInstanceIdentifier); WriteLine("if ({0} || force)", Helpers.OwnsNativeInstanceIdentifier);
var implicitArg = string.Empty; if (dtor.IsVirtual)
if (dtor.Parameters.Any(parameter => {
parameter.Kind == ParameterKind.ImplicitDestructorParameter)) WriteStartBraceIndent();
implicitArg = ", 0"; // Do not delete instance in MS ABI. GenerateVirtualFunctionCall(dtor, @class);
WriteLineIndent("Internal.{0}({1}{2});", GetFunctionNativeIdentifier(dtor), WriteCloseBraceIndent();
Helpers.InstanceIdentifier, implicitArg); }
else
{
GenerateInternalFunctionCall(dtor);
}
} }
} }
@ -1908,10 +1912,11 @@ namespace CppSharp.Generators.CSharp
private void GenerateNativeConstructor(Class @class) private void GenerateNativeConstructor(Class @class)
{ {
if (@class.IsRefType) var shouldGenerateClassNativeField = ShouldGenerateClassNativeField(@class);
if (@class.IsRefType && shouldGenerateClassNativeField)
{ {
PushBlock(CSharpBlockKind.Field); PushBlock(CSharpBlockKind.Field);
WriteLine("private bool {0};", Helpers.OwnsNativeInstanceIdentifier); WriteLine("protected bool {0};", Helpers.OwnsNativeInstanceIdentifier);
PopBlock(NewLineKind.BeforeNextBlock); PopBlock(NewLineKind.BeforeNextBlock);
} }
@ -1950,7 +1955,7 @@ namespace CppSharp.Generators.CSharp
if (@class.IsRefType) if (@class.IsRefType)
{ {
if (ShouldGenerateClassNativeField(@class)) if (shouldGenerateClassNativeField)
{ {
WriteLine("{0} = new global::System.IntPtr(native);", Helpers.InstanceIdentifier); WriteLine("{0} = new global::System.IntPtr(native);", Helpers.InstanceIdentifier);
var dtor = @class.Destructors.FirstOrDefault(); var dtor = @class.Destructors.FirstOrDefault();
@ -2689,11 +2694,13 @@ namespace CppSharp.Generators.CSharp
Function function = null) Function function = null)
{ {
PrimitiveType primitive; PrimitiveType primitive;
// Do not delete instance in MS ABI.
var name = param.Kind == ParameterKind.ImplicitDestructorParameter ? "0" : param.Name;
// returned structs must be blittable and bool and char aren't // returned structs must be blittable and bool and char aren't
if (param.Type.IsPrimitiveType(out primitive) && if (param.Type.IsPrimitiveType(out primitive) &&
primitive != PrimitiveType.Char && primitive != PrimitiveType.Bool) primitive != PrimitiveType.Char && primitive != PrimitiveType.Bool)
{ {
return new ParamMarshal { Name = param.Name, Param = param }; return new ParamMarshal { Name = name, Param = param };
} }
var argName = "arg" + paramIndex.ToString(CultureInfo.InvariantCulture); var argName = "arg" + paramIndex.ToString(CultureInfo.InvariantCulture);
@ -2708,7 +2715,7 @@ namespace CppSharp.Generators.CSharp
{ {
var qualifiedIdentifier = CSharpMarshalNativeToManagedPrinter.QualifiedIdentifier( var qualifiedIdentifier = CSharpMarshalNativeToManagedPrinter.QualifiedIdentifier(
@class.OriginalClass ?? @class); @class.OriginalClass ?? @class);
WriteLine("{0} = new {1}();", param.Name, qualifiedIdentifier); WriteLine("{0} = new {1}();", name, qualifiedIdentifier);
} }
} }
@ -2724,7 +2731,7 @@ namespace CppSharp.Generators.CSharp
if (param.Type.IsPrimitiveTypeConvertibleToRef()) if (param.Type.IsPrimitiveTypeConvertibleToRef())
{ {
WriteLine("fixed ({0} {1} = &{2})", param.Type.CSharpType(TypePrinter), argName, param.Name); WriteLine("fixed ({0} {1} = &{2})", param.Type.CSharpType(TypePrinter), argName, name);
paramMarshal.HasFixedBlock = true; paramMarshal.HasFixedBlock = true;
WriteStartBraceIndent(); WriteStartBraceIndent();
} }

9
tests/CSharp/CSharp.Tests.cs

@ -319,6 +319,15 @@ public class CSharpTests : GeneratorTestFixture
} }
} }
[Test]
public void TestCallingVirtualDtor()
{
var callDtorVirtually = new CallDtorVirtually();
var hasVirtualDtor1 = CallDtorVirtually.GetHasVirtualDtor1(callDtorVirtually);
hasVirtualDtor1.Dispose();
Assert.That(CallDtorVirtually.Destroyed, Is.True);
}
[Test] [Test]
public void TestParamTypeToInterfacePass() public void TestParamTypeToInterfacePass()
{ {

16
tests/CSharp/CSharp.cpp

@ -578,6 +578,22 @@ void TestNativeToManagedMap::setPropertyWithNoVirtualDtor(Bar* bar)
this->bar = bar; this->bar = bar;
} }
CallDtorVirtually::CallDtorVirtually()
{
}
CallDtorVirtually::~CallDtorVirtually()
{
Destroyed = true;
}
bool CallDtorVirtually::Destroyed = false;
HasVirtualDtor1* CallDtorVirtually::getHasVirtualDtor1(HasVirtualDtor1* returned)
{
return returned;
}
void SecondaryBase::VirtualMember() void SecondaryBase::VirtualMember()
{ {
} }

9
tests/CSharp/CSharp.h

@ -549,6 +549,15 @@ private:
Bar* bar; Bar* bar;
}; };
class DLL_API CallDtorVirtually : public HasVirtualDtor1
{
public:
CallDtorVirtually();
~CallDtorVirtually();
static bool Destroyed;
static HasVirtualDtor1* getHasVirtualDtor1(HasVirtualDtor1* returned);
};
class HasProtectedNestedAnonymousType class HasProtectedNestedAnonymousType
{ {
protected: protected:

Loading…
Cancel
Save