From e61f46c4749a35a9c0a65ecc9e0abf0d690da0eb Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Tue, 10 May 2022 19:34:28 +0200 Subject: [PATCH] Add MethodCodeType argument to MethodImplAttribute. --- .../PrettyTestRunner.cs | 6 ++ .../TestCases/Pretty/MetadataAttributes.cs | 92 +++++++++++++++++++ .../Implementation/MetadataMethod.cs | 14 ++- 3 files changed, 107 insertions(+), 5 deletions(-) create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Pretty/MetadataAttributes.cs diff --git a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs index db7b7ff30..57cea8eba 100644 --- a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs @@ -714,6 +714,12 @@ namespace ICSharpCode.Decompiler.Tests await RunForLibrary(cscOptions: cscOptions | CompilerOptions.Preview); } + [Test] + public async Task MetadataAttributes([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) + { + await RunForLibrary(cscOptions: cscOptions); + } + async Task RunForLibrary([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, DecompilerSettings decompilerSettings = null) { await Run(testName, asmOptions | AssemblerOptions.Library, cscOptions | CompilerOptions.Library, decompilerSettings); diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/MetadataAttributes.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/MetadataAttributes.cs new file mode 100644 index 000000000..a1a8e258c --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/MetadataAttributes.cs @@ -0,0 +1,92 @@ +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty +{ + internal class MetadataAttributes + { + private class MethodImplAttr + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public extern void A(); +#if NETCORE + [MethodImpl(MethodImplOptions.AggressiveOptimization)] + public extern void B(); +#endif + [MethodImpl(MethodImplOptions.ForwardRef)] + public extern void D(); + [MethodImpl(MethodImplOptions.InternalCall)] + public extern void E(); + [MethodImpl(MethodImplOptions.NoInlining)] + public extern void F(); + [MethodImpl(MethodImplOptions.NoOptimization)] + public extern void G(); + [PreserveSig] + public extern void H(); + [MethodImpl(MethodImplOptions.Synchronized)] + public extern void I(); + [MethodImpl(MethodImplOptions.Unmanaged)] + public extern void J(); + [MethodImpl(MethodImplOptions.AggressiveInlining, MethodCodeType = MethodCodeType.Native)] + public extern void A1(); +#if NETCORE + [MethodImpl(MethodImplOptions.AggressiveOptimization, MethodCodeType = MethodCodeType.Native)] + public extern void B1(); +#endif + [MethodImpl(MethodImplOptions.ForwardRef, MethodCodeType = MethodCodeType.Native)] + public extern void D1(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Native)] + public extern void E1(); + [MethodImpl(MethodImplOptions.NoInlining, MethodCodeType = MethodCodeType.Native)] + public extern void F1(); + [MethodImpl(MethodImplOptions.NoOptimization, MethodCodeType = MethodCodeType.Native)] + public extern void G1(); + [MethodImpl(MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Native)] + public extern void H1(); + [MethodImpl(MethodImplOptions.Synchronized, MethodCodeType = MethodCodeType.Native)] + public extern void I1(); + [MethodImpl(MethodImplOptions.Unmanaged, MethodCodeType = MethodCodeType.Native)] + public extern void J1(); + [MethodImpl(MethodImplOptions.AggressiveInlining, MethodCodeType = MethodCodeType.OPTIL)] + public extern void A2(); +#if NETCORE + [MethodImpl(MethodImplOptions.AggressiveOptimization, MethodCodeType = MethodCodeType.OPTIL)] + public extern void B2(); +#endif + [MethodImpl(MethodImplOptions.ForwardRef, MethodCodeType = MethodCodeType.OPTIL)] + public extern void D2(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.OPTIL)] + public extern void E2(); + [MethodImpl(MethodImplOptions.NoInlining, MethodCodeType = MethodCodeType.OPTIL)] + public extern void F2(); + [MethodImpl(MethodImplOptions.NoOptimization, MethodCodeType = MethodCodeType.OPTIL)] + public extern void G2(); + [MethodImpl(MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.OPTIL)] + public extern void H2(); + [MethodImpl(MethodImplOptions.Synchronized, MethodCodeType = MethodCodeType.OPTIL)] + public extern void I2(); + [MethodImpl(MethodImplOptions.Unmanaged, MethodCodeType = MethodCodeType.OPTIL)] + public extern void J2(); + [MethodImpl(MethodImplOptions.AggressiveInlining, MethodCodeType = MethodCodeType.OPTIL)] + public extern void A3(); +#if NETCORE + [MethodImpl(MethodImplOptions.AggressiveOptimization, MethodCodeType = MethodCodeType.Runtime)] + public extern void B3(); +#endif + [MethodImpl(MethodImplOptions.ForwardRef, MethodCodeType = MethodCodeType.Runtime)] + public extern void D3(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public extern void E3(); + [MethodImpl(MethodImplOptions.NoInlining, MethodCodeType = MethodCodeType.Runtime)] + public extern void F3(); + [MethodImpl(MethodImplOptions.NoOptimization, MethodCodeType = MethodCodeType.Runtime)] + public extern void G3(); + [MethodImpl(MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)] + public extern void H3(); + [MethodImpl(MethodImplOptions.Synchronized, MethodCodeType = MethodCodeType.Runtime)] + public extern void I3(); + [MethodImpl(MethodImplOptions.Unmanaged, MethodCodeType = MethodCodeType.Runtime)] + public extern void J3(); + } + } +} diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs index e9a1d7ac9..282740f92 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs @@ -333,6 +333,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation var metadata = module.metadata; var def = metadata.GetMethodDefinition(handle); MethodImplAttributes implAttributes = def.ImplAttributes & ~MethodImplAttributes.CodeTypeMask; + int methodCodeType = (int)(def.ImplAttributes & MethodImplAttributes.CodeTypeMask); #region DllImportAttribute var info = def.GetImport(); @@ -430,7 +431,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation #endregion #region PreserveSigAttribute - if (implAttributes == MethodImplAttributes.PreserveSig) + if (implAttributes == MethodImplAttributes.PreserveSig && methodCodeType == 0) { b.Add(KnownAttribute.PreserveSig); implAttributes = 0; @@ -440,10 +441,13 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation #region MethodImplAttribute if (implAttributes != 0) { - b.Add(KnownAttribute.MethodImpl, - new TopLevelTypeName("System.Runtime.CompilerServices", nameof(MethodImplOptions)), - (int)implAttributes - ); + var methodImpl = new AttributeBuilder(module, KnownAttribute.MethodImpl); + methodImpl.AddFixedArg(new TopLevelTypeName("System.Runtime.CompilerServices", nameof(MethodImplOptions)), (int)implAttributes); + if (methodCodeType != 0) + { + methodImpl.AddNamedArg("MethodCodeType", new TopLevelTypeName("System.Runtime.CompilerServices", nameof(MethodCodeType)), methodCodeType); + } + b.Add(methodImpl.Build()); } #endregion