Browse Source

Add support for InlineArrayConversion

feature/inlinearrays
Siegfried Pammer 3 weeks ago
parent
commit
667036c54e
  1. 32
      ICSharpCode.Decompiler.Tests/TestCases/Correctness/Conversions.cs
  2. 4
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/InlineArrayTests.cs
  3. 10
      ICSharpCode.Decompiler/CSharp/Resolver/CSharpConversions.cs
  4. 7
      ICSharpCode.Decompiler/TypeSystem/Implementation/KnownAttributes.cs
  5. 10
      ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs

32
ICSharpCode.Decompiler.Tests/TestCases/Correctness/Conversions.cs

@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
// #include "../../../ICSharpCode.Decompiler/Util/CSharpPrimitiveCast.cs"
using System;
using System.Runtime.CompilerServices;
using ICSharpCode.Decompiler.Util;
@ -111,6 +112,9 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -111,6 +112,9 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
Console.WriteLine(ReadZeroTerminatedString("Hello World!".Length));
C1.Test();
#if ROSLYN2 && !NET40
C3.Run();
#endif
}
static void RunTest(bool checkForOverflow)
@ -199,4 +203,32 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -199,4 +203,32 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
return new C1();
}
}
#if ROSLYN2 && !NET40
class C3
{
[InlineArray(4)] struct MyArray { private int elem; }
static void Foo(object o)
{
Console.WriteLine("Foo(object) called");
}
static void Foo(ReadOnlySpan<int> o)
{
Console.WriteLine("Foo(ReadOnlySpan<int>) called");
}
static void Test(MyArray arr)
{
Foo((object)arr);
}
public static void Run()
{
Console.WriteLine("C3.Run() called");
Test(default);
}
}
#endif
}

4
ICSharpCode.Decompiler.Tests/TestCases/Pretty/InlineArrayTests.cs

@ -91,9 +91,9 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -91,9 +91,9 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
Byte16 buffer2 = GetByte16();
Receiver((ReadOnlySpan<byte>)buffer2);
Byte16 buffer3 = GetByte16();
ReceiverSpan((Span<byte>)buffer3);
ReceiverSpan(buffer3);
Byte16 buffer4 = GetByte16();
ReceiverReadOnlySpan((ReadOnlySpan<byte>)buffer4);
ReceiverReadOnlySpan(buffer4);
}
public Byte16 GetByte16()

10
ICSharpCode.Decompiler/CSharp/Resolver/CSharpConversions.cs

@ -230,12 +230,20 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver @@ -230,12 +230,20 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
if (c != Conversion.None)
return c;
}
if ((toType.IsKnownType(KnownTypeCode.SpanOfT) || toType.IsKnownType(KnownTypeCode.ReadOnlySpanOfT))
&& fromType.IsInlineArrayType())
{
var @field = fromType.GetFields(f => !f.IsStatic, GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault();
var spanElementType = toType.TypeArguments[0];
if (field != null && IdentityConversion(field.ReturnType, spanElementType))
return Conversion.InlineArrayConversion;
}
return Conversion.None;
}
/// <summary>
/// Gets whether the type 'fromType' is convertible to 'toType'
/// using one of the conversions allowed when satisying constraints (§4.4.4)
/// using one of the conversions allowed when satisfying constraints (§4.4.4)
/// </summary>
public bool IsConstraintConvertible(IType fromType, IType toType)
{

7
ICSharpCode.Decompiler/TypeSystem/Implementation/KnownAttributes.cs

@ -112,11 +112,14 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -112,11 +112,14 @@ namespace ICSharpCode.Decompiler.TypeSystem
// C# 11 attributes:
RequiredAttribute,
// C# 12 attributes:
InlineArray,
}
public static class KnownAttributes
{
internal const int Count = (int)KnownAttribute.RequiredAttribute + 1;
internal const int Count = (int)KnownAttribute.InlineArray + 1;
static readonly TopLevelTypeName[] typeNames = new TopLevelTypeName[Count]{
default,
@ -186,6 +189,8 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -186,6 +189,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
new TopLevelTypeName("System.Runtime.CompilerServices", "PreserveBaseOverridesAttribute"),
// C# 11 attributes:
new TopLevelTypeName("System.Runtime.CompilerServices", "RequiredMemberAttribute"),
// C# 12 attributes:
new TopLevelTypeName("System.Runtime.CompilerServices", "InlineArrayAttribute"),
};
public static ref readonly TopLevelTypeName GetTypeName(this KnownAttribute attr)

10
ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs

@ -306,6 +306,16 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -306,6 +306,16 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
}
public static bool IsInlineArrayType(this IType type)
{
if (type.Kind != TypeKind.Struct)
return false;
var td = type.GetDefinition();
if (td == null)
return false;
return td.HasAttribute(KnownAttribute.InlineArray);
}
/// <summary>
/// Gets whether the type is the specified known type.
/// For generic known types, this returns true for any parameterization of the type (and also for the definition itself).

Loading…
Cancel
Save