using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty { public class FunctionPointerAddressOf { public static void Overloaded() { } public static void Overloaded(int a) { } public unsafe delegate* GetAddress() { return &Overloaded; } #if !(CS110 && NET70) public unsafe IntPtr GetAddressAsIntPtr() { return (IntPtr)(delegate*)(&Overloaded); } #endif public unsafe nint GetAddressAsNInt() { return (nint)(delegate*)(&Overloaded); } public unsafe void* GetAddressAsVoidPtr() { return (delegate*)(&Overloaded); } public static string VarianceTest(object o) { return null; } public unsafe delegate* Variance() { return (delegate*)(&VarianceTest); } public unsafe delegate* AddressOfLocalFunction_Managed() { return &LocalFunction; static void LocalFunction() { } } public unsafe delegate* unmanaged AddressOfLocalFunction_Unmanaged() { return &LocalFunction; [UnmanagedCallersOnly] static void LocalFunction() { } } public unsafe delegate* unmanaged[Cdecl] AddressOfLocalFunction_CDecl() { return &LocalFunction; [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvCdecl) })] static void LocalFunction() { } } public unsafe delegate* unmanaged[Fastcall] AddressOfLocalFunction_Fastcall() { return &LocalFunction; [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvFastcall) })] static void LocalFunction() { } } #if NET60 public unsafe delegate* unmanaged[MemberFunction] AddressOfLocalFunction_MemberFunction() { return &LocalFunction; [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvMemberFunction) })] static void LocalFunction() { } } #endif public unsafe delegate* unmanaged[Stdcall] AddressOfLocalFunction_Stdcall() { return &LocalFunction; [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvStdcall) })] static void LocalFunction() { } } #if NET60 public unsafe delegate* unmanaged[SuppressGCTransition] AddressOfLocalFunction_SuppressGCTransition() { return &LocalFunction; [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvSuppressGCTransition) })] static void LocalFunction() { } } #endif public unsafe delegate* unmanaged[Thiscall] AddressOfLocalFunction_Thiscall() { return &LocalFunction; [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvThiscall) })] static void LocalFunction() { } } public unsafe delegate* unmanaged[Cdecl, Fastcall] AddressOfLocalFunction_CDeclAndFastcall() { return &LocalFunction; [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvCdecl), typeof(CallConvFastcall) })] static void LocalFunction() { } } public unsafe delegate* unmanaged[Fastcall, Cdecl] AddressOfLocalFunction_FastcallAndCDecl() { return &LocalFunction; [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvFastcall), typeof(CallConvCdecl) })] static void LocalFunction() { } } #if NET60 public unsafe delegate* unmanaged[Cdecl, SuppressGCTransition] AddressOfLocalFunction_CDeclAndSuppressGCTransition() { return &LocalFunction; [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvCdecl), typeof(CallConvSuppressGCTransition) })] static void LocalFunction() { } } public unsafe delegate* unmanaged[Fastcall, SuppressGCTransition] AddressOfLocalFunction_FastcallAndSuppressGCTransition() { return &LocalFunction; [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvFastcall), typeof(CallConvSuppressGCTransition) })] static void LocalFunction() { } } public unsafe delegate* unmanaged[Stdcall, SuppressGCTransition] AddressOfLocalFunction_StdcallAndSuppressGCTransition() { return &LocalFunction; [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvStdcall), typeof(CallConvSuppressGCTransition) })] static void LocalFunction() { } } public unsafe delegate* unmanaged[Thiscall, SuppressGCTransition] AddressOfLocalFunction_ThiscallAndSuppressGCTransition() { return &LocalFunction; [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvThiscall), typeof(CallConvSuppressGCTransition) })] static void LocalFunction() { } } #endif } internal class FunctionPointersWithCallingConvention { public unsafe delegate* fn_default; // Unmanaged without explicit callconv is only supported with .NET 5, // and emits metadata that cannot be parsed by older SRM versions. //public delegate* unmanaged fn_unmanaged; public unsafe delegate* unmanaged[Cdecl] fn_cdecl; public unsafe delegate* unmanaged[Fastcall] fn_fastcall; public unsafe delegate* unmanaged[Stdcall] fn_stdcall; public unsafe delegate* unmanaged[Thiscall] fn_thiscall; } internal class FunctionPointersWithDynamicTypes { public class D { } public class A { public class B { } } public unsafe delegate* F1; public unsafe delegate* F2; public unsafe delegate* F3; public unsafe delegate* F4; public unsafe delegate* F5; public unsafe delegate* F6; public unsafe delegate* F7; public unsafe delegate* F8; public unsafe delegate* F9; public unsafe delegate* F10; public unsafe delegate* F11; public unsafe delegate* F12; public unsafe delegate* F13; public unsafe delegate* F14; #if CS120 public unsafe delegate* F15; #endif public unsafe D[], dynamic> F16; public unsafe delegate*.B> F17; } internal class FunctionPointersWithNativeIntegerTypes { public unsafe delegate* F1; #if !(CS110 && NET70) public unsafe delegate* F2; public unsafe delegate* F3; public unsafe delegate* F4; public unsafe delegate*, nint> F5; public unsafe delegate*> F6; public unsafe delegate*, IntPtr> F7; public unsafe delegate*> F8; public unsafe delegate*> F9; #endif } internal class FunctionPointersWithRefParams { public unsafe delegate* F1; public unsafe delegate* F2; public unsafe int CallF1(byte b, char c, out float f) { return F1(in b, ref c, out f); } public unsafe void CallF2(byte b, char c, out float f) { F2(ref c, out f) = b; } } internal class FunctionPointerTypeInference { private static char Test(int i) { return (char)i; } public unsafe R GenericMethod(delegate* f, T arg) { return f(arg); } public unsafe void Call() { delegate* f = &Test; GenericMethod(f, 0); GenericMethod((delegate*)(&Test), 1); GenericMethod(null, 2); } } }