Skip to content

Commit 060afd5

Browse files
committed
Add partial ref param support
1 parent 565776e commit 060afd5

File tree

5 files changed

+73
-1
lines changed

5 files changed

+73
-1
lines changed

src/AST/Assembly.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
using System.Runtime.CompilerServices;
2+
3+
[assembly: InternalsVisibleTo("CppSharp.Generator")]

src/AST/TypeExtensions.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,5 +442,31 @@ public static long GetSizeInBits(this ArrayType array)
442442
{
443443
return array.Size * array.ElementSize;
444444
}
445+
446+
internal static bool IsReferenceToPtrToClass(this Type type)
447+
{
448+
var @ref = type.Desugar().AsLvReference();
449+
if (@ref == null)
450+
return false;
451+
452+
var @ptr = @ref.Pointee.Desugar(false).AsPtr();
453+
if (@ptr == null)
454+
return false;
455+
456+
var @class = @ptr.Pointee;
457+
return @class != null && @class.IsClass();
458+
}
459+
460+
internal static PointerType AsLvReference(this Type type)
461+
{
462+
var reference = type as PointerType;
463+
return reference?.Modifier == PointerType.TypeModifier.LVReference ? reference : null;
464+
}
465+
466+
internal static PointerType AsPtr(this Type type)
467+
{
468+
var ptr = type as PointerType;
469+
return ptr?.Modifier == PointerType.TypeModifier.Pointer ? ptr : null;
470+
}
445471
}
446472
}

src/Generator/Generators/CSharp/CSharpSources.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3193,6 +3193,17 @@ public void GenerateFunctionCall(string functionName, Function function,
31933193
}
31943194
WriteLine("{0}({1});", functionName, string.Join(", ", names));
31953195

3196+
foreach(var param in @params)
3197+
{
3198+
if (param.Param.IsInOut && param.Param.Type.IsReferenceToPtrToClass())
3199+
{
3200+
var qualifiedClass = param.Param.Type.Visit(TypePrinter);
3201+
3202+
WriteLine($"if ({param.Name} != {param.Param.Name}.__Instance)");
3203+
WriteLine($"{param.Param.Name} = {qualifiedClass}.__GetOrCreateInstance(__{param.Name}, false);");
3204+
}
3205+
}
3206+
31963207
foreach (TextGenerator cleanup in from p in @params
31973208
select p.Context.Cleanup)
31983209
Write(cleanup);

tests/CSharp/CSharp.Tests.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1908,4 +1908,21 @@ public void TestFunctionTemplate()
19081908
Assert.That(CSharpTemplates.FunctionTemplate(6f), Is.EqualTo(6 + 4.1f));
19091909
Assert.That(CSharpTemplates.FunctionTemplate(7), Is.EqualTo(7 + 4));
19101910
}
1911+
1912+
[Test]
1913+
public void TestPatialRefSupport()
1914+
{
1915+
var myclass = new ClassWithIntValue();
1916+
var backup = myclass;
1917+
myclass.Value = 7;
1918+
1919+
CSharp.CSharp.ModifyCore(ref myclass);
1920+
Assert.That(myclass.Value, Is.EqualTo(10));
1921+
Assert.That(myclass, Is.SameAs(myclass));
1922+
1923+
CSharp.CSharp.CreateCore(ref myclass);
1924+
Assert.That(myclass.Value, Is.EqualTo(20));
1925+
Assert.That(myclass, Is.Not.SameAs(backup));
1926+
}
1927+
19111928
}

tests/CSharp/CSharp.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1535,4 +1535,19 @@ DLL_API int TestFunctionToInstanceMethodRefStruct(FTIStruct* bb, FTIStruct& defa
15351535
DLL_API int TestFunctionToInstanceMethodConstStruct(FTIStruct* bb, const FTIStruct defaultValue);
15361536
DLL_API int TestFunctionToInstanceMethodConstRefStruct(FTIStruct* bb, const FTIStruct& defaultValue);
15371537

1538-
class ClassWithoutNativeToManaged { };
1538+
class ClassWithoutNativeToManaged { };
1539+
1540+
struct DLL_API ClassWithIntValue {
1541+
int value;
1542+
};
1543+
1544+
DLL_API inline ClassWithIntValue* ModifyCore(CS_IN_OUT ClassWithIntValue*& pClass) {
1545+
pClass->value = 10;
1546+
return nullptr;
1547+
}
1548+
1549+
DLL_API inline ClassWithIntValue* CreateCore(CS_IN_OUT ClassWithIntValue*& pClass) {
1550+
pClass = new ClassWithIntValue();
1551+
pClass->value = 20;
1552+
return nullptr;
1553+
}

0 commit comments

Comments
 (0)