Browse Source

Generate valid C# for pure functions returning or taking dependent pointers

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
update-llvm
Dimitar Dobrev 4 years ago
parent
commit
5552f2b484
  1. 11
      src/Generator/Generators/CSharp/CSharpSources.cs
  2. 7
      src/Generator/Passes/GenerateAbstractImplementationsPass.cs
  3. 5
      src/Generator/Passes/SpecializationMethodsWithDependentPointersPass.cs
  4. 12
      tests/CSharp/CSharp.Tests.cs
  5. 51
      tests/CSharp/CSharpTemplates.h

11
src/Generator/Generators/CSharp/CSharpSources.cs

@ -1676,7 +1676,7 @@ namespace CppSharp.Generators.CSharp @@ -1676,7 +1676,7 @@ namespace CppSharp.Generators.CSharp
NewLine();
// Generate a delegate type for each method.
foreach (var method in wrappedEntries.Select(e => e.Method))
foreach (var method in wrappedEntries.Select(e => e.Method).Where(m => !m.Ignore))
GenerateVTableMethodDelegates(containingClass, method.Namespace.IsDependent ?
(Method) method.InstantiatedFrom : method);
@ -1701,7 +1701,7 @@ namespace CppSharp.Generators.CSharp @@ -1701,7 +1701,7 @@ namespace CppSharp.Generators.CSharp
WriteLine($"static VTableLoader()");
{
WriteOpenBraceAndIndent();
foreach (var entry in wrappedEntries.Distinct())
foreach (var entry in wrappedEntries.Distinct().Where(e => !e.Method.Ignore))
{
var name = GetVTableMethodDelegateName(entry.Method);
WriteLine($"{name + "Instance"} += {name}Hook;");
@ -1709,8 +1709,11 @@ namespace CppSharp.Generators.CSharp @@ -1709,8 +1709,11 @@ namespace CppSharp.Generators.CSharp
for (var i = 0; i < wrappedEntries.Count; ++i)
{
var entry = wrappedEntries[i];
var name = GetVTableMethodDelegateName(entry.Method);
WriteLine($"Thunks[{i}] = Marshal.GetFunctionPointerForDelegate({name + "Instance"});");
if (!entry.Method.Ignore)
{
var name = GetVTableMethodDelegateName(entry.Method);
WriteLine($"Thunks[{i}] = Marshal.GetFunctionPointerForDelegate({name + "Instance"});");
}
}
UnindentAndWriteCloseBrace();
}

7
src/Generator/Passes/GenerateAbstractImplementationsPass.cs

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using CppSharp.AST;
using CppSharp.AST.Extensions;
namespace CppSharp.Passes
{
@ -72,6 +73,12 @@ namespace CppSharp.Passes @@ -72,6 +73,12 @@ namespace CppSharp.Passes
};
impl.OverriddenMethods.Clear();
impl.OverriddenMethods.Add(abstractMethod);
if (abstractMethod.OriginalReturnType.Type.IsDependentPointer() ||
abstractMethod.Parameters.Any(p => p.Type.IsDependentPointer()))
{
// this is an extension but marks the class as an abstract impl
impl.ExplicitlyIgnore();
}
internalImpl.Methods.Add(impl);
}

5
src/Generator/Passes/SpecializationMethodsWithDependentPointersPass.cs

@ -118,6 +118,11 @@ namespace CppSharp.Passes @@ -118,6 +118,11 @@ namespace CppSharp.Passes
extensionMethod.OriginalFunction = specializedMethod;
extensionMethod.Kind = CXXMethodKind.Normal;
extensionMethod.IsStatic = true;
if (extensionMethod.IsPure)
{
extensionMethod.IsPure = false;
extensionMethod.SynthKind = FunctionSynthKind.AbstractImplCall;
}
var qualReturnType = extensionMethod.OriginalReturnType;
RemoveTemplateSubstitution(ref qualReturnType);

12
tests/CSharp/CSharp.Tests.cs

@ -1328,6 +1328,18 @@ public unsafe class CSharpTests @@ -1328,6 +1328,18 @@ public unsafe class CSharpTests
}
}
[Test]
public void TestAbstractImplTemplate()
{
using (var returnsPointer = new DependentValueFields<int>())
{
using (var value = returnsPointer.AbstractReturnPointer)
{
Assert.That(new IntPtr(value.AbstractReturnPointer()), Is.EqualTo(IntPtr.Zero));
}
}
}
[Test]
public void TestSpecializationForSecondaryBase()
{

51
tests/CSharp/CSharpTemplates.h

@ -36,6 +36,50 @@ class DLL_API Ignored @@ -36,6 +36,50 @@ class DLL_API Ignored
{
};
template <typename T>
class HasAbstractReturnPointer
{
public:
HasAbstractReturnPointer();
~HasAbstractReturnPointer();
virtual const T* abstractReturnPointer() = 0;
};
template <typename T>
HasAbstractReturnPointer<T>::HasAbstractReturnPointer()
{
}
template <typename T>
HasAbstractReturnPointer<T>::~HasAbstractReturnPointer()
{
}
template <typename T>
class ImplReturnPointer : public HasAbstractReturnPointer<T>
{
public:
ImplReturnPointer();
~ImplReturnPointer();
virtual const T* abstractReturnPointer() override;
};
template <typename T>
ImplReturnPointer<T>::ImplReturnPointer()
{
}
template <typename T>
ImplReturnPointer<T>::~ImplReturnPointer()
{
}
template <typename T>
const T* ImplReturnPointer<T>::abstractReturnPointer()
{
return 0;
}
template <typename T>
class IndependentFields : public T1
{
@ -176,6 +220,7 @@ public: @@ -176,6 +220,7 @@ public:
const T* returnTakeDependentPointer(const T* p);
const T* propertyReturnDependentPointer();
void hasDefaultDependentParam(T* ptr, const T& refT = T());
HasAbstractReturnPointer<T>* getAbstractReturnPointer();
typedef void (*DependentFunctionPointer)(T);
DependentFunctionPointer dependentFunctionPointerField;
private:
@ -235,6 +280,12 @@ void DependentValueFields<T>::hasDefaultDependentParam(T* ptr, const T& refT) @@ -235,6 +280,12 @@ void DependentValueFields<T>::hasDefaultDependentParam(T* ptr, const T& refT)
{
}
template <typename T>
HasAbstractReturnPointer<T>* DependentValueFields<T>::getAbstractReturnPointer()
{
return new ImplReturnPointer<T>();
}
template <typename T>
DependentValueFields<T>& DependentValueFields<T>::returnInjectedClass()
{

Loading…
Cancel
Save