public bool TryGetParameterVariant(Parameter parameter, out Parameter variant, Project core)
        {
            if (parameter.Type.OriginalGroup is null || core.Enums.All
                    (x => x.Name != parameter.Type.OriginalGroup) /* || (parameter.Type.OriginalName != "GLenum" &&
                                                                   *   parameter.Type.OriginalName != "CLenum")*/)
            {
                variant = null;
                return(false);
            }

            var t =
                new TypeSignatureBuilder(parameter.Type).WithName
                    (parameter.Type.OriginalGroup)
                .Build();

            t.OriginalName = t.Name; // stop GLenum mapping
            variant        =
                new ParameterSignatureBuilder(parameter).WithType
                (
                    t
                )
                .Build()
            ;
            return(true);
        }
        /// <inheritdoc/>
        public IEnumerable <Overload> CreateOverloads(Function function)
        {
            if (!IsApplicable(function))
            {
                yield break;
            }

            var arrayParameter     = function.Parameters.Last();
            var arrayParameterType = arrayParameter.Type;

            var newName       = function.Name.Singularize(false);
            var newParameters = SkipLastExtension.SkipLast(new List <Parameter>(function.Parameters), 2).ToList();

            var newArrayParameterType = new TypeSignatureBuilder(arrayParameterType)
                                        .WithArrayDimensions(0)
                                        .WithIndirectionLevel(0)
                                        .Build();

            var newArrayParameter = new ParameterSignatureBuilder(arrayParameter)
                                    .WithType(newArrayParameterType)
                                    .Build();

            newParameters.Add(newArrayParameter);

            var sb = new StringBuilder();

            sb.AppendLine("// ArrayParameterOverloader");
            sb.AppendLine(function.Name + "(1, &" + newArrayParameter.Name + ");");

            yield return(new Overload(new FunctionSignatureBuilder(function)
                                      .WithName(newName)
                                      .WithParameters(newParameters)
                                      .Build(), sb, true));
        }
Exemple #3
0
        public bool TryGetParameterVariant(Parameter parameter, out Parameter variant, Project core)
        {
            if (parameter.Type.ToString() == "char*" || parameter.Type.ToString() == "byte*" ||
                parameter.Type.ToString() == "GLchar*" || parameter.Type.ToString() == "GLbyte*" ||
                parameter.Type.ToString() == "GLubyte*")
            {
                var variantBuilder = new ParameterSignatureBuilder(parameter)
                                     .WithType
                                     (
                    new Type
                {
                    Name  = "string", IndirectionLevels = 0,
                    IsOut = parameter.Flow == FlowDirection.Out &&
                            ((parameter.Count?.IsStatic ?? false) || (parameter.Count?.IsReference ?? false))
                }
                                     );

                if (!(parameter.Flow == FlowDirection.Out &&
                      ((parameter.Count?.IsStatic ?? false) || (parameter.Count?.IsReference ?? false))))
                {
                    variantBuilder = variantBuilder.WithCount(null);
                }

                variant = variantBuilder.Build();

                return(true);
            }

            variant = null;
            return(false);
        }
        public IEnumerable <ImplementedFunction> CreateOverloads(Function function)
        {
            var @params = new List <Parameter>(function.Parameters);
            var sb      = new StringBuilder();

            sb.AppendLine("// IntPtrOverloader");
            if (function.ReturnType.ToString() != "void")
            {
                sb.Append("return ");
            }

            sb.Append($"{function.Name}(");
            var ret = false;

            for (var i = 0; i < function.Parameters.Count; i++)
            {
                var parameter     = function.Parameters[i];
                var parameterName = Utilities.CSharpKeywords.Contains(parameter.Name)
                    ? $"@{parameter.Name}"
                    : parameter.Name;
                if (parameter.Type.IsIntPtr() && !(parameter.Type.IsOut))
                {
                    @params[i] = new ParameterSignatureBuilder(parameter)
                                 .WithType(new TypeSignatureBuilder(parameter.Type).WithName("int").Build())
                                 .Build();
                    sb.Append($"new IntPtr({parameterName})");
                    ret = true;
                }
                else if (parameter.Type.IsUIntPtr() && !(parameter.Type.IsOut))
                {
                    @params[i] = new ParameterSignatureBuilder(parameter)
                                 .WithType(new TypeSignatureBuilder(parameter.Type).WithName("uint").Build())
                                 .Build();
                    sb.Append($"new UIntPtr({parameterName})");
                    ret = true;
                }
                else
                {
                    var prefix = parameter.Type.IsOut ? "out " : parameter.Type.IsByRef ? "ref " : string.Empty;
                    sb.Append($"{prefix}{parameterName}");
                }

                if (i != function.Parameters.Count - 1)
                {
                    sb.Append(", ");
                }
            }

            sb.AppendLine(");");

            if (ret)
            {
                yield return(new ImplementedFunction(new FunctionSignatureBuilder(function).WithParameters(@params).Build(), sb));
            }
        }
        /// <inheritdoc/>
        public IEnumerable <FunctionSignature> CreateOverloads(FunctionSignature function)
        {
            var baseParameters = function.Parameters;

            var staticCountPermutation = new List <ParameterSignature>(baseParameters);

            for (int i = 0; i < baseParameters.Count; ++i)
            {
                var baseParameter = baseParameters[i];
                var baseType      = baseParameter.Type;

                if (!HasStaticCount(baseParameter))
                {
                    continue;
                }

                // ReSharper disable once PossibleNullReferenceException
                var count = baseParameter.Count.Count;

                if (count > 1)
                {
                    // TODO: Support higher-ranked types
                    continue;
                }

                if (!baseType.IsPointer || baseType.IndirectionLevel > 1)
                {
                    continue;
                }

                var refTypeBuilder = new TypeSignatureBuilder(baseType)
                                     .WithIndirectionLevel(0)
                                     .WithByRef(true);

                if (baseParameter.Flow == FlowDirection.Out)
                {
                    refTypeBuilder = refTypeBuilder.WithIsOut(true);
                }

                var refType = refTypeBuilder.Build();

                var refParameter = new ParameterSignatureBuilder(baseParameter)
                                   .WithType(refType)
                                   .Build();

                staticCountPermutation[i] = refParameter;
            }

            yield return(new FunctionSignatureBuilder(function)
                         .WithParameters(staticCountPermutation)
                         .Build());
        }
        public IEnumerable <Overload> CreateOverloads(Function function)
        {
            var @params = new List <Parameter>(function.Parameters);
            var sb      = new StringBuilder();

            sb.AppendLine("// IntPtrOverloader");
            if (function.ReturnType.ToString() != "void")
            {
                sb.Append("return ");
            }

            sb.Append(function.Name + "(");
            var ret = false;

            for (var i = 0; i < function.Parameters.Count; i++)
            {
                var parameter = function.Parameters[i];
                if (parameter.Type.IsIntPtr())
                {
                    @params[i] = new ParameterSignatureBuilder(parameter)
                                 .WithType(new TypeSignatureBuilder(parameter.Type).WithName("int").Build())
                                 .Build();
                    sb.Append("new IntPtr(" + parameter.Name + ")");
                    ret = true;
                }
                else if (parameter.Type.IsUIntPtr())
                {
                    @params[i] = new ParameterSignatureBuilder(parameter)
                                 .WithType(new TypeSignatureBuilder(parameter.Type).WithName("uint").Build())
                                 .Build();
                    sb.Append("new UIntPtr(" + parameter.Name + ")");
                    ret = true;
                }
                else
                {
                    sb.Append(parameter.Name);
                }

                if (i != function.Parameters.Count - 1)
                {
                    sb.Append(", ");
                }
            }

            sb.AppendLine(");");

            if (ret)
            {
                yield return(new Overload(new FunctionSignatureBuilder(function).WithParameters(@params).Build(), sb));
            }
        }
        private IEnumerable <FunctionSignature> MapGenericEnumFunctions
        (
            [NotNull] ApiProfile profile,
            [NotNull, ItemNotNull] IReadOnlyList <FunctionSignature> genericEnumFunctions
        )
        {
            var mappedGenericEnumFunctions = new List <FunctionSignature>();

            foreach (var functionWithGenericEnum in genericEnumFunctions)
            {
                var newParameters = new List <ParameterSignature>(functionWithGenericEnum.Parameters);
                for (var i = 0; i < newParameters.Count; ++i)
                {
                    var parameter     = newParameters[i];
                    var parameterType = parameter.Type;

                    if (parameterType.Name != "GLenum")
                    {
                        continue;
                    }

                    var newParameterType = MapGenericEnumerationType(profile, functionWithGenericEnum, parameterType);
                    var newParameter     = new ParameterSignatureBuilder(parameter).WithType(newParameterType).Build();

                    newParameters[i] = newParameter;
                }

                var newReturnType = functionWithGenericEnum.ReturnType;
                if (newReturnType.Name == "GLenum")
                {
                    newReturnType = MapGenericEnumerationType(profile, functionWithGenericEnum, newReturnType);
                }

                var newFunction = new FunctionSignatureBuilder(functionWithGenericEnum)
                                  .WithParameters(newParameters)
                                  .WithReturnType(newReturnType)
                                  .Build();

                mappedGenericEnumFunctions.Add(newFunction);

                Debug.WriteLine
                (
                    $"Mapped parameters in \"{functionWithGenericEnum.Name}\" to generic enum types. Consider adding" +
                    " an override to a more specialized enum."
                );
            }

            return(mappedGenericEnumFunctions);
        }
Exemple #8
0
        public bool TryCreateVariant(Parameter parameter, out Parameter variant, Project core)
        {
            if (parameter.Type.ToString() == "char*" || parameter.Type.ToString() == "byte*" ||
                parameter.Type.ToString() == "GLchar*" || parameter.Type.ToString() == "GLbyte*" ||
                parameter.Type.ToString() == "GLubyte*")
            {
                variant = new ParameterSignatureBuilder(parameter)
                          .WithType
                          (
                    new Type
                {
                    Name  = "string", IndirectionLevels = 0,
                    IsOut = parameter.Flow == FlowDirection.Out &&
                            ((parameter.Count?.IsStatic ?? false) || (parameter.Count?.IsReference ?? false))
                }
                          )
                          .WithCount(null) // scrap the count as it causes trouble later down the line
                          .Build();

                if (variant.Type.IsOut)
                {
                    variant.Attributes.Add
                    (
                        new Attribute
                    {
                        Name      = "Ultz.SuperInvoke.InteropServices.CountAttribute",
                        Arguments = new List <string>
                        {
                            parameter.Count.IsStatic
                                    ? "Ultz.SuperInvoke.InteropServices.CountType.Constant"
                                    : "Ultz.SuperInvoke.InteropServices.CountType.ParameterReference",
                            (parameter.Count.IsStatic
                                    ? parameter.Count.StaticCount
                                    : parameter.Origin.Parameters.FindIndex
                                 (x => x.Name == parameter.Count.ValueReference) -
                             parameter.Origin.Parameters.IndexOf(parameter)).ToString()
                        }
                    }
                    );
                }

                return(true);
            }

            variant = null;
            return(false);
        }
        public bool TryGetParameterVariant(Parameter parameter, out Parameter variant, Project core)
        {
            Struct s;

            if (parameter.Type.OriginalClass is null || (s = core.Structs.FirstOrDefault
                                                                 (x => x.NativeName == parameter.Type.OriginalClass)) is null)
            {
                variant = null;
                return(false);
            }

            var t = new TypeSignatureBuilder(parameter.Type).WithName(s.Name).Build();

            t.OriginalName = t.Name; // stop GLenum mapping
            variant        = new ParameterSignatureBuilder(parameter).WithType(t).Build();
            return(true);
        }
        public bool TryGetParameterVariant(Parameter parameter, out Parameter varied, Project core)
        {
            if (parameter.Type.IsPointer)
            {
                varied = new ParameterSignatureBuilder(parameter).WithType
                         (
                    new TypeSignatureBuilder(parameter.Type)
                    .WithIndirectionLevel(parameter.Type.IndirectionLevels - 1)
                    .WithByRef(parameter.Flow != FlowDirection.In && parameter.Flow != FlowDirection.Out)
                    .WithIsIn(parameter.Flow == FlowDirection.In)
                    .WithIsOut(parameter.Flow == FlowDirection.Out)
                    .WithIsGenericType(parameter.Type.IndirectionLevels == 1 && parameter.Type.Name == "void")
                    .Build()
                         )
                         .Build();
                return(true);
            }

            varied = null;
            return(false);
        }
Exemple #11
0
        public bool TryGetParameterVariant(Parameter parameter, out Parameter variant, Project core)
        {
            if (parameter.Type.ToString() == "char*" || parameter.Type.ToString() == "byte*" ||
                parameter.Type.ToString() == "GLchar*" || parameter.Type.ToString() == "GLbyte*" ||
                parameter.Type.ToString() == "GLubyte*")
            {
                var variantBuilder = new ParameterSignatureBuilder(parameter)
                                     .WithType
                                     (
                    new Type
                {
                    Name  = "string", IndirectionLevels = 0,
                    IsOut = parameter.Flow == FlowDirection.Out &&
                            ((parameter.Count?.IsStatic ?? false) || (parameter.Count?.IsReference ?? false)),
                    OriginalName = parameter.Type.OriginalName
                }
                                     );

                if (!(parameter.Flow == FlowDirection.Out &&
                      ((parameter.Count?.IsStatic ?? false) || (parameter.Count?.IsReference ?? false))))
                {
                    variantBuilder = variantBuilder.WithCount(null);
                }

                variant = variantBuilder.Build();
                variant.Attributes.Add
                (
                    new()
                {
                    Name      = "UnmanagedType",
                    Arguments = new() { variant.Type.MapUnmanagedType() }
                }
                );

                return(true);
            }

            variant = null;
            return(false);
        }
        /// <inheritdoc/>
        public bool TryGetFunctionVariant(Function function, out ImplementedFunction overload, Project core)
        {
            if (!IsApplicable(function))
            {
                overload = null;
                return(false);
            }

            var arrayParameter     = function.Parameters.Last();
            var arrayParameterType = arrayParameter.Type;

            var newName       = function.Name.Singularize(false);
            var newParameters = SkipLastExtension.SkipLast(new List <Parameter>(function.Parameters), 2).ToList();

            var newArrayParameterType = new TypeSignatureBuilder(arrayParameterType)
                                        .WithArrayDimensions(0)
                                        .WithIndirectionLevel(0)
                                        .Build();

            var newArrayParameter = new ParameterSignatureBuilder(arrayParameter)
                                    .WithType(newArrayParameterType)
                                    .Build();

            newParameters.Add(newArrayParameter);

            var sb = new StringBuilder();

            sb.AppendLine("// ArrayParameterOverloader");
            sb.AppendLine($"{function.Name}(1, &{newArrayParameter.Name});");

            overload = new ImplementedFunction(new FunctionSignatureBuilder(function)
                                               .WithName(newName)
                                               .WithParameters(newParameters)
                                               .Build(), sb, function, true);
            return(true);
        }
Exemple #13
0
        /// <inheritdoc/>
        public IEnumerable <FunctionSignature> CreateOverloads(FunctionSignature function)
        {
            var arrayParameter     = function.Parameters.Last();
            var arrayParameterType = arrayParameter.Type;

            var newName       = function.Name.Singularize(false);
            var newParameters = SkipLastExtension.SkipLast(new List <ParameterSignature>(function.Parameters), 2).ToList();

            var newArrayParameterType = new TypeSignatureBuilder(arrayParameterType)
                                        .WithArrayDimensions(0)
                                        .WithIndirectionLevel(0)
                                        .Build();

            var newArrayParameter = new ParameterSignatureBuilder(arrayParameter)
                                    .WithType(newArrayParameterType)
                                    .Build();

            newParameters.Add(newArrayParameter);

            yield return(new FunctionSignatureBuilder(function)
                         .WithName(newName)
                         .WithParameters(newParameters)
                         .Build());
        }
        /// <inheritdoc/>
        public IEnumerable <(FunctionSignature, StringBuilder)> CreateOverloads(FunctionSignature function)
        {
            if (!function.Parameters.Any(p => p.Type.IsVoidPointer()))
            {
                yield break;
            }

            var baseParameters = function.Parameters;

            var newIntPtrParameters         = new List <ParameterSignature>(baseParameters);
            var newGenericArray1DParameters = new List <ParameterSignature>(baseParameters);
            var newGenericArray2DParameters = new List <ParameterSignature>(baseParameters);
            var newGenericArray3DParameters = new List <ParameterSignature>(baseParameters);

            var newGenericTypeParameters = new List <GenericTypeParameterSignature>();

            for (var i = 0; i < baseParameters.Count; ++i)
            {
                var parameter = baseParameters[i];
                if (!parameter.Type.IsVoidPointer())
                {
                    continue;
                }

                var genericTypeParameterName = baseParameters.Count(p => p.Type.IsVoidPointer()) > 1
                    ? $"T{newGenericTypeParameters.Count + 1}" : "T";

                var genericTypeParameter = new GenericTypeParameterSignature(
                    genericTypeParameterName,
                    new[] { "unmanaged" });

                newGenericTypeParameters.Add(genericTypeParameter);

                var newIntPtrParameterType = new TypeSignatureBuilder(parameter.Type)
                                             .WithIndirectionLevel(0)
                                             .WithName(nameof(IntPtr))
                                             .Build();

                // TODO: Simplify and generalize this
                var newGenericArray1DParameterType = new TypeSignatureBuilder(parameter.Type)
                                                     .WithIndirectionLevel(0)
                                                     .WithArrayDimensions(1)
                                                     .WithName(genericTypeParameterName)
                                                     .Build();

                var newGenericArray2DParameterType = new TypeSignatureBuilder(parameter.Type)
                                                     .WithIndirectionLevel(0)
                                                     .WithArrayDimensions(2)
                                                     .WithName(genericTypeParameterName)
                                                     .Build();

                var newGenericArray3DParameterType = new TypeSignatureBuilder(parameter.Type)
                                                     .WithIndirectionLevel(0)
                                                     .WithArrayDimensions(3)
                                                     .WithName(genericTypeParameterName)
                                                     .Build();

                newIntPtrParameters[i] = new ParameterSignatureBuilder(parameter)
                                         .WithType(newIntPtrParameterType)
                                         .Build();

                newGenericArray1DParameters[i] = new ParameterSignatureBuilder(parameter)
                                                 .WithType(newGenericArray1DParameterType)
                                                 .Build();

                newGenericArray2DParameters[i] = new ParameterSignatureBuilder(parameter)
                                                 .WithType(newGenericArray2DParameterType)
                                                 .Build();

                newGenericArray3DParameters[i] = new ParameterSignatureBuilder(parameter)
                                                 .WithType(newGenericArray3DParameterType)
                                                 .Build();
            }

            yield return(ToPointer
                         (
                             new FunctionSignatureBuilder(function)
                             .WithParameters(newIntPtrParameters)
                             .Build(),
                             function
                         ));

            yield return(Fixed
                         (
                             new FunctionSignatureBuilder(function)
                             .WithParameters(newGenericArray1DParameters)
                             .WithGenericTypeParameters(newGenericTypeParameters)
                             .Build()
                         ));

            yield return(Fixed
                         (
                             new FunctionSignatureBuilder(function)
                             .WithParameters(newGenericArray2DParameters)
                             .WithGenericTypeParameters(newGenericTypeParameters)
                             .Build()
                         ));

            yield return(Fixed
                         (
                             new FunctionSignatureBuilder(function)
                             .WithParameters(newGenericArray3DParameters)
                             .WithGenericTypeParameters(newGenericTypeParameters)
                             .Build()
                         ));
        }
        public IEnumerable <Overload> CreateOverloads(Function function)
        {
            if (!function.Parameters.Any(IsApplicable))
            {
                yield break;
            }

            var newParameters = new List <Parameter>(function.Parameters);
            var sb            = new StringBuilder();

            for (var i = 0; i < newParameters.Count; i++)
            {
                var param = newParameters[i];
                if (!IsApplicable(param))
                {
                    continue;
                }

                sb.AppendLine("// StaticCountOverloader");
                sb.Append("var " + param.Name + " = stackalloc " + param.Type.Name);
                sb.AppendLine("[" + param.Count.StaticCount + "];");
                for (var j = 0; j < param.Count.StaticCount; j++)
                {
                    if (j == 0)
                    {
                        newParameters[i + j] = new ParameterSignatureBuilder(param)
                                               .WithName(param.Name + j)
                                               .WithType(new TypeSignatureBuilder(param.Type).WithIndirectionLevel(0).Build())
                                               .WithCount(null)
                                               .Build();
                    }
                    else
                    {
                        newParameters.Insert(i + (j - 1), new ParameterSignatureBuilder(param)
                                             .WithName(param.Name + j)
                                             .WithCount(null)
                                             .WithType(new TypeSignatureBuilder(param.Type).WithIndirectionLevel(0).Build())
                                             .Build());
                    }

                    sb.AppendLine(param.Name + "[" + j + "] = " + param.Name + j + ";");
                }
            }

            if (function.ReturnType.ToString() != "void")
            {
                sb.Append("return ");
            }

            sb.Append(function.Name + "(");
            sb.Append(string.Join(", ", function.Parameters.Select(x => Format(x.Name))));
            sb.Append(");");
            sb.AppendLine();

            yield return(new Overload
                         (
                             new FunctionSignatureBuilder(function).WithParameters(newParameters).Build(),
                             sb,
                             true
                         ));

            string Format(string n)
            {
                if (Utilities.CSharpKeywords.Contains(n))
                {
                    return("@" + n);
                }

                return(n);
            }
        }
Exemple #16
0
        public IEnumerable <ImplementedFunction> CreateOverloads(Function function)
        {
            for (var i = 0; i < function.Parameters.Count; i++)
            {
                var param = function.Parameters[i];
                if (param.Type.ToString() == "char**" && !param.Type.IsOut)
                {
                    var parameters = function.Parameters.ToArray();
                    var o          = new StringBuilder();
                    parameters[i] = new ParameterSignatureBuilder(param).WithType
                                    (
                        new Type
                    {
                        Name            = "string",
                        ArrayDimensions = 1
                    }
                                    )
                                    .Build();
                    o.AppendLine
                        ($"var {param.Name}_o = SilkMarshal.MarshalStringArrayToPtr({ConvertName(param.Name)});");
                    if (function.ReturnType.ToString() != "void")
                    {
                        o.Append("var silkReturn = ");
                    }

                    o.Append(function.Name);
                    o.Append("(");
                    o.Append
                    (
                        string.Join
                        (
                            ", ", function.Parameters.Select((x, j) => j == i ? $"(char**){param.Name}_o" : Convert(x))
                        )
                    );
                    o.AppendLine(");");
                    o.AppendLine($"SilkMarshal.FreeStringArrayPtr({param.Name}_o, {ConvertName(param.Name)}.Length);");
                    if (function.ReturnType.ToString() != "void")
                    {
                        o.Append("return silkReturn;");
                    }

                    yield return(new ImplementedFunction
                                     (new FunctionSignatureBuilder(function).WithParameters(parameters).Build(), o, true));
                }
                else if ((param.Type.ToString() == "char*" || param.Type.ToString() == "byte*") &&
                         function.Parameters.Any
                             (x => x.Name == param.Count?.ValueReference) && param.Flow == FlowDirection.Out)
                {
                    var parameters = function.Parameters.ToArray();
                    var o          = new StringBuilder();
                    o.AppendLine($"var {param.Name}_s = SilkMarshal.NewStringPtr({param.Count.ValueReference});");
                    parameters[i] = new ParameterSignatureBuilder(param).WithType
                                        (new Type {
                        Name = "string", IsOut = true
                    })
                                    .Build();
                    if (function.ReturnType.ToString() != "void")
                    {
                        o.Append("var silkReturn = ");
                    }

                    o.Append(function.Name);
                    o.Append("(");
                    o.Append
                    (
                        string.Join
                        (
                            ", ", function.Parameters.Select((x, j) => j == i ? $"({param.Type}){param.Name}_s" : Convert(x))
                        )
                    );
                    o.AppendLine(");");
                    o.AppendLine($"{ConvertName(param.Name)} = SilkMarshal.MarshalPtrToString({param.Name}_s);");
                    o.AppendLine($"SilkMarshal.FreeStringPtr({param.Name}_s);");
                    if (function.ReturnType.ToString() != "void")
                    {
                        o.Append("return silkReturn;");
                    }

                    yield return(new ImplementedFunction
                                     (new FunctionSignatureBuilder(function).WithParameters(parameters).Build(), o, true));
                }
                else if ((param.Type.ToString() == "char*" || param.Type.ToString() == "byte*") && !param.Type.IsOut)
                {
                    var parameters = function.Parameters.ToArray();
                    var o          = new StringBuilder();
                    o.AppendLine($"var {param.Name}_s = SilkMarshal.MarshalStringToPtr({ConvertName(param.Name)});");
                    parameters[i] = new ParameterSignatureBuilder(param).WithType(new Type {
                        Name = "string"
                    }).Build();
                    if (function.ReturnType.ToString() != "void")
                    {
                        o.Append("var silkReturn = ");
                    }

                    o.Append(function.Name);
                    o.Append("(");
                    o.Append
                    (
                        string.Join
                        (
                            ", ", function.Parameters.Select((x, j) => j == i ? $"({param.Type}){param.Name}_s" : Convert(x))
                        )
                    );
                    o.AppendLine(");");
                    o.AppendLine($"{ConvertName(param.Name)} = SilkMarshal.MarshalPtrToString({param.Name}_s);");
                    o.AppendLine($"SilkMarshal.FreeStringPtr({param.Name}_s);");
                    if (function.ReturnType.ToString() != "void")
                    {
                        o.Append("return silkReturn;");
                    }

                    yield return(new ImplementedFunction
                                     (new FunctionSignatureBuilder(function).WithParameters(parameters).Build(), o, true));
                }
            }
        }
        public bool TryCreateVariant(Function function, out Function variant, Project core)
        {
            var varied     = false;
            var parameters = new List <Parameter>();

            parameters.AddRange(function.Parameters);
            var genericParams = new List <GenericTypeParameter>();

            for (var i = 0; i < parameters.Count; i++)
            {
                var param    = parameters[i];
                var typeName = param.Type.Name == "void" ? $"T{genericParams.Count}" : param.Type.Name;
                if (param.Type.Name == "void")
                {
                    genericParams.Add
                    (
                        new GenericTypeParameter
                    {
                        Name = $"T{genericParams.Count}", Constraints = new List <string> {
                            "unmanaged"
                        }
                    }
                    );
                }

                if (param.Type.IndirectionLevels == 1 && (param.Count?.IsMultiple ?? true))
                {
                    varied        = true;
                    parameters[i] = new ParameterSignatureBuilder(param).WithType
                                    (
                        new Type
                    {
                        GenericTypes = new List <Type>
                        {
                            new TypeSignatureBuilder(param.Type).WithName(typeName).WithIndirectionLevel(0).Build()
                        },
                        Name = "Span"
                    }
                                    )
                                    .Build();
                    continue;
                }

                if (param.Type.IsPointer && !(param.Count?.IsMultiple ?? true))
                {
                    varied        = true;
                    parameters[i] = new ParameterSignatureBuilder(param).WithType
                                    (
                        new TypeSignatureBuilder(param.Type)
                        .WithIndirectionLevel(param.Type.IndirectionLevels - 1)
                        .WithName(typeName)
                        .WithByRef(param.Flow != FlowDirection.Out)
                        .WithIsOut(param.Flow == FlowDirection.Out)
                        .Build()
                                    )
                                    .Build();
                }
            }

            if (varied)
            {
                variant = new FunctionSignatureBuilder(function).WithParameters
                              (parameters)
                          .WithGenericTypeParameters(genericParams)
                          .Build();
                return(true);
            }

            variant = null;
            return(false);
        }
Exemple #18
0
        public IEnumerable <ImplementedFunction> CreateOverloads(Function function)
        {
            var returnTypeChanged = false;
            var parameterChanged  = false;
            var sb = new StringBuilder();

            sb.AppendLine("// SpanOverloader");
            var parameters = function.Parameters.ToList();
            var fun        = new FunctionSignatureBuilder(function);
            // TODO we need a length for span returns, so I've disabled them for now
            //if (function.ReturnType.IndirectionLevels == 1 && function.ReturnType.Name != "void")
            //{
            //    fun.WithReturnType
            //    (
            //        new Type
            //        {
            //            Name = "Span", OriginalName = "Span",
            //            GenericTypes = new List<Type> {new Type {Name = function.ReturnType.Name}}
            //        }
            //    );
            //    returnTypeChanged = true;
            //}

            var ind = string.Empty;

            for (var i = 0; i < function.Parameters.Count; i++)
            {
                var param = function.Parameters[i];
                if (param.Type.IndirectionLevels == 1 && param.Type.Name != "void" && !param.Type.IsOut && !param.Type.IsIn && !param.Type.IsByRef)
                {
                    parameterChanged = true;
                    parameters[i]    = new ParameterSignatureBuilder(param).WithName($"{param.Name}Span")
                                       .WithType
                                       (
                        new Type
                    {
                        Name         = "Span", OriginalName = "Span",
                        GenericTypes = new List <Type>
                        {
                            new Type {
                                Name = param.Type.Name, OriginalName = param.Type.OriginalName
                            }
                        }
                    }
                                       )
                                       .Build();
                    sb.AppendLine($"{ind}fixed ({param.Type} {param.Name} = {param.Name}Span)");
                    sb.AppendLine($"{ind}{{");
                    ind += "    ";
                }
                else
                {
                    parameters[i] = param;
                }
            }

            if (returnTypeChanged)
            {
                sb.Append($"{ind}return (Span<{function.ReturnType.Name}>) ");
            }
            else if (function.ReturnType.ToString() != "void")
            {
                sb.Append($"{ind}return ");
            }
            else
            {
                sb.Append(ind);
            }

            sb.Append($"{function.Name}(");
            sb.Append(string.Join(", ", function.Parameters.Select(x => GetPrefix(x.Type) + Format(x.Name))));
            sb.AppendLine(");");

            while (!string.IsNullOrEmpty(ind))
            {
                ind = ind.Remove(ind.Length - 4, 4);
                sb.AppendLine($"{ind}}}");
            }

            fun.WithParameters(parameters);

            if (returnTypeChanged && !parameterChanged)
            {
                yield return(new ImplementedFunction(fun.WithName($"{function.Name}AsSpan").Build(), sb, true));
            }
            else if (parameterChanged)
            {
                yield return(new ImplementedFunction(fun.Build(), sb, true));
            }

            string GetPrefix(Type t)
            {
                return(t.IsOut ? "out " : t.IsByRef ? "ref " : string.Empty);
            }

            string Format(string n)
            {
                if (Utilities.CSharpKeywords.Contains(n))
                {
                    return($"@{n}");
                }

                return(n);
            }
        }
Exemple #19
0
        /// <inheritdoc/>
        public IEnumerable <FunctionSignature> CreateOverloads(FunctionSignature function)
        {
            var baseParameters = function.Parameters;

            var newIntPtrParameters         = new List <ParameterSignature>(baseParameters);
            var newGenericArray1DParameters = new List <ParameterSignature>(baseParameters);
            var newGenericArray2DParameters = new List <ParameterSignature>(baseParameters);
            var newGenericArray3DParameters = new List <ParameterSignature>(baseParameters);
            var newGenericRefParameters     = new List <ParameterSignature>(baseParameters);

            var newGenericTypeParameters = new List <GenericTypeParameterSignature>();

            for (int i = 0; i < baseParameters.Count; ++i)
            {
                var parameter = baseParameters[i];
                if (!parameter.Type.IsVoidPointer())
                {
                    continue;
                }

                string genericTypeParameterName;
                if (baseParameters.Count(p => p.Type.IsVoidPointer()) > 1)
                {
                    genericTypeParameterName = $"T{newGenericTypeParameters.Count + 1}";
                }
                else
                {
                    genericTypeParameterName = "T";
                }

                var genericTypeParameter = new GenericTypeParameterSignature(genericTypeParameterName);

                newGenericTypeParameters.Add(genericTypeParameter);

                var newIntPtrParameterType = new TypeSignatureBuilder(parameter.Type)
                                             .WithIndirectionLevel(0)
                                             .WithName(nameof(IntPtr))
                                             .Build();

                // TODO: Simplify and generalize this
                var newGenericArray1DParameterType = new TypeSignatureBuilder(parameter.Type)
                                                     .WithIndirectionLevel(0)
                                                     .WithArrayDimensions(1)
                                                     .WithName(genericTypeParameterName)
                                                     .Build();

                var newGenericArray2DParameterType = new TypeSignatureBuilder(parameter.Type)
                                                     .WithIndirectionLevel(0)
                                                     .WithArrayDimensions(2)
                                                     .WithName(genericTypeParameterName)
                                                     .Build();

                var newGenericArray3DParameterType = new TypeSignatureBuilder(parameter.Type)
                                                     .WithIndirectionLevel(0)
                                                     .WithArrayDimensions(3)
                                                     .WithName(genericTypeParameterName)
                                                     .Build();

                var newGenericRefParameterType = new TypeSignatureBuilder(parameter.Type)
                                                 .WithIndirectionLevel(0)
                                                 .WithName(genericTypeParameterName)
                                                 .WithByRef(true)
                                                 .Build();

                newIntPtrParameters[i] = new ParameterSignatureBuilder(parameter)
                                         .WithType(newIntPtrParameterType)
                                         .Build();

                newGenericArray1DParameters[i] = new ParameterSignatureBuilder(parameter)
                                                 .WithType(newGenericArray1DParameterType)
                                                 .Build();

                newGenericArray2DParameters[i] = new ParameterSignatureBuilder(parameter)
                                                 .WithType(newGenericArray2DParameterType)
                                                 .Build();

                newGenericArray3DParameters[i] = new ParameterSignatureBuilder(parameter)
                                                 .WithType(newGenericArray3DParameterType)
                                                 .Build();

                newGenericRefParameters[i] = new ParameterSignatureBuilder(parameter)
                                             .WithType(newGenericRefParameterType)
                                             .Build();
            }

            yield return(new FunctionSignatureBuilder(function)
                         .WithParameters(newIntPtrParameters)
                         .Build());

            yield return(new FunctionSignatureBuilder(function)
                         .WithParameters(newGenericArray1DParameters)
                         .WithGenericTypeParameters(newGenericTypeParameters)
                         .Build());

            yield return(new FunctionSignatureBuilder(function)
                         .WithParameters(newGenericArray2DParameters)
                         .WithGenericTypeParameters(newGenericTypeParameters)
                         .Build());

            yield return(new FunctionSignatureBuilder(function)
                         .WithParameters(newGenericArray3DParameters)
                         .WithGenericTypeParameters(newGenericTypeParameters)
                         .Build());

            yield return(new FunctionSignatureBuilder(function)
                         .WithParameters(newGenericRefParameters)
                         .WithGenericTypeParameters(newGenericTypeParameters)
                         .Build());
        }
        /// <inheritdoc/>
        public IEnumerable <FunctionSignature> CreateOverloads(FunctionSignature function)
        {
            var baseParameters = function.Parameters;

            var refParameterPermutation   = new List <ParameterSignature>(baseParameters);
            var arrayParameterPermutation = new List <ParameterSignature>(baseParameters);

            for (int i = 0; i < baseParameters.Count; ++i)
            {
                var baseParameter = baseParameters[i];
                var baseType      = baseParameter.Type;

                if (!baseType.IsPointer || baseType.IndirectionLevel > 1)
                {
                    continue;
                }

                if (baseType.Name.Equals(typeof(void).Name, StringComparison.OrdinalIgnoreCase))
                {
                    // Skip void pointers
                    continue;
                }

                var refTypeBuilder = new TypeSignatureBuilder(baseType)
                                     .WithIndirectionLevel(0)
                                     .WithByRef(true);

                if (baseParameter.Flow == FlowDirection.Out)
                {
                    refTypeBuilder = refTypeBuilder.WithIsOut(true);
                }

                var refType = refTypeBuilder.Build();

                var refParameter = new ParameterSignatureBuilder(baseParameter)
                                   .WithType(refType)
                                   .Build();

                refParameterPermutation[i] = refParameter;

                if (!(baseParameter.Count is null) && baseParameter.Count.IsStatic && baseParameter.Count.Count == 1)
                {
                    // Single-element count pointers don't need array overloads
                    continue;
                }

                var arrayType = new TypeSignatureBuilder(baseType)
                                .WithIndirectionLevel(0)
                                .WithArrayDimensions(1)
                                .Build();

                var arrayParameter = new ParameterSignatureBuilder(baseParameter)
                                     .WithType(arrayType)
                                     .Build();

                arrayParameterPermutation[i] = arrayParameter;
            }

            yield return(new FunctionSignatureBuilder(function)
                         .WithParameters(refParameterPermutation)
                         .Build());

            yield return(new FunctionSignatureBuilder(function)
                         .WithParameters(arrayParameterPermutation)
                         .Build());
        }
Exemple #21
0
        public IEnumerable <Overload> CreateOverloads(Function function)
        {
            if (!function.Parameters.Any(x => x.Type.IsPointer && !x.Type.IsVoidPointer()))
            {
                yield break;
            }

            var sb            = new StringBuilder();
            var parameters    = new List <string>();
            var ind           = string.Empty;
            var sig           = new FunctionSignatureBuilder(function);
            var newParameters = new Parameter[function.Parameters.Count];

            sb.AppendLine("// FlowPointerOverloader");

            for (var i = 0; i < function.Parameters.Count; i++)
            {
                var param = function.Parameters[i];
                if (param.Type.IsPointer && !param.Type.IsVoidPointer())
                {
                    var newParameterType = new TypeSignatureBuilder(param.Type)
                                           .WithIndirectionLevel(param.Type.IndirectionLevels - 1);
                    switch (param.Flow)
                    {
                    case FlowDirection.Undefined:
                        newParameterType = newParameterType.WithByRef(true);
                        break;

                    case FlowDirection.In:
                        newParameterType = newParameterType.WithIsIn(true);
                        break;

                    case FlowDirection.Out:
                        newParameterType = newParameterType.WithIsOut(true);
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }

                    var newParameter = new ParameterSignatureBuilder(param).WithType(newParameterType.Build());
                    var ptrName      = (param.Name + "Ptr").Replace("@", "");

                    parameters.Add(ptrName);
                    sb.AppendLine(ind + $"fixed ({param.Type} {ptrName} = &{param.Name})");
                    sb.AppendLine(ind + "{");

                    ind += "    ";
                    newParameters[i] = newParameter.Build();
                }
                else
                {
                    parameters.Add((Utilities.CSharpKeywords.Contains(param.Name) ? "@" : string.Empty) + param.Name);
                    newParameters[i] = param;
                }
            }

            sb.Append(ind);
            if (function.ReturnType.ToString() != "void")
            {
                sb.Append("return ");
            }

            sb.AppendLine(function.Name + "(" + string.Join(", ", parameters) + ");");

            while (!string.IsNullOrEmpty(ind))
            {
                ind = ind.Remove(ind.Length - 4, 4);
                sb.AppendLine(ind + "}");
            }

            yield return(new Overload(sig.WithParameters(newParameters).Build(), sb, true));
        }
        public bool TryGetFunctionVariant(Function function, out ImplementedFunction overload, Project core)
        {
            // SilkTouch currently can't properly marshal string spans, so we need to help out.
            var sb     = new StringBuilder();
            var pl     = new List <Parameter>();
            var ep     = new List <string>();
            var varied = false;

            sb.AppendLine("// StringArrayOverloader");
            pl.AddRange(function.Parameters);
            for (var i = 0; i < pl.Count; i++)
            {
                var parameter = pl[i];
                if (parameter.Type.ToString() == "char**" || parameter.Type.ToString() == "byte**")
                {
                    pl[i] = new ParameterSignatureBuilder(parameter).WithType
                            (
                        new Type
                    {
                        Name = "string", ArrayDimensions = 1, OriginalName = parameter.Type.OriginalName
                    }
                            )
                            .WithName(parameter.Name + "Sa")
                            .Build();
                    varied = true;
                    sb.AppendLine
                    (
                        $"var {parameter.Name} = ({parameter.Type}) SilkMarshal.StringArrayToPtr({parameter.Name}Sa);"
                    );
                    ep.Add($"SilkMarshal.CopyPtrToStringArray((nint) {parameter.Name}, {parameter.Name}Sa);");
                    ep.Add($"SilkMarshal.Free((nint) {parameter.Name});");
                }
            }

            if (function.ReturnType.ToString() != "void")
            {
                sb.Append("var ret = ");
            }

            sb.AppendLine
            (
                $"{function.Name}" +
                "(" + string.Join
                (
                    ", ",
                    function.Parameters.Select
                    (
                        x => (x.Type.IsIn ? "in " : string.Empty) + (x.Type.IsOut ? "out " : string.Empty) +
                        (x.Type.IsByRef ? "ref " : string.Empty) + (Utilities.CSharpKeywords.Contains
                                                                        (x.Name)
                                 ? "@"
                                 : string.Empty) + x.Name
                    )
                ) + ");"
            );

            foreach (var epilogueLine in ep)
            {
                sb.AppendLine(epilogueLine);
            }

            if (function.ReturnType.ToString() != "void")
            {
                sb.AppendLine("return ret;");
            }

            if (varied)
            {
                overload = new ImplementedFunction
                               (new FunctionSignatureBuilder(function).WithParameters(pl).Build(), sb, function);
                return(true);
            }

            overload = null;
            return(false);
        }
Exemple #23
0
        public bool TryCreateOverload(Function function, out ImplementedFunction overload, Project core)
        {
            if (function.NativeName == "clEnqueueSVMMigrateMem" || function.NativeName == "clEnqueueNativeKernel")
            {
                // BUG these functions think a span variant exists where one doesnt, was unable to filter out.
                overload = null;
                return(false);
            }

            var @params = new List <Parameter>(function.Parameters);
            var sb      = new StringBuilder();

            sb.AppendLine("// IntPtrOverloader");
            if (function.ReturnType.ToString() != "void")
            {
                sb.Append("return ");
            }

            sb.Append($"{function.Name}(");
            var ret = false;

            for (var i = 0; i < function.Parameters.Count; i++)
            {
                var parameter     = function.Parameters[i];
                var parameterName = Utilities.CSharpKeywords.Contains(parameter.Name)
                    ? $"@{parameter.Name}"
                    : parameter.Name;
                if (parameter.Type.IsIntPtr() && !(parameter.Type.IsOut))
                {
                    @params[i] = new ParameterSignatureBuilder(parameter)
                                 .WithType(new TypeSignatureBuilder(parameter.Type).WithName("int").Build())
                                 .Build();
                    sb.Append($"new IntPtr({parameterName})");
                    ret = true;
                }
                else if (parameter.Type.IsUIntPtr() && !(parameter.Type.IsOut))
                {
                    @params[i] = new ParameterSignatureBuilder(parameter)
                                 .WithType(new TypeSignatureBuilder(parameter.Type).WithName("uint").Build())
                                 .Build();
                    sb.Append($"new UIntPtr({parameterName})");
                    ret = true;
                }
                else
                {
                    var prefix = parameter.Type.IsOut ? "out " : parameter.Type.IsByRef ? "ref " : string.Empty;
                    sb.Append($"{prefix}{parameterName}");
                }

                if (i != function.Parameters.Count - 1)
                {
                    sb.Append(", ");
                }
            }

            sb.AppendLine(");");

            if (ret)
            {
                overload = new ImplementedFunction(new FunctionSignatureBuilder(function).WithParameters(@params).Build(), sb, function);
                return(true);
            }

            overload = null;
            return(false);
        }
Exemple #24
0
        public IEnumerable <ImplementedFunction> CreateOverloads(Function function)
        {
            if (!function.Parameters.Any(IsApplicable))
            {
                yield break;
            }

            var newParameters = new List <Parameter>(function.Parameters);
            var sb            = new StringBuilder();

            for (var i = 0; i < newParameters.Count; i++)
            {
                var param = newParameters[i];
                if (!IsApplicable(param))
                {
                    continue;
                }

                sb.AppendLine("// StaticCountOverloader");
                sb.Append($"var {param.Name} = stackalloc {param.Type.Name}");
                sb.AppendLine($"[{param.Count.StaticCount}];");
                for (var j = 0; j < param.Count.StaticCount; j++)
                {
                    if (j == 0)
                    {
                        newParameters[i + j] = new ParameterSignatureBuilder(param)
                                               .WithName(param.Name + j)
                                               .WithType(new TypeSignatureBuilder(param.Type).WithIndirectionLevel(0).Build())
                                               .WithCount(null)
                                               .Build();
                    }
                    else
                    {
                        newParameters.Insert(i + (j - 1), new ParameterSignatureBuilder(param)
                                             .WithName(param.Name + j)
                                             .WithCount(null)
                                             .WithType(new TypeSignatureBuilder(param.Type).WithIndirectionLevel(0).Build())
                                             .Build());
                    }

                    sb.AppendLine($"{param.Name}[{j}] = {param.Name}{j};");
                }
            }

            if (function.ReturnType.ToString() != "void")
            {
                sb.Append("return ");
            }

            sb.Append($"{function.Name}(");
            sb.Append(string.Join(", ", function.Parameters.Select(x => GetOut(x.Type) + Format(x.Name))));
            sb.Append(");");
            sb.AppendLine();

            yield return(new ImplementedFunction
                         (
                             new FunctionSignatureBuilder(function).WithParameters(newParameters).Build(),
                             sb,
                             true
                         ));

            string GetOut(Type t)
            {
                return(t.IsOut ? "out " : string.Empty);
            }

            string Format(string n)
            {
                if (Utilities.CSharpKeywords.Contains(n))
                {
                    return($"@{n}");
                }

                return(n);
            }
        }
Exemple #25
0
        public bool TryGetFunctionVariant(Function original, out ImplementedFunction varied, Project core)
        {
            varied = null;

            // use the ref overload for simplicity
            if (original.Kind != SignatureKind.SimpleOverload)
            {
                return(false);
            }

            var applicable           = false;
            var invocationParameters = new List <string>();
            var parameters           = new List <Parameter>(original.Parameters);

            for (var i = 0; i < original.Parameters.Count; i++)
            {
                var parameter = original.Parameters[i];
                var name      = (Utilities.CSharpKeywords.Contains(parameter.Name)
                    ? "@"
                    : string.Empty) + parameter.Name;
                if (parameter.Type.IsIn && !parameter.Type.IsPointer)
                {
                    applicable    = true;
                    parameters[i] = new ParameterSignatureBuilder(parameter).WithType
                                    (
                        new Type
                    {
                        Name         = "ReadOnlySpan",
                        GenericTypes = new List <Type>
                        {
                            new TypeSignatureBuilder(parameter.Type).WithIsIn(false).Build()
                        },
                        IsGenericTypeParameterReference = parameter.Type.IsGenericTypeParameterReference,
                        OriginalName = parameter.Type.OriginalName
                    }
                                    )
                                    .Build();
                    invocationParameters.Add($"in {name}.GetPinnableReference()");
                }
                else if (parameter.Type.IsOut && !parameter.Type.IsPointer)
                {
                    applicable    = true;
                    parameters[i] = new ParameterSignatureBuilder(parameter).WithType
                                    (
                        new Type
                    {
                        Name         = "Span",
                        GenericTypes = new List <Type>
                        {
                            new TypeSignatureBuilder(parameter.Type).WithIsOut(false).Build()
                        },
                        IsGenericTypeParameterReference = parameter.Type.IsGenericTypeParameterReference,
                        OriginalName = parameter.Type.OriginalName
                    }
                                    )
                                    .Build();
                    invocationParameters.Add($"out {name}.GetPinnableReference()");
                }
                else if (parameter.Type.IsByRef && !parameter.Type.IsPointer)
                {
                    applicable    = true;
                    parameters[i] = new ParameterSignatureBuilder(parameter).WithType
                                    (
                        new Type
                    {
                        Name         = "Span",
                        GenericTypes = new List <Type>
                        {
                            new TypeSignatureBuilder(parameter.Type).WithByRef(false).Build()
                        },
                        IsGenericTypeParameterReference = parameter.Type.IsGenericTypeParameterReference,
                        OriginalName = parameter.Type.OriginalName
                    }
                                    )
                                    .Build();
                    invocationParameters.Add($"ref {name}.GetPinnableReference()");
                }
                else
                {
                    invocationParameters.Add
                    (
                        (parameter.Type.IsIn ? "in " :
                         parameter.Type.IsOut ? "out " :
                         parameter.Type.IsByRef ? "ref " : string.Empty) + name
                    );
                }
            }

            if (applicable)
            {
                var sb = new StringBuilder();
                sb.AppendLine("// SpanOverloader");
                if (original.ReturnType.ToString() != "void")
                {
                    sb.Append("return ");
                }

                sb.Append("thisApi." + original.Name);
                sb.Append("(");
                sb.Append(string.Join(", ", invocationParameters));
                sb.Append(");");
                varied = new ImplementedFunction
                         (
                    new FunctionSignatureBuilder(original)
                    .WithParameters(parameters)
                    .WithKind(SignatureKind.PotentiallyConflictingOverload)
                    .Build(), sb, original
                         );
            }

            return(applicable);
        }
Exemple #26
0
        public bool TryCreateOverload(Function function, out ImplementedFunction overload, Project core)
        {
            // SuperInvoke currently can't properly marshal string spans, so we need to help out.
            var sb     = new StringBuilder();
            var pl     = new List <Parameter>();
            var ep     = new List <string>();
            var varied = false;

            sb.AppendLine("// StringArrayOverloader");
            pl.AddRange(function.Parameters);
            for (var i = 0; i < pl.Count; i++)
            {
                var parameter = pl[i];
                if (parameter.Type.ToString() == "char**" || parameter.Type.ToString() == "byte**")
                {
                    pl[i] = new ParameterSignatureBuilder(parameter).WithType
                            (
                        new Type
                    {
                        Name = "string", ArrayDimensions = 1
                    }
                            )
                            .WithName(parameter.Name + "Sa")
                            .Build();
                    varied = true;
                    sb.AppendLine
                    (
                        $"var {parameter.Name} = ({parameter.Type}) SilkMarshal.MarshalStringArrayToPtr({parameter.Name}Sa);"
                    );
                    ep.Add($"SilkMarshal.CopyPtrToStringArray((IntPtr) {parameter.Name}, {parameter.Name}Sa);");
                }
            }

            if (function.ReturnType.ToString() != "void")
            {
                sb.Append("var ret = ");
            }

            sb.AppendLine
            (
                $"{function.Name}" +
                $"({string.Join(", ", function.Parameters.Select(x => (x.Type.IsByRef ? "ref " : string.Empty) + x.Name))});"
            );

            foreach (var epilogueLine in ep)
            {
                sb.AppendLine(epilogueLine);
            }

            if (function.ReturnType.ToString() != "void")
            {
                sb.AppendLine("return ret;");
            }

            if (varied)
            {
                overload = new ImplementedFunction
                               (new FunctionSignatureBuilder(function).WithParameters(pl).Build(), sb, function);
                return(true);
            }

            overload = null;
            return(false);
        }