Browse Source

Handle multiple calling conventions at once

pull/3620/head
ds5678 1 month ago committed by Jeremy Pritts
parent
commit
83df0ab9b9
  1. 26
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/FunctionPointers.cs
  2. 2
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  3. 39
      ICSharpCode.Decompiler/TypeSystem/FunctionPointerType.cs

26
ICSharpCode.Decompiler.Tests/TestCases/Pretty/FunctionPointers.cs

@ -129,6 +129,32 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
} }
} }
public unsafe delegate* unmanaged[Cdecl, Fastcall]<void> AddressOfLocalFunction_CDeclAndFastcall()
{
return &LocalFunction;
[UnmanagedCallersOnly(CallConvs = new Type[] {
typeof(CallConvCdecl),
typeof(CallConvFastcall)
})]
static void LocalFunction()
{
}
}
public unsafe delegate* unmanaged[Fastcall, Cdecl]<void> AddressOfLocalFunction_FastcallAndCDecl()
{
return &LocalFunction;
[UnmanagedCallersOnly(CallConvs = new Type[] {
typeof(CallConvFastcall),
typeof(CallConvCdecl)
})]
static void LocalFunction()
{
}
}
#if NET60 #if NET60
public unsafe delegate* unmanaged[Cdecl, SuppressGCTransition]<void> AddressOfLocalFunction_CDeclAndSuppressGCTransition() public unsafe delegate* unmanaged[Cdecl, SuppressGCTransition]<void> AddressOfLocalFunction_CDeclAndSuppressGCTransition()
{ {

2
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -4611,7 +4611,7 @@ namespace ICSharpCode.Decompiler.CSharp
var builder = ImmutableArray.CreateBuilder<IType>(array.Length); var builder = ImmutableArray.CreateBuilder<IType>(array.Length);
foreach (var type in array.Select(a => a.Value).OfType<IType>()) foreach (var type in array.Select(a => a.Value).OfType<IType>())
{ {
SignatureCallingConvention? foundCallingConvention = type.Namespace is not "System.Runtime.CompilerServices" ? null : type.Name switch { SignatureCallingConvention? foundCallingConvention = type.Namespace is not "System.Runtime.CompilerServices" || callingConvention != SignatureCallingConvention.Unmanaged ? null : type.Name switch {
"CallConvCdecl" => SignatureCallingConvention.CDecl, "CallConvCdecl" => SignatureCallingConvention.CDecl,
"CallConvFastcall" => SignatureCallingConvention.FastCall, "CallConvFastcall" => SignatureCallingConvention.FastCall,
"CallConvStdcall" => SignatureCallingConvention.StdCall, "CallConvStdcall" => SignatureCallingConvention.StdCall,

39
ICSharpCode.Decompiler/TypeSystem/FunctionPointerType.cs

@ -46,23 +46,30 @@ namespace ICSharpCode.Decompiler.TypeSystem
&& modReturn.Modifier.Namespace == "System.Runtime.CompilerServices") && modReturn.Modifier.Namespace == "System.Runtime.CompilerServices")
{ {
returnType = modReturn.ElementType; returnType = modReturn.ElementType;
switch (modReturn.Modifier.Name) if (callingConvention == SignatureCallingConvention.Unmanaged)
{ {
case "CallConvCdecl": switch (modReturn.Modifier.Name)
callingConvention = SignatureCallingConvention.CDecl; {
break; case "CallConvCdecl":
case "CallConvFastcall": callingConvention = SignatureCallingConvention.CDecl;
callingConvention = SignatureCallingConvention.FastCall; break;
break; case "CallConvFastcall":
case "CallConvStdcall": callingConvention = SignatureCallingConvention.FastCall;
callingConvention = SignatureCallingConvention.StdCall; break;
break; case "CallConvStdcall":
case "CallConvThiscall": callingConvention = SignatureCallingConvention.StdCall;
callingConvention = SignatureCallingConvention.ThisCall; break;
break; case "CallConvThiscall":
default: callingConvention = SignatureCallingConvention.ThisCall;
customCallConvs.Add(modReturn.Modifier); break;
break; default:
customCallConvs.Add(modReturn.Modifier);
break;
}
}
else
{
customCallConvs.Add(modReturn.Modifier);
} }
} }
else else

Loading…
Cancel
Save