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

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

@ -1889,12 +1889,16 @@ namespace CppSharp.Generators.CSharp @@ -1889,12 +1889,16 @@ namespace CppSharp.Generators.CSharp
{
WriteLine("if ({0} || force)", Helpers.OwnsNativeInstanceIdentifier);
var implicitArg = string.Empty;
if (dtor.Parameters.Any(parameter =>
parameter.Kind == ParameterKind.ImplicitDestructorParameter))
implicitArg = ", 0"; // Do not delete instance in MS ABI.
WriteLineIndent("Internal.{0}({1}{2});", GetFunctionNativeIdentifier(dtor),
Helpers.InstanceIdentifier, implicitArg);
if (dtor.IsVirtual)
{
WriteStartBraceIndent();
GenerateVirtualFunctionCall(dtor, @class);
WriteCloseBraceIndent();
}
else
{
GenerateInternalFunctionCall(dtor);
}
}
}
@ -1908,10 +1912,11 @@ namespace CppSharp.Generators.CSharp @@ -1908,10 +1912,11 @@ namespace CppSharp.Generators.CSharp
private void GenerateNativeConstructor(Class @class)
{
if (@class.IsRefType)
var shouldGenerateClassNativeField = ShouldGenerateClassNativeField(@class);
if (@class.IsRefType && shouldGenerateClassNativeField)
{
PushBlock(CSharpBlockKind.Field);
WriteLine("private bool {0};", Helpers.OwnsNativeInstanceIdentifier);
WriteLine("protected bool {0};", Helpers.OwnsNativeInstanceIdentifier);
PopBlock(NewLineKind.BeforeNextBlock);
}
@ -1950,7 +1955,7 @@ namespace CppSharp.Generators.CSharp @@ -1950,7 +1955,7 @@ namespace CppSharp.Generators.CSharp
if (@class.IsRefType)
{
if (ShouldGenerateClassNativeField(@class))
if (shouldGenerateClassNativeField)
{
WriteLine("{0} = new global::System.IntPtr(native);", Helpers.InstanceIdentifier);
var dtor = @class.Destructors.FirstOrDefault();
@ -2689,11 +2694,13 @@ namespace CppSharp.Generators.CSharp @@ -2689,11 +2694,13 @@ namespace CppSharp.Generators.CSharp
Function function = null)
{
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
if (param.Type.IsPrimitiveType(out primitive) &&
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);
@ -2708,7 +2715,7 @@ namespace CppSharp.Generators.CSharp @@ -2708,7 +2715,7 @@ namespace CppSharp.Generators.CSharp
{
var qualifiedIdentifier = CSharpMarshalNativeToManagedPrinter.QualifiedIdentifier(
@class.OriginalClass ?? @class);
WriteLine("{0} = new {1}();", param.Name, qualifiedIdentifier);
WriteLine("{0} = new {1}();", name, qualifiedIdentifier);
}
}
@ -2724,7 +2731,7 @@ namespace CppSharp.Generators.CSharp @@ -2724,7 +2731,7 @@ namespace CppSharp.Generators.CSharp
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;
WriteStartBraceIndent();
}

9
tests/CSharp/CSharp.Tests.cs

@ -319,6 +319,15 @@ public class CSharpTests : GeneratorTestFixture @@ -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]
public void TestParamTypeToInterfacePass()
{

16
tests/CSharp/CSharp.cpp

@ -578,6 +578,22 @@ void TestNativeToManagedMap::setPropertyWithNoVirtualDtor(Bar* bar) @@ -578,6 +578,22 @@ void TestNativeToManagedMap::setPropertyWithNoVirtualDtor(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()
{
}

9
tests/CSharp/CSharp.h

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

Loading…
Cancel
Save