Skip to content

Commit a9bfe1c

Browse files
ddobrevtritao
authored andcommitted
Support indirect parameters
Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
1 parent 76ef6b0 commit a9bfe1c

File tree

5 files changed

+25
-26
lines changed

5 files changed

+25
-26
lines changed

src/CppParser/Parser.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3286,14 +3286,11 @@ void Parser::WalkFunction(const clang::FunctionDecl* FD, Function* F,
32863286
F->isReturnIndirect = CGInfo.getReturnInfo().isIndirect();
32873287

32883288
unsigned Index = 0;
3289-
for (auto I = CGInfo.arg_begin(), E = CGInfo.arg_end(); I != E; I++)
3289+
for (const auto& Arg : CGInfo.arguments())
32903290
{
3291-
// Skip the first argument as it's the return type.
3292-
if (I == CGInfo.arg_begin())
3293-
continue;
32943291
if (Index >= F->Parameters.size())
32953292
continue;
3296-
F->Parameters[Index++]->isIndirect = I->info.isIndirect();
3293+
F->Parameters[Index++]->isIndirect = Arg.info.isIndirect();
32973294
}
32983295

32993296
MarkValidity(F);

src/Generator/Generators/CSharp/CSharpMarshal.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,10 @@ public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
551551
}
552552

553553
pointer.QualifiedPointee.Visit(this);
554+
555+
if (Context.Parameter.IsIndirect)
556+
Context.ArgumentPrefix.Write("&");
557+
554558
bool isVoid = primitive == PrimitiveType.Void &&
555559
pointee.IsAddress() && pointer.IsReference();
556560
if (pointer.Pointee.Desugar(false) is TemplateParameterSubstitutionType ||

src/Generator/Generators/CSharp/CSharpTypePrinter.cs

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,8 @@ public override TypePrinterResult VisitPointerType(PointerType pointer,
201201
// * Any pointer type.
202202
// * Any user-defined struct type that contains fields of unmanaged types only.
203203
var finalPointee = (pointee.GetFinalPointee() ?? pointee).Desugar();
204-
if (finalPointee.IsPrimitiveType())
204+
Enumeration @enum;
205+
if (finalPointee.IsPrimitiveType() || finalPointee.TryGetEnum(out @enum))
205206
{
206207
// Skip one indirection if passed by reference
207208
bool isRefParam = Parameter != null && (Parameter.IsOut || Parameter.IsInOut);
@@ -220,18 +221,8 @@ public override TypePrinterResult VisitPointerType(PointerType pointer,
220221
var result = pointer.QualifiedPointee.Visit(this);
221222
allowStrings = true;
222223

223-
return !isRefParam && result.Type == IntPtrType ? "void**" : result + "*";
224-
}
225-
226-
Enumeration @enum;
227-
if (pointee.TryGetEnum(out @enum))
228-
{
229-
// Skip one indirection if passed by reference
230-
if (isManagedContext && Parameter != null && (Parameter.IsOut || Parameter.IsInOut)
231-
&& pointee == finalPointee)
232-
return pointer.QualifiedPointee.Visit(this);
233-
234-
return pointer.QualifiedPointee.Visit(this) + "*";
224+
string @ref = Parameter != null && Parameter.IsIndirect ? string.Empty : "*";
225+
return !isRefParam && result.Type == this.IntPtrType ? "void**" : result + @ref;
235226
}
236227

237228
Class @class;
@@ -738,8 +729,6 @@ private static string GetParameterUsage(ParameterUsage usage)
738729

739730
public override TypePrinterResult VisitFieldDecl(Field field)
740731
{
741-
var cSharpSourcesDummy = new CSharpSources(Context, new List<TranslationUnit>());
742-
743732
PushMarshalKind(MarshalKind.NativeField);
744733
var fieldTypePrinted = field.QualifiedType.Visit(this);
745734
PopMarshalKind();

src/Generator/Passes/CheckAbiParameters.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using CppSharp.AST;
2+
using CppSharp.AST.Extensions;
3+
using System.Linq;
24

35
namespace CppSharp.Passes
46
{
@@ -79,7 +81,12 @@ public override bool VisitFunctionDecl(Function function)
7981
});
8082
}
8183

82-
// TODO: Handle indirect parameters
84+
foreach (var param in from p in function.Parameters
85+
where p.IsIndirect && !p.Type.Desugar().IsAddress()
86+
select p)
87+
{
88+
param.QualifiedType = new QualifiedType(new PointerType(param.QualifiedType));
89+
}
8390

8491
return true;
8592
}

tests/Common/Common.Tests.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -897,12 +897,14 @@ public void TestReturnChar16()
897897
}
898898
}
899899

900-
[Test, Ignore("Indirect parameters not supported yet")]
900+
[Test]
901901
public void TestStructWithCopyCtorByValue()
902902
{
903-
var structWithCopyCtor = new StructWithCopyCtor();
904-
structWithCopyCtor.MBits = 10;
905-
var ret = Common.TestStructWithCopyCtorByValue(structWithCopyCtor);
906-
Assert.That(ret, Is.EqualTo(10));
903+
using (var structWithCopyCtor = new StructWithCopyCtor())
904+
{
905+
structWithCopyCtor.MBits = 10;
906+
var ret = Common.TestStructWithCopyCtorByValue(structWithCopyCtor);
907+
Assert.That(ret, Is.EqualTo(10));
908+
}
907909
}
908910
}

0 commit comments

Comments
 (0)