Browse Source

Support indirect parameters

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/1214/head
Dimitar Dobrev 6 years ago committed by João Matos
parent
commit
a9bfe1c31f
  1. 7
      src/CppParser/Parser.cpp
  2. 4
      src/Generator/Generators/CSharp/CSharpMarshal.cs
  3. 19
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs
  4. 9
      src/Generator/Passes/CheckAbiParameters.cs
  5. 12
      tests/Common/Common.Tests.cs

7
src/CppParser/Parser.cpp

@ -3286,14 +3286,11 @@ void Parser::WalkFunction(const clang::FunctionDecl* FD, Function* F, @@ -3286,14 +3286,11 @@ void Parser::WalkFunction(const clang::FunctionDecl* FD, Function* F,
F->isReturnIndirect = CGInfo.getReturnInfo().isIndirect();
unsigned Index = 0;
for (auto I = CGInfo.arg_begin(), E = CGInfo.arg_end(); I != E; I++)
for (const auto& Arg : CGInfo.arguments())
{
// Skip the first argument as it's the return type.
if (I == CGInfo.arg_begin())
continue;
if (Index >= F->Parameters.size())
continue;
F->Parameters[Index++]->isIndirect = I->info.isIndirect();
F->Parameters[Index++]->isIndirect = Arg.info.isIndirect();
}
MarkValidity(F);

4
src/Generator/Generators/CSharp/CSharpMarshal.cs

@ -551,6 +551,10 @@ namespace CppSharp.Generators.CSharp @@ -551,6 +551,10 @@ namespace CppSharp.Generators.CSharp
}
pointer.QualifiedPointee.Visit(this);
if (Context.Parameter.IsIndirect)
Context.ArgumentPrefix.Write("&");
bool isVoid = primitive == PrimitiveType.Void &&
pointee.IsAddress() && pointer.IsReference();
if (pointer.Pointee.Desugar(false) is TemplateParameterSubstitutionType ||

19
src/Generator/Generators/CSharp/CSharpTypePrinter.cs

@ -201,7 +201,8 @@ namespace CppSharp.Generators.CSharp @@ -201,7 +201,8 @@ namespace CppSharp.Generators.CSharp
// * Any pointer type.
// * Any user-defined struct type that contains fields of unmanaged types only.
var finalPointee = (pointee.GetFinalPointee() ?? pointee).Desugar();
if (finalPointee.IsPrimitiveType())
Enumeration @enum;
if (finalPointee.IsPrimitiveType() || finalPointee.TryGetEnum(out @enum))
{
// Skip one indirection if passed by reference
bool isRefParam = Parameter != null && (Parameter.IsOut || Parameter.IsInOut);
@ -220,18 +221,8 @@ namespace CppSharp.Generators.CSharp @@ -220,18 +221,8 @@ namespace CppSharp.Generators.CSharp
var result = pointer.QualifiedPointee.Visit(this);
allowStrings = true;
return !isRefParam && result.Type == IntPtrType ? "void**" : result + "*";
}
Enumeration @enum;
if (pointee.TryGetEnum(out @enum))
{
// Skip one indirection if passed by reference
if (isManagedContext && Parameter != null && (Parameter.IsOut || Parameter.IsInOut)
&& pointee == finalPointee)
return pointer.QualifiedPointee.Visit(this);
return pointer.QualifiedPointee.Visit(this) + "*";
string @ref = Parameter != null && Parameter.IsIndirect ? string.Empty : "*";
return !isRefParam && result.Type == this.IntPtrType ? "void**" : result + @ref;
}
Class @class;
@ -738,8 +729,6 @@ namespace CppSharp.Generators.CSharp @@ -738,8 +729,6 @@ namespace CppSharp.Generators.CSharp
public override TypePrinterResult VisitFieldDecl(Field field)
{
var cSharpSourcesDummy = new CSharpSources(Context, new List<TranslationUnit>());
PushMarshalKind(MarshalKind.NativeField);
var fieldTypePrinted = field.QualifiedType.Visit(this);
PopMarshalKind();

9
src/Generator/Passes/CheckAbiParameters.cs

@ -1,4 +1,6 @@ @@ -1,4 +1,6 @@
using CppSharp.AST;
using CppSharp.AST.Extensions;
using System.Linq;
namespace CppSharp.Passes
{
@ -79,7 +81,12 @@ namespace CppSharp.Passes @@ -79,7 +81,12 @@ namespace CppSharp.Passes
});
}
// TODO: Handle indirect parameters
foreach (var param in from p in function.Parameters
where p.IsIndirect && !p.Type.Desugar().IsAddress()
select p)
{
param.QualifiedType = new QualifiedType(new PointerType(param.QualifiedType));
}
return true;
}

12
tests/Common/Common.Tests.cs

@ -897,12 +897,14 @@ This is a very long string. This is a very long string. This is a very long stri @@ -897,12 +897,14 @@ This is a very long string. This is a very long string. This is a very long stri
}
}
[Test, Ignore("Indirect parameters not supported yet")]
[Test]
public void TestStructWithCopyCtorByValue()
{
var structWithCopyCtor = new StructWithCopyCtor();
structWithCopyCtor.MBits = 10;
var ret = Common.TestStructWithCopyCtorByValue(structWithCopyCtor);
Assert.That(ret, Is.EqualTo(10));
using (var structWithCopyCtor = new StructWithCopyCtor())
{
structWithCopyCtor.MBits = 10;
var ret = Common.TestStructWithCopyCtorByValue(structWithCopyCtor);
Assert.That(ret, Is.EqualTo(10));
}
}
}

Loading…
Cancel
Save