/// <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); }
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); }
static bool CheckDuplicate(ImplementedFunction left, ImplementedFunction right) => left.Signature.Equals(right.Signature);
public bool TryCreateOverload(Function function, out ImplementedFunction overload, Project core) { overload = null; return(false); }
/// <inheritdoc/> public bool TryGetFunctionVariant(Function function, out ImplementedFunction overload, Project core) { if (!IsApplicable(function)) { overload = null; return(false); } var lastParameterType = function.Parameters.Last().Type; var newReturnType = new TypeSignatureBuilder(lastParameterType) .WithIndirectionLevel(lastParameterType.IndirectionLevels - 1) .WithArrayDimensions(0) .Build(); var newParameters = SkipLastExtension.SkipLast(function.Parameters, 1).ToList(); var newName = function.Name.Singularize(false); var functionBuilder = new FunctionSignatureBuilder(function) .WithName(newName) .WithReturnType(newReturnType); var sb = new StringBuilder(); var strParams = newParameters.Select(Convert).Concat(new[] { "&ret" }); sb.AppendLine("// ReturnTypeOverloader"); sb.AppendLine($"{newReturnType} ret = default;"); sb.Append($"{function.Name}("); sb.Append(string.Join(", ", strParams)); sb.AppendLine(");"); sb.AppendLine("return ret;"); if (!newParameters.Any()) { overload = new ImplementedFunction ( functionBuilder .WithParameters(newParameters) .Build(), sb, function, true ); return(true); } var sizeParameterType = newParameters.Last().Type; if ((sizeParameterType.Name != "int" && sizeParameterType.Name != "uint") || sizeParameterType.IsPointer) { overload = new ImplementedFunction ( functionBuilder .WithParameters(newParameters) .Build(), sb, function, true ); return(true); } var n = newParameters.Last().Name; sb.Insert ( 0, $"const {(sizeParameterType.Name == "uint" ? "uint " : "int ")}{(Utilities.CSharpKeywords.Contains(n) ? "@" : "")}{n} = 1;\n" ); newParameters = SkipLastExtension.SkipLast(newParameters, 1).ToList(); overload = new ImplementedFunction ( functionBuilder .WithParameters(newParameters) .Build(), sb, function, true ); return(true); string Convert(Parameter x) { var pre = x.Type.IsOut ? "out " : string.Empty; return(pre + (Utilities.CSharpKeywords.Contains(x.Name) ? $"@{x.Name}" : x.Name)); } }
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); }
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); }
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); }