diff --git a/src/CppParser/Parser.cpp b/src/CppParser/Parser.cpp index d6497a7a..52508a87 100644 --- a/src/CppParser/Parser.cpp +++ b/src/CppParser/Parser.cpp @@ -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); diff --git a/src/Generator/Generators/CSharp/CSharpMarshal.cs b/src/Generator/Generators/CSharp/CSharpMarshal.cs index 73597be0..30f33b36 100644 --- a/src/Generator/Generators/CSharp/CSharpMarshal.cs +++ b/src/Generator/Generators/CSharp/CSharpMarshal.cs @@ -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 || diff --git a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs index cce03c1f..0a7167a9 100644 --- a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs +++ b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs @@ -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 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 public override TypePrinterResult VisitFieldDecl(Field field) { - var cSharpSourcesDummy = new CSharpSources(Context, new List()); - PushMarshalKind(MarshalKind.NativeField); var fieldTypePrinted = field.QualifiedType.Visit(this); PopMarshalKind(); diff --git a/src/Generator/Passes/CheckAbiParameters.cs b/src/Generator/Passes/CheckAbiParameters.cs index f1bc9130..eb454283 100644 --- a/src/Generator/Passes/CheckAbiParameters.cs +++ b/src/Generator/Passes/CheckAbiParameters.cs @@ -1,4 +1,6 @@ using CppSharp.AST; +using CppSharp.AST.Extensions; +using System.Linq; 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; } diff --git a/tests/Common/Common.Tests.cs b/tests/Common/Common.Tests.cs index c0409099..f53a2d94 100644 --- a/tests/Common/Common.Tests.cs +++ b/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 } } - [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)); + } } }