diff --git a/src/Generator/Passes/CheckAbiParameters.cs b/src/Generator/Passes/CheckAbiParameters.cs index 715fc790..b5fda0bc 100644 --- a/src/Generator/Passes/CheckAbiParameters.cs +++ b/src/Generator/Passes/CheckAbiParameters.cs @@ -2,6 +2,22 @@ namespace CppSharp.Passes { + /// + /// This pass checks for ABI-specific details that need to be fixed + /// in the generated code. + /// + /// In both the Microsoft and Itanium ABI, some functions return types + /// and parameter can be returned indirectly. In the case of an indirect + /// return type we need to add an extra pointer parameter to the function + /// and use that to call the function instead. In the case of parameters + /// then the type of that parameter is converted to a pointer. + /// + /// Itanium ABI reference (3.1.4 Return values): + /// http://refspecs.linux-foundation.org/cxxabi-1.83.html#calls + /// + /// Microsoft ABI reference: + /// http://blog.aaronballman.com/2012/02/describing-the-msvc-abi-for-structure-return-types/ + /// public class CheckAbiParameters : TranslationUnitPass { private readonly DriverOptions options; @@ -11,41 +27,28 @@ namespace CppSharp.Passes this.options = options; } - public override bool VisitMethodDecl(Method method) + public override bool VisitFunctionDecl(Function function) { - if (!NeedsHiddenStructParameterReturn(method, options)) - return true; - - var structParameter = new Parameter() - { - Kind = ParameterKind.HiddenStructureReturn, - QualifiedType = method.ReturnType, - Name = "return", - }; - - method.Parameters.Insert(0, structParameter); - method.ReturnType = new QualifiedType(new BuiltinType(PrimitiveType.Void)); - - return true; - } + if (AlreadyVisited(function)) + return false; - public static bool NeedsHiddenStructParameterReturn(Method method, DriverOptions options) - { - // In both the Microsoft and Itanium ABI, functions returning - // structure types by value have an extra parameter - // Itanium ABI reference (3.1.4 Return values): - // http://refspecs.linux-foundation.org/cxxabi-1.83.html#calls - // Microsoft ABI reference: - // http://blog.aaronballman.com/2012/02/describing-the-msvc-abi-for-structure-return-types/ + if (function.IsReturnIndirect) + { + var indirectParam = new Parameter() + { + Kind = ParameterKind.IndirectReturnType, + QualifiedType = function.ReturnType, + Name = "return", + }; - Class retClass; - if (!method.ReturnType.Type.IsTagDecl(out retClass)) - return false; + function.Parameters.Insert(0, indirectParam); + function.ReturnType = new QualifiedType(new BuiltinType( + PrimitiveType.Void)); + } - // TODO: Add the various combinations for that need hidden parameter - var needsMSHiddenPtr = options.IsMicrosoftAbi && method.IsThisCall; + // TODO: Handle indirect parameters - return needsMSHiddenPtr || options.IsItaniumAbi; + return true; } } }