Browse Source

Merge pull request #960 from icsharpcode/increment

Improve handling of post-increment and compound assignments
pull/925/merge
Daniel Grunwald 8 years ago committed by GitHub
parent
commit
13140f60be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 31
      ICSharpCode.Decompiler.Tests/Helpers/CodeAssert.cs
  2. 24
      ICSharpCode.Decompiler.Tests/Helpers/Tester.cs
  3. 4
      ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
  4. 4
      ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
  5. 21
      ICSharpCode.Decompiler.Tests/TestCases/Correctness/CompoundAssignment.cs
  6. 427
      ICSharpCode.Decompiler.Tests/TestCases/Correctness/StackTypes.il
  7. 244
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.cs
  8. 1008
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.il
  9. 810
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.opt.il
  10. 806
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.opt.roslyn.il
  11. 1014
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.roslyn.il
  12. 68
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/InlineAssignmentTest.cs
  13. 285
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/InlineAssignmentTest.il
  14. 231
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/InlineAssignmentTest.opt.il
  15. 431
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/InlineAssignmentTest.opt.roslyn.il
  16. 524
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/InlineAssignmentTest.roslyn.il
  17. 6
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.cs
  18. 10
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  19. 76
      ICSharpCode.Decompiler/CSharp/CallBuilder.cs
  20. 19
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  21. 55
      ICSharpCode.Decompiler/CSharp/StatementBuilder.cs
  22. 4
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  23. 35
      ICSharpCode.Decompiler/IL/ILTypeExtensions.cs
  24. 17
      ICSharpCode.Decompiler/IL/ILVariable.cs
  25. 117
      ICSharpCode.Decompiler/IL/Instructions.cs
  26. 15
      ICSharpCode.Decompiler/IL/Instructions.tt
  27. 62
      ICSharpCode.Decompiler/IL/Instructions/Block.cs
  28. 14
      ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs
  29. 4
      ICSharpCode.Decompiler/IL/Instructions/InstructionCollection.cs
  30. 8
      ICSharpCode.Decompiler/IL/Instructions/MemoryInstructions.cs
  31. 17
      ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs
  32. 17
      ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs
  33. 571
      ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs
  34. 3
      ICSharpCode.Decompiler/TypeSystem/TypeUtils.cs

31
ICSharpCode.Decompiler.Tests/Helpers/CodeAssert.cs

@ -3,6 +3,8 @@ using System.Collections.Generic; @@ -3,6 +3,8 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using DiffLib;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using NUnit.Framework;
namespace ICSharpCode.Decompiler.Tests.Helpers
@ -115,24 +117,23 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -115,24 +117,23 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
return NormalizeLine(line) == string.Empty;
}
private static IEnumerable<string> NormalizeAndSplitCode(string input, string[] definedSymbols)
class DeleteDisabledTextRewriter : CSharpSyntaxRewriter
{
bool include = true;
foreach (string line in input.Split(new[] { "\r\n", "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries)) {
var temp = line.Trim();
if (temp.StartsWith("#if !", StringComparison.Ordinal)) {
string symbol = temp.Substring(5);
if (definedSymbols.Contains(symbol))
include = false;
} else if (temp.StartsWith("#if ", StringComparison.Ordinal)) {
string symbol = temp.Substring(4);
if (!definedSymbols.Contains(symbol))
include = false;
} else if (temp.StartsWith("#endif", StringComparison.Ordinal)) {
include = true;
public override SyntaxTrivia VisitTrivia(SyntaxTrivia trivia)
{
if (trivia.IsKind(SyntaxKind.DisabledTextTrivia)) {
return default(SyntaxTrivia); // delete
}
if (include) yield return line;
return base.VisitTrivia(trivia);
}
}
private static IEnumerable<string> NormalizeAndSplitCode(string input, IEnumerable<string> definedSymbols)
{
var syntaxTree = CSharpSyntaxTree.ParseText(input, new CSharpParseOptions(preprocessorSymbols: definedSymbols));
var result = new DeleteDisabledTextRewriter().Visit(syntaxTree.GetRoot());
input = result.ToFullString();
return input.Split(new[] { "\r\n", "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries);
}
}
}

24
ICSharpCode.Decompiler.Tests/Helpers/Tester.cs

@ -158,6 +158,24 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -158,6 +158,24 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
};
});
public static List<string> GetPreprocessorSymbols(CompilerOptions flags)
{
var preprocessorSymbols = new List<string>();
if (flags.HasFlag(CompilerOptions.UseDebug)) {
preprocessorSymbols.Add("DEBUG");
}
if (flags.HasFlag(CompilerOptions.Optimize)) {
preprocessorSymbols.Add("OPT");
}
if (flags.HasFlag(CompilerOptions.UseRoslyn)) {
preprocessorSymbols.Add("ROSLYN");
} else {
preprocessorSymbols.Add("LEGACY_CSC");
}
return preprocessorSymbols;
}
public static CompilerResults CompileCSharp(string sourceFileName, CompilerOptions flags = CompilerOptions.UseDebug, string outputFileName = null)
{
List<string> sourceFileNames = new List<string> { sourceFileName };
@ -165,10 +183,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -165,10 +183,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
sourceFileNames.Add(Path.GetFullPath(Path.Combine(Path.GetDirectoryName(sourceFileName), match.Groups[1].Value)));
}
var preprocessorSymbols = new List<string>();
if (flags.HasFlag(CompilerOptions.UseDebug)) {
preprocessorSymbols.Add("DEBUG");
}
var preprocessorSymbols = GetPreprocessorSymbols(flags);
if (flags.HasFlag(CompilerOptions.UseRoslyn)) {
var parseOptions = new CSharpParseOptions(preprocessorSymbols: preprocessorSymbols.ToArray());
@ -194,7 +209,6 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -194,7 +209,6 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
}
return results;
} else {
preprocessorSymbols.Add("LEGACY_CSC");
var provider = new CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v4.0" } });
CompilerParameters options = new CompilerParameters();
options.GenerateExecutable = !flags.HasFlag(CompilerOptions.Library);

4
ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj

@ -32,8 +32,8 @@ @@ -32,8 +32,8 @@
<ItemGroup>
<PackageReference Include="DiffLib" Version="1.0.0.55" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="2.3.2" />
<PackageReference Include="System.Collections.Immutable" Version="1.4.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="2.4.0" />
<PackageReference Include="System.Collections.Immutable" Version="1.3.1" />
<PackageReference Include="NUnit" Version="2.6.3" />
<PackageReference Include="NUnitTestAdapter" Version="2.0.0" />
</ItemGroup>

4
ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs

@ -74,7 +74,7 @@ namespace ICSharpCode.Decompiler.Tests @@ -74,7 +74,7 @@ namespace ICSharpCode.Decompiler.Tests
}
[Test]
public void InlineAssignmentTest([ValueSource("noRoslynOptions")] CompilerOptions cscOptions)
public void InlineAssignmentTest([ValueSource("defaultOptions")] CompilerOptions cscOptions)
{
Run(cscOptions: cscOptions);
}
@ -226,7 +226,7 @@ namespace ICSharpCode.Decompiler.Tests @@ -226,7 +226,7 @@ namespace ICSharpCode.Decompiler.Tests
var executable = Tester.AssembleIL(ilFile, asmOptions | AssemblerOptions.Library);
var decompiled = Tester.DecompileCSharp(executable);
CodeAssert.FilesAreEqual(csFile, decompiled, cscOptions.HasFlag(CompilerOptions.UseRoslyn) ? null : new[] { "LEGACY_CSC" });
CodeAssert.FilesAreEqual(csFile, decompiled, Tester.GetPreprocessorSymbols(cscOptions).ToArray());
}
}
}

21
ICSharpCode.Decompiler.Tests/TestCases/Correctness/CompoundAssignment.cs

@ -30,6 +30,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -30,6 +30,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
CallTwice();
UnsignedShiftRightInstanceField();
UnsignedShiftRightStaticProperty();
DivideByBigValue();
}
static void Test(int a, int b)
@ -76,6 +77,19 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -76,6 +77,19 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
}
}
static ushort shortField;
public static ushort ShortProperty {
get {
Console.WriteLine("In get_ShortProperty");
return shortField;
}
set {
Console.WriteLine("In set_ShortProperty, value={0}", value);
shortField = value;
}
}
public static Dictionary<string, int> GetDict()
{
Console.WriteLine("In GetDict()");
@ -133,5 +147,12 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -133,5 +147,12 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
StaticProperty = -15;
Test(X(), StaticProperty = (int)((uint)StaticProperty >> 2));
}
static void DivideByBigValue()
{
ShortProperty = 5;
// can't use "ShortProperty /= (ushort)(ushort.MaxValue + 3)" because that would be division by 2.
ShortProperty = (ushort)(ShortProperty / (ushort.MaxValue + 3));
}
}
}

427
ICSharpCode.Decompiler.Tests/TestCases/Correctness/StackTypes.il

@ -1,12 +1,12 @@ @@ -1,12 +1,12 @@
.assembly extern mscorlib
{
.publickeytoken = ( b7 7a 5c 56 19 34 e0 89 )
.ver 4:0:0:0
.publickeytoken = ( b7 7a 5c 56 19 34 e0 89 )
.ver 4:0:0:0
}
.assembly 'StackTypes'
{
.ver 0:0:0:0
.ver 0:0:0:0
}
.module StackTypes.exe
@ -15,204 +15,227 @@ @@ -15,204 +15,227 @@
.class private auto ansi abstract sealed beforefieldinit Program
extends [mscorlib]System.Object
{
.method public hidebysig static void Main (string[] args) cil managed
{
.maxstack 8
.entrypoint
//call void Program::Int32OrNativeTests()
ret
} // end of method Main
/*
.method public static void Int32OrNativeTests()
{
ldstr "Int32OrNative(0x7fffffff, false) = {0}"
ldc.i4 0x7fffffff
ldc.i4 0
call native int Program::Int32OrNative(int32, bool)
box native int
call void [mscorlib]System.Console::WriteLine(string, object)
ldstr "Int32OrNative(0x7fffffff, true) = {0}"
ldc.i4 0x7fffffff
ldc.i4 1
call native int Program::Int32OrNative(int32, bool)
box native int
call void [mscorlib]System.Console::WriteLine(string, object)
ldstr "Int32OrNative(-1, false) = {0}"
ldc.i4.m1
ldc.i4 0
call native int Program::Int32OrNative(int32, bool)
box native int
call void [mscorlib]System.Console::WriteLine(string, object)
ldstr "Int32OrNative(-1, true) = {0}"
ldc.i4.m1
ldc.i4 1
call native int Program::Int32OrNative(int32, bool)
box native int
call void [mscorlib]System.Console::WriteLine(string, object)
ldstr "Int32OrNativeLoopStyle(0x7fffffff):"
call void [mscorlib]System.Console::WriteLine(string)
ldc.i4 0x7fffffff
call void Program::Int32OrNativeLoopStyle(int32)
ldstr "Int32OrNativeLoopStyle(-1):"
call void [mscorlib]System.Console::WriteLine(string)
ldc.i4.m1
call void Program::Int32OrNativeLoopStyle(int32)
ldstr "Int32OrNativeDeadCode(0x7fffffff) = {0}"
ldc.i4 0x7fffffff
call native int Program::Int32OrNativeDeadCode(int32)
box native int
call void [mscorlib]System.Console::WriteLine(string, object)
ldstr "Int32OrNativeDeadCode(-1) = {0}"
ldc.i4.m1
call native int Program::Int32OrNativeDeadCode(int32)
box native int
call void [mscorlib]System.Console::WriteLine(string, object)
ldc.i4 0x7fffffff
call void Program::RunInt32OrNativeMultiUse(int32)
ldc.i4.m1
call void Program::RunInt32OrNativeMultiUse(int32)
ret
}
.method public static native int Int32OrNative(int32 val, bool use_native)
{
ldarg.1
brtrue use_native_int
use_i4:
ldarg.0
br after_if
after_if:
ldc.i4.1
add
ret
use_native_int:
ldarg.0
conv.u
br after_if
}
.method public static void Int32OrNativeLoopStyle(int32 val)
{
.locals init (
int32 i
)
ldarg.0
loop:
ldc.i4.1
add
call void Program::Print(native int)
ldloc.0
brtrue end
ldc.i4.1
stloc.0
ldarg.0
conv.u
br loop
end:
ret
}
.method public static native int Int32OrNativeDeadCode(int32 val)
{
use_i4:
ldarg.0
br after_if
after_if:
ldc.i4.1
add
ret
use_native_int: // dead code
ldarg.0
conv.u
br after_if
}
.method public static void RunInt32OrNativeMultiUse(int32 val)
{
ldstr "RunInt32OrNativeMultiUse({0}, push_i: false, use2: false) = {1}"
ldarg val
box int32
ldarg val
ldc.i4 0 // push_i
ldc.i4 0 // use2
call native int Program::Int32OrNativeMultiUse(int32 val, bool push_i, bool use2)
box native int
call void [mscorlib]System.Console::WriteLine(string, object, object)
ldstr "RunInt32OrNativeMultiUse({0}, push_i: false, use2: true) = {1}"
ldarg val
box int32
ldarg val
ldc.i4 0 // push_i
ldc.i4 1 // use2
call native int Program::Int32OrNativeMultiUse(int32 val, bool push_i, bool use2)
box native int
call void [mscorlib]System.Console::WriteLine(string, object, object)
ldstr "RunInt32OrNativeMultiUse({0}, push_i: true, use2: false) = {1}"
ldarg val
box int32
ldarg val
ldc.i4 1 // push_i
ldc.i4 0 // use2
call native int Program::Int32OrNativeMultiUse(int32 val, bool push_i, bool use2)
box native int
call void [mscorlib]System.Console::WriteLine(string, object, object)
ldstr "RunInt32OrNativeMultiUse({0}, push_i: true, use2: true) = {1}"
ldarg val
box int32
ldarg val
ldc.i4 1 // push_i
ldc.i4 1 // use2
call native int Program::Int32OrNativeMultiUse(int32 val, bool push_i, bool use2)
box native int
call void [mscorlib]System.Console::WriteLine(string, object, object)
ret
}
.method public static native int Int32OrNativeMultiUse(int32 val, bool push_i, bool use2)
{
ldarg.1
brtrue push_i
br push_i4
push_i4:
ldarg.0
ldarg.2
brtrue use2
br use1
push_i:
ldarg.0
conv.u
br use1
use1:
ldc.i4.1
add
ret
use2:
ldc.i4.2
add
ret
}
*/
.method public hidebysig static void Main (string[] args) cil managed
{
.maxstack 8
.entrypoint
call void Program::InlineAssignByte()
//call void Program::Int32OrNativeTests()
ret
} // end of method Main
.method public static void InlineAssignByte()
{
.locals init (
int8 local
)
ldstr "InlineAssignByte: WriteLine(local = {0})"
ldc.i4 300
dup
br pointless // this pointless branch is a workaround for https://github.com/dotnet/coreclr/issues/14784
// it doesn't have any effect on ILSpy as TransformAssignment runs after control-flow reconstruction
pointless:
// This assignment cannot be turned into a C# inline assignment, because doing so would truncate to 8 bits.
stloc.0
box int32
call void [mscorlib]System.Console::WriteLine(string, object)
ldstr "InlineAssignByte: local is {0}"
ldloc.0
box int32
call void [mscorlib]System.Console::WriteLine(string, object)
ret
}
/*
.method public static void Int32OrNativeTests()
{
ldstr "Int32OrNative(0x7fffffff, false) = {0}"
ldc.i4 0x7fffffff
ldc.i4 0
call native int Program::Int32OrNative(int32, bool)
box native int
call void [mscorlib]System.Console::WriteLine(string, object)
ldstr "Int32OrNative(0x7fffffff, true) = {0}"
ldc.i4 0x7fffffff
ldc.i4 1
call native int Program::Int32OrNative(int32, bool)
box native int
call void [mscorlib]System.Console::WriteLine(string, object)
ldstr "Int32OrNative(-1, false) = {0}"
ldc.i4.m1
ldc.i4 0
call native int Program::Int32OrNative(int32, bool)
box native int
call void [mscorlib]System.Console::WriteLine(string, object)
ldstr "Int32OrNative(-1, true) = {0}"
ldc.i4.m1
ldc.i4 1
call native int Program::Int32OrNative(int32, bool)
box native int
call void [mscorlib]System.Console::WriteLine(string, object)
ldstr "Int32OrNativeLoopStyle(0x7fffffff):"
call void [mscorlib]System.Console::WriteLine(string)
ldc.i4 0x7fffffff
call void Program::Int32OrNativeLoopStyle(int32)
ldstr "Int32OrNativeLoopStyle(-1):"
call void [mscorlib]System.Console::WriteLine(string)
ldc.i4.m1
call void Program::Int32OrNativeLoopStyle(int32)
ldstr "Int32OrNativeDeadCode(0x7fffffff) = {0}"
ldc.i4 0x7fffffff
call native int Program::Int32OrNativeDeadCode(int32)
box native int
call void [mscorlib]System.Console::WriteLine(string, object)
ldstr "Int32OrNativeDeadCode(-1) = {0}"
ldc.i4.m1
call native int Program::Int32OrNativeDeadCode(int32)
box native int
call void [mscorlib]System.Console::WriteLine(string, object)
ldc.i4 0x7fffffff
call void Program::RunInt32OrNativeMultiUse(int32)
ldc.i4.m1
call void Program::RunInt32OrNativeMultiUse(int32)
ret
}
.method public static native int Int32OrNative(int32 val, bool use_native)
{
ldarg.1
brtrue use_native_int
use_i4:
ldarg.0
br after_if
after_if:
ldc.i4.1
add
ret
use_native_int:
ldarg.0
conv.u
br after_if
}
.method public static void Int32OrNativeLoopStyle(int32 val)
{
.locals init (
int32 i
)
ldarg.0
loop:
ldc.i4.1
add
call void Program::Print(native int)
ldloc.0
brtrue end
ldc.i4.1
stloc.0
ldarg.0
conv.u
br loop
end:
ret
}
.method public static native int Int32OrNativeDeadCode(int32 val)
{
use_i4:
ldarg.0
br after_if
after_if:
ldc.i4.1
add
ret
use_native_int: // dead code
ldarg.0
conv.u
br after_if
}
.method public static void RunInt32OrNativeMultiUse(int32 val)
{
ldstr "RunInt32OrNativeMultiUse({0}, push_i: false, use2: false) = {1}"
ldarg val
box int32
ldarg val
ldc.i4 0 // push_i
ldc.i4 0 // use2
call native int Program::Int32OrNativeMultiUse(int32 val, bool push_i, bool use2)
box native int
call void [mscorlib]System.Console::WriteLine(string, object, object)
ldstr "RunInt32OrNativeMultiUse({0}, push_i: false, use2: true) = {1}"
ldarg val
box int32
ldarg val
ldc.i4 0 // push_i
ldc.i4 1 // use2
call native int Program::Int32OrNativeMultiUse(int32 val, bool push_i, bool use2)
box native int
call void [mscorlib]System.Console::WriteLine(string, object, object)
ldstr "RunInt32OrNativeMultiUse({0}, push_i: true, use2: false) = {1}"
ldarg val
box int32
ldarg val
ldc.i4 1 // push_i
ldc.i4 0 // use2
call native int Program::Int32OrNativeMultiUse(int32 val, bool push_i, bool use2)
box native int
call void [mscorlib]System.Console::WriteLine(string, object, object)
ldstr "RunInt32OrNativeMultiUse({0}, push_i: true, use2: true) = {1}"
ldarg val
box int32
ldarg val
ldc.i4 1 // push_i
ldc.i4 1 // use2
call native int Program::Int32OrNativeMultiUse(int32 val, bool push_i, bool use2)
box native int
call void [mscorlib]System.Console::WriteLine(string, object, object)
ret
}
.method public static native int Int32OrNativeMultiUse(int32 val, bool push_i, bool use2)
{
ldarg.1
brtrue push_i
br push_i4
push_i4:
ldarg.0
ldarg.2
brtrue use2
br use1
push_i:
ldarg.0
conv.u
br use1
use1:
ldc.i4.1
add
ret
use2:
ldc.i4.2
add
ret
}
*/
.method public static void Print(native int val)
{
ldarg.0
box native int
call void [mscorlib]System.Console::WriteLine(object)
ret
}
.method public static void Print(native int val)
{
ldarg.0
box native int
call void [mscorlib]System.Console::WriteLine(object)
ret
}
}

244
ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.cs

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
@ -30,7 +31,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -30,7 +31,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
Two = 2,
Four = 4
}
public enum ShortEnum : short
{
None = 0,
One = 1,
Two = 2,
Four = 4
}
private struct StructContainer
{
public bool HasIndex;
@ -40,11 +49,17 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -40,11 +49,17 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public class MutableClass
{
public int Field;
public short ShortField;
public int Property {
get;
set;
}
public byte ByteProperty {
get;
set;
}
public uint this[string name] {
get {
@ -64,13 +79,22 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -64,13 +79,22 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
private int[] array1;
private StructContainer field1;
private MyEnum enumField;
private Dictionary<ushort, ushort> ushortDict = new Dictionary<ushort, ushort>();
private ushort ushortField;
private ShortEnum shortEnumField;
public static int StaticField;
public static short StaticShortField;
public static int StaticProperty {
get;
set;
}
public static ShortEnum StaticShortProperty {
get;
set;
}
private MutableClass M()
{
return new MutableClass();
@ -200,6 +224,8 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -200,6 +224,8 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public void NestedField()
{
if (this.field1.HasIndex) {
Console.WriteLine(this.field1.Field *= 2);
this.field1.Field++;
Console.WriteLine(this.field1.Field++);
}
}
@ -208,8 +234,18 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -208,8 +234,18 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
this.enumField |= MyEnum.Two;
this.enumField &= ~MyEnum.Four;
this.enumField += 2;
this.enumField -= 3;
}
public void ShortEnumTest()
{
this.shortEnumField |= ShortEnum.Two;
this.shortEnumField &= ShortEnum.Four;
this.shortEnumField += 2;
this.shortEnumField -= 3;
}
public int PreIncrementInAddition(int i, int j)
{
return i + ++j;
@ -230,51 +266,146 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -230,51 +266,146 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
array[pos]++;
}
public void DoubleArrayElement(int[] array, int pos)
{
array[pos] *= 2;
}
public int DoubleArrayElementAndReturn(int[] array, int pos)
{
return array[pos] *= 2;
}
public int PreIncrementArrayElementShort(short[] array, int pos)
{
return --array[pos];
}
public int PostIncrementArrayElementShort(short[] array, int pos)
{
return array[pos]++;
}
public void IncrementArrayElementShort(short[] array, int pos)
{
array[pos]++;
}
public void DoubleArrayElementShort(short[] array, int pos)
{
array[pos] *= 2;
}
public short DoubleArrayElementShortAndReturn(short[] array, int pos)
{
return array[pos] *= 2;
}
public int PreIncrementInstanceField()
{
return ++this.M().Field;
}
//public int PostIncrementInstanceField()
//{
// return this.M().Field++;
//}
public int PostIncrementInstanceField()
{
return this.M().Field++;
}
public void IncrementInstanceField()
{
this.M().Field++;
}
public void DoubleInstanceField()
{
this.M().Field *= 2;
}
public int DoubleInstanceFieldAndReturn()
{
return this.M().Field *= 2;
}
public int PreIncrementInstanceField2(MutableClass m)
{
return ++m.Field;
}
//public int PostIncrementInstanceField2(MutableClass m)
//{
// return m.Field++;
//}
public int PostIncrementInstanceField2(MutableClass m)
{
return m.Field++;
}
public void IncrementInstanceField2(MutableClass m)
{
m.Field++;
}
public int PreIncrementInstanceFieldShort()
{
return ++this.M().ShortField;
}
public int PostIncrementInstanceFieldShort()
{
return this.M().ShortField++;
}
public void IncrementInstanceFieldShort()
{
this.M().ShortField++;
}
public int PreIncrementInstanceProperty()
{
return ++this.M().Property;
}
//public int PostIncrementInstanceProperty()
//{
// return this.M().Property++;
//}
public int PostIncrementInstanceProperty()
{
return this.M().Property++;
}
public void IncrementInstanceProperty()
{
this.M().Property++;
}
public void DoubleInstanceProperty()
{
this.M().Property *= 2;
}
public int DoubleInstancePropertyAndReturn()
{
return this.M().Property *= 2;
}
public int PreIncrementInstancePropertyByte()
{
return ++this.M().ByteProperty;
}
public int PostIncrementInstancePropertyByte()
{
return this.M().ByteProperty++;
}
public void IncrementInstancePropertyByte()
{
this.M().ByteProperty++;
}
public void DoubleInstancePropertyByte()
{
this.M().ByteProperty *= 2;
}
public int DoubleInstancePropertyByteAndReturn()
{
return this.M().ByteProperty *= 2;
}
public int PreIncrementStaticField()
{
return ++CompoundAssignmentTest.StaticField;
@ -290,20 +421,80 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -290,20 +421,80 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
CompoundAssignmentTest.StaticField++;
}
public void DoubleStaticField()
{
CompoundAssignmentTest.StaticField *= 2;
}
public int DoubleStaticFieldAndReturn()
{
return CompoundAssignmentTest.StaticField *= 2;
}
public int PreIncrementStaticFieldShort()
{
return ++CompoundAssignmentTest.StaticShortField;
}
public int PostIncrementStaticFieldShort()
{
return CompoundAssignmentTest.StaticShortField++;
}
public void IncrementStaticFieldShort()
{
CompoundAssignmentTest.StaticShortField++;
}
public void DoubleStaticFieldShort()
{
CompoundAssignmentTest.StaticShortField *= 2;
}
public short DoubleStaticFieldAndReturnShort()
{
return CompoundAssignmentTest.StaticShortField *= 2;
}
public int PreIncrementStaticProperty()
{
return ++CompoundAssignmentTest.StaticProperty;
}
//public int PostIncrementStaticProperty()
//{
// return CompoundAssignmentTest.StaticProperty++;
//}
public int PostIncrementStaticProperty()
{
return CompoundAssignmentTest.StaticProperty++;
}
public void IncrementStaticProperty()
{
CompoundAssignmentTest.StaticProperty++;
}
public void DoubleStaticProperty()
{
CompoundAssignmentTest.StaticProperty *= 2;
}
public int DoubleStaticPropertyAndReturn()
{
return CompoundAssignmentTest.StaticProperty *= 2;
}
public ShortEnum PreIncrementStaticPropertyShort()
{
return ++CompoundAssignmentTest.StaticShortProperty;
}
public ShortEnum PostIncrementStaticPropertyShort()
{
return CompoundAssignmentTest.StaticShortProperty++;
}
public void IncrementStaticPropertyShort()
{
CompoundAssignmentTest.StaticShortProperty++;
}
private static Item GetItem(object obj)
{
@ -315,5 +506,18 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -315,5 +506,18 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
Item item = CompoundAssignmentTest.GetItem(null);
item.Self = item;
}
private void Issue954(ref MyEnum a, MyEnum b)
{
// cannot decompile to: "a %= b;", because the % operator does not apply to enums
a = (MyEnum)((int)a % (int)b);
// same with enum field:
this.enumField = (MyEnum)((int)this.enumField % (int)b);
}
private void Issue588(ushort val)
{
this.ushortDict.Add(this.ushortField++, val);
}
}
}

1008
ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.il

File diff suppressed because it is too large Load Diff

810
ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.opt.il

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
// Microsoft (R) .NET Framework IL Disassembler. Version 4.0.30319.18020
// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0
// Copyright (c) Microsoft Corporation. All rights reserved.
@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly d4bhqxbe
.assembly '0ffxad1m'
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
@ -20,15 +20,15 @@ @@ -20,15 +20,15 @@
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module d4bhqxbe.dll
// MVID: {B884BD61-6FE3-4893-B161-02EE675C0DF0}
.module '0ffxad1m.dll'
// MVID: {C53B3CFA-3FF4-4724-8DBE-8B180FA612BA}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x003A0000
// Image base: 0x028A0000
// =============== CLASS MEMBERS DECLARATION ===================
@ -47,6 +47,16 @@ @@ -47,6 +47,16 @@
.field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MyEnum Four = int32(0x00000004)
} // end of class MyEnum
.class auto ansi sealed nested public ShortEnum
extends [mscorlib]System.Enum
{
.field public specialname rtspecialname int16 value__
.field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum None = int16(0x0000)
.field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum One = int16(0x0001)
.field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum Two = int16(0x0002)
.field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum Four = int16(0x0004)
} // end of class ShortEnum
.class sequential ansi sealed nested private beforefieldinit StructContainer
extends [mscorlib]System.ValueType
{
@ -59,8 +69,11 @@ @@ -59,8 +69,11 @@
{
.custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = ( 01 00 04 49 74 65 6D 00 00 ) // ...Item..
.field public int32 Field
.field public int16 ShortField
.field private int32 '<Property>k__BackingField'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.field private uint8 '<ByteProperty>k__BackingField'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.method public hidebysig specialname
instance int32 get_Property() cil managed
{
@ -84,6 +97,29 @@ @@ -84,6 +97,29 @@
IL_0007: ret
} // end of method MutableClass::set_Property
.method public hidebysig specialname
instance uint8 get_ByteProperty() cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld uint8 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::'<ByteProperty>k__BackingField'
IL_0006: ret
} // end of method MutableClass::get_ByteProperty
.method public hidebysig specialname
instance void set_ByteProperty(uint8 'value') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: stfld uint8 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::'<ByteProperty>k__BackingField'
IL_0007: ret
} // end of method MutableClass::set_ByteProperty
.method public hidebysig specialname
instance uint32 get_Item(string name) cil managed
{
@ -117,6 +153,11 @@ @@ -117,6 +153,11 @@
.get instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::get_Property()
.set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::set_Property(int32)
} // end of property MutableClass::Property
.property instance uint8 ByteProperty()
{
.set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::set_ByteProperty(uint8)
.get instance uint8 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::get_ByteProperty()
} // end of property MutableClass::ByteProperty
.property instance uint32 Item(string)
{
.get instance uint32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::get_Item(string)
@ -145,9 +186,15 @@ @@ -145,9 +186,15 @@
.field private int32[] array1
.field private valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/StructContainer field1
.field private valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MyEnum enumField
.field private class [mscorlib]System.Collections.Generic.Dictionary`2<uint16,uint16> ushortDict
.field private uint16 ushortField
.field private valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum shortEnumField
.field public static int32 StaticField
.field public static int16 StaticShortField
.field private static int32 '<StaticProperty>k__BackingField'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.field private static valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum '<StaticShortProperty>k__BackingField'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.method public hidebysig specialname static
int32 get_StaticProperty() cil managed
{
@ -169,6 +216,28 @@ @@ -169,6 +216,28 @@
IL_0006: ret
} // end of method CompoundAssignmentTest::set_StaticProperty
.method public hidebysig specialname static
valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum
get_StaticShortProperty() cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 6 (0x6)
.maxstack 8
IL_0000: ldsfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::'<StaticShortProperty>k__BackingField'
IL_0005: ret
} // end of method CompoundAssignmentTest::get_StaticShortProperty
.method public hidebysig specialname static
void set_StaticShortProperty(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum 'value') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: stsfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::'<StaticShortProperty>k__BackingField'
IL_0006: ret
} // end of method CompoundAssignmentTest::set_StaticShortProperty
.method private hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass
M() cil managed
{
@ -568,32 +637,51 @@ @@ -568,32 +637,51 @@
.method public hidebysig instance void
NestedField() cil managed
{
// Code size 41 (0x29)
// Code size 87 (0x57)
.maxstack 3
.locals init (int32 V_0)
.locals init (int32 V_0,
int32 V_1)
IL_0000: ldarg.0
IL_0001: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/StructContainer ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::field1
IL_0006: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/StructContainer::HasIndex
IL_000b: brfalse.s IL_0028
IL_000b: brfalse.s IL_0056
IL_000d: ldarg.0
IL_000e: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/StructContainer ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::field1
IL_0013: dup
IL_0014: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/StructContainer::Field
IL_0019: dup
IL_001a: stloc.0
IL_001b: ldc.i4.1
IL_001c: add
IL_0019: ldc.i4.2
IL_001a: mul
IL_001b: dup
IL_001c: stloc.0
IL_001d: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/StructContainer::Field
IL_0022: ldloc.0
IL_0023: call void [mscorlib]System.Console::WriteLine(int32)
IL_0028: ret
IL_0028: ldarg.0
IL_0029: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/StructContainer ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::field1
IL_002e: dup
IL_002f: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/StructContainer::Field
IL_0034: ldc.i4.1
IL_0035: add
IL_0036: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/StructContainer::Field
IL_003b: ldarg.0
IL_003c: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/StructContainer ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::field1
IL_0041: dup
IL_0042: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/StructContainer::Field
IL_0047: dup
IL_0048: stloc.1
IL_0049: ldc.i4.1
IL_004a: add
IL_004b: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/StructContainer::Field
IL_0050: ldloc.1
IL_0051: call void [mscorlib]System.Console::WriteLine(int32)
IL_0056: ret
} // end of method CompoundAssignmentTest::NestedField
.method public hidebysig instance void
Enum() cil managed
{
// Code size 30 (0x1e)
// Code size 58 (0x3a)
.maxstack 8
IL_0000: ldarg.0
IL_0001: dup
@ -607,9 +695,57 @@ @@ -607,9 +695,57 @@
IL_0015: ldc.i4.s -5
IL_0017: and
IL_0018: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::enumField
IL_001d: ret
IL_001d: ldarg.0
IL_001e: dup
IL_001f: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::enumField
IL_0024: ldc.i4.2
IL_0025: add
IL_0026: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::enumField
IL_002b: ldarg.0
IL_002c: dup
IL_002d: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::enumField
IL_0032: ldc.i4.3
IL_0033: sub
IL_0034: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::enumField
IL_0039: ret
} // end of method CompoundAssignmentTest::Enum
.method public hidebysig instance void
ShortEnumTest() cil managed
{
// Code size 61 (0x3d)
.maxstack 8
IL_0000: ldarg.0
IL_0001: dup
IL_0002: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::shortEnumField
IL_0007: ldc.i4.2
IL_0008: or
IL_0009: conv.i2
IL_000a: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::shortEnumField
IL_000f: ldarg.0
IL_0010: dup
IL_0011: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::shortEnumField
IL_0016: ldc.i4.4
IL_0017: and
IL_0018: conv.i2
IL_0019: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::shortEnumField
IL_001e: ldarg.0
IL_001f: dup
IL_0020: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::shortEnumField
IL_0025: ldc.i4.2
IL_0026: add
IL_0027: conv.i2
IL_0028: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::shortEnumField
IL_002d: ldarg.0
IL_002e: dup
IL_002f: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::shortEnumField
IL_0034: ldc.i4.3
IL_0035: sub
IL_0036: conv.i2
IL_0037: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::shortEnumField
IL_003c: ret
} // end of method CompoundAssignmentTest::ShortEnumTest
.method public hidebysig instance int32
PreIncrementInAddition(int32 i,
int32 j) cil managed
@ -685,6 +821,146 @@ @@ -685,6 +821,146 @@
IL_0014: ret
} // end of method CompoundAssignmentTest::IncrementArrayElement
.method public hidebysig instance void
DoubleArrayElement(int32[] 'array',
int32 pos) cil managed
{
// Code size 21 (0x15)
.maxstack 8
IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: ldelema [mscorlib]System.Int32
IL_0007: dup
IL_0008: ldobj [mscorlib]System.Int32
IL_000d: ldc.i4.2
IL_000e: mul
IL_000f: stobj [mscorlib]System.Int32
IL_0014: ret
} // end of method CompoundAssignmentTest::DoubleArrayElement
.method public hidebysig instance int32
DoubleArrayElementAndReturn(int32[] 'array',
int32 pos) cil managed
{
// Code size 24 (0x18)
.maxstack 3
.locals init (int32 V_0)
IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: ldelema [mscorlib]System.Int32
IL_0007: dup
IL_0008: ldobj [mscorlib]System.Int32
IL_000d: ldc.i4.2
IL_000e: mul
IL_000f: dup
IL_0010: stloc.0
IL_0011: stobj [mscorlib]System.Int32
IL_0016: ldloc.0
IL_0017: ret
} // end of method CompoundAssignmentTest::DoubleArrayElementAndReturn
.method public hidebysig instance int32
PreIncrementArrayElementShort(int16[] 'array',
int32 pos) cil managed
{
// Code size 25 (0x19)
.maxstack 3
.locals init (int16 V_0)
IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: ldelema [mscorlib]System.Int16
IL_0007: dup
IL_0008: ldobj [mscorlib]System.Int16
IL_000d: ldc.i4.1
IL_000e: sub
IL_000f: conv.i2
IL_0010: dup
IL_0011: stloc.0
IL_0012: stobj [mscorlib]System.Int16
IL_0017: ldloc.0
IL_0018: ret
} // end of method CompoundAssignmentTest::PreIncrementArrayElementShort
.method public hidebysig instance int32
PostIncrementArrayElementShort(int16[] 'array',
int32 pos) cil managed
{
// Code size 25 (0x19)
.maxstack 3
.locals init (int16 V_0)
IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: ldelema [mscorlib]System.Int16
IL_0007: dup
IL_0008: ldobj [mscorlib]System.Int16
IL_000d: dup
IL_000e: stloc.0
IL_000f: ldc.i4.1
IL_0010: add
IL_0011: conv.i2
IL_0012: stobj [mscorlib]System.Int16
IL_0017: ldloc.0
IL_0018: ret
} // end of method CompoundAssignmentTest::PostIncrementArrayElementShort
.method public hidebysig instance void
IncrementArrayElementShort(int16[] 'array',
int32 pos) cil managed
{
// Code size 22 (0x16)
.maxstack 8
IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: ldelema [mscorlib]System.Int16
IL_0007: dup
IL_0008: ldobj [mscorlib]System.Int16
IL_000d: ldc.i4.1
IL_000e: add
IL_000f: conv.i2
IL_0010: stobj [mscorlib]System.Int16
IL_0015: ret
} // end of method CompoundAssignmentTest::IncrementArrayElementShort
.method public hidebysig instance void
DoubleArrayElementShort(int16[] 'array',
int32 pos) cil managed
{
// Code size 22 (0x16)
.maxstack 8
IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: ldelema [mscorlib]System.Int16
IL_0007: dup
IL_0008: ldobj [mscorlib]System.Int16
IL_000d: ldc.i4.2
IL_000e: mul
IL_000f: conv.i2
IL_0010: stobj [mscorlib]System.Int16
IL_0015: ret
} // end of method CompoundAssignmentTest::DoubleArrayElementShort
.method public hidebysig instance int16
DoubleArrayElementShortAndReturn(int16[] 'array',
int32 pos) cil managed
{
// Code size 25 (0x19)
.maxstack 3
.locals init (int16 V_0)
IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: ldelema [mscorlib]System.Int16
IL_0007: dup
IL_0008: ldobj [mscorlib]System.Int16
IL_000d: ldc.i4.2
IL_000e: mul
IL_000f: conv.i2
IL_0010: dup
IL_0011: stloc.0
IL_0012: stobj [mscorlib]System.Int16
IL_0017: ldloc.0
IL_0018: ret
} // end of method CompoundAssignmentTest::DoubleArrayElementShortAndReturn
.method public hidebysig instance int32
PreIncrementInstanceField() cil managed
{
@ -704,6 +980,25 @@ @@ -704,6 +980,25 @@
IL_0016: ret
} // end of method CompoundAssignmentTest::PreIncrementInstanceField
.method public hidebysig instance int32
PostIncrementInstanceField() cil managed
{
// Code size 23 (0x17)
.maxstack 3
.locals init (int32 V_0)
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::Field
IL_000c: dup
IL_000d: stloc.0
IL_000e: ldc.i4.1
IL_000f: add
IL_0010: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::Field
IL_0015: ldloc.0
IL_0016: ret
} // end of method CompoundAssignmentTest::PostIncrementInstanceField
.method public hidebysig instance void
IncrementInstanceField() cil managed
{
@ -719,6 +1014,40 @@ @@ -719,6 +1014,40 @@
IL_0013: ret
} // end of method CompoundAssignmentTest::IncrementInstanceField
.method public hidebysig instance void
DoubleInstanceField() cil managed
{
// Code size 20 (0x14)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::Field
IL_000c: ldc.i4.2
IL_000d: mul
IL_000e: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::Field
IL_0013: ret
} // end of method CompoundAssignmentTest::DoubleInstanceField
.method public hidebysig instance int32
DoubleInstanceFieldAndReturn() cil managed
{
// Code size 23 (0x17)
.maxstack 3
.locals init (int32 V_0)
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::Field
IL_000c: ldc.i4.2
IL_000d: mul
IL_000e: dup
IL_000f: stloc.0
IL_0010: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::Field
IL_0015: ldloc.0
IL_0016: ret
} // end of method CompoundAssignmentTest::DoubleInstanceFieldAndReturn
.method public hidebysig instance int32
PreIncrementInstanceField2(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass m) cil managed
{
@ -737,6 +1066,24 @@ @@ -737,6 +1066,24 @@
IL_0011: ret
} // end of method CompoundAssignmentTest::PreIncrementInstanceField2
.method public hidebysig instance int32
PostIncrementInstanceField2(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass m) cil managed
{
// Code size 18 (0x12)
.maxstack 3
.locals init (int32 V_0)
IL_0000: ldarg.1
IL_0001: dup
IL_0002: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::Field
IL_0007: dup
IL_0008: stloc.0
IL_0009: ldc.i4.1
IL_000a: add
IL_000b: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::Field
IL_0010: ldloc.0
IL_0011: ret
} // end of method CompoundAssignmentTest::PostIncrementInstanceField2
.method public hidebysig instance void
IncrementInstanceField2(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass m) cil managed
{
@ -751,6 +1098,62 @@ @@ -751,6 +1098,62 @@
IL_000e: ret
} // end of method CompoundAssignmentTest::IncrementInstanceField2
.method public hidebysig instance int32
PreIncrementInstanceFieldShort() cil managed
{
// Code size 24 (0x18)
.maxstack 3
.locals init (int16 V_0)
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: ldfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::ShortField
IL_000c: ldc.i4.1
IL_000d: add
IL_000e: conv.i2
IL_000f: dup
IL_0010: stloc.0
IL_0011: stfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::ShortField
IL_0016: ldloc.0
IL_0017: ret
} // end of method CompoundAssignmentTest::PreIncrementInstanceFieldShort
.method public hidebysig instance int32
PostIncrementInstanceFieldShort() cil managed
{
// Code size 24 (0x18)
.maxstack 3
.locals init (int16 V_0)
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: ldfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::ShortField
IL_000c: dup
IL_000d: stloc.0
IL_000e: ldc.i4.1
IL_000f: add
IL_0010: conv.i2
IL_0011: stfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::ShortField
IL_0016: ldloc.0
IL_0017: ret
} // end of method CompoundAssignmentTest::PostIncrementInstanceFieldShort
.method public hidebysig instance void
IncrementInstanceFieldShort() cil managed
{
// Code size 21 (0x15)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: ldfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::ShortField
IL_000c: ldc.i4.1
IL_000d: add
IL_000e: conv.i2
IL_000f: stfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::ShortField
IL_0014: ret
} // end of method CompoundAssignmentTest::IncrementInstanceFieldShort
.method public hidebysig instance int32
PreIncrementInstanceProperty() cil managed
{
@ -770,6 +1173,25 @@ @@ -770,6 +1173,25 @@
IL_0016: ret
} // end of method CompoundAssignmentTest::PreIncrementInstanceProperty
.method public hidebysig instance int32
PostIncrementInstanceProperty() cil managed
{
// Code size 23 (0x17)
.maxstack 3
.locals init (int32 V_0)
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::get_Property()
IL_000c: dup
IL_000d: stloc.0
IL_000e: ldc.i4.1
IL_000f: add
IL_0010: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::set_Property(int32)
IL_0015: ldloc.0
IL_0016: ret
} // end of method CompoundAssignmentTest::PostIncrementInstanceProperty
.method public hidebysig instance void
IncrementInstanceProperty() cil managed
{
@ -785,6 +1207,132 @@ @@ -785,6 +1207,132 @@
IL_0013: ret
} // end of method CompoundAssignmentTest::IncrementInstanceProperty
.method public hidebysig instance void
DoubleInstanceProperty() cil managed
{
// Code size 20 (0x14)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::get_Property()
IL_000c: ldc.i4.2
IL_000d: mul
IL_000e: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::set_Property(int32)
IL_0013: ret
} // end of method CompoundAssignmentTest::DoubleInstanceProperty
.method public hidebysig instance int32
DoubleInstancePropertyAndReturn() cil managed
{
// Code size 23 (0x17)
.maxstack 3
.locals init (int32 V_0)
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::get_Property()
IL_000c: ldc.i4.2
IL_000d: mul
IL_000e: dup
IL_000f: stloc.0
IL_0010: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::set_Property(int32)
IL_0015: ldloc.0
IL_0016: ret
} // end of method CompoundAssignmentTest::DoubleInstancePropertyAndReturn
.method public hidebysig instance int32
PreIncrementInstancePropertyByte() cil managed
{
// Code size 24 (0x18)
.maxstack 3
.locals init (uint8 V_0)
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: callvirt instance uint8 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::get_ByteProperty()
IL_000c: ldc.i4.1
IL_000d: add
IL_000e: conv.u1
IL_000f: dup
IL_0010: stloc.0
IL_0011: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::set_ByteProperty(uint8)
IL_0016: ldloc.0
IL_0017: ret
} // end of method CompoundAssignmentTest::PreIncrementInstancePropertyByte
.method public hidebysig instance int32
PostIncrementInstancePropertyByte() cil managed
{
// Code size 24 (0x18)
.maxstack 3
.locals init (uint8 V_0)
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: callvirt instance uint8 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::get_ByteProperty()
IL_000c: dup
IL_000d: stloc.0
IL_000e: ldc.i4.1
IL_000f: add
IL_0010: conv.u1
IL_0011: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::set_ByteProperty(uint8)
IL_0016: ldloc.0
IL_0017: ret
} // end of method CompoundAssignmentTest::PostIncrementInstancePropertyByte
.method public hidebysig instance void
IncrementInstancePropertyByte() cil managed
{
// Code size 21 (0x15)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: callvirt instance uint8 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::get_ByteProperty()
IL_000c: ldc.i4.1
IL_000d: add
IL_000e: conv.u1
IL_000f: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::set_ByteProperty(uint8)
IL_0014: ret
} // end of method CompoundAssignmentTest::IncrementInstancePropertyByte
.method public hidebysig instance void
DoubleInstancePropertyByte() cil managed
{
// Code size 21 (0x15)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: callvirt instance uint8 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::get_ByteProperty()
IL_000c: ldc.i4.2
IL_000d: mul
IL_000e: conv.u1
IL_000f: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::set_ByteProperty(uint8)
IL_0014: ret
} // end of method CompoundAssignmentTest::DoubleInstancePropertyByte
.method public hidebysig instance int32
DoubleInstancePropertyByteAndReturn() cil managed
{
// Code size 24 (0x18)
.maxstack 3
.locals init (uint8 V_0)
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: callvirt instance uint8 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::get_ByteProperty()
IL_000c: ldc.i4.2
IL_000d: mul
IL_000e: conv.u1
IL_000f: dup
IL_0010: stloc.0
IL_0011: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::set_ByteProperty(uint8)
IL_0016: ldloc.0
IL_0017: ret
} // end of method CompoundAssignmentTest::DoubleInstancePropertyByteAndReturn
.method public hidebysig instance int32
PreIncrementStaticField() cil managed
{
@ -823,6 +1371,99 @@ @@ -823,6 +1371,99 @@
IL_000c: ret
} // end of method CompoundAssignmentTest::IncrementStaticField
.method public hidebysig instance void
DoubleStaticField() cil managed
{
// Code size 13 (0xd)
.maxstack 8
IL_0000: ldsfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticField
IL_0005: ldc.i4.2
IL_0006: mul
IL_0007: stsfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticField
IL_000c: ret
} // end of method CompoundAssignmentTest::DoubleStaticField
.method public hidebysig instance int32
DoubleStaticFieldAndReturn() cil managed
{
// Code size 14 (0xe)
.maxstack 8
IL_0000: ldsfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticField
IL_0005: ldc.i4.2
IL_0006: mul
IL_0007: dup
IL_0008: stsfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticField
IL_000d: ret
} // end of method CompoundAssignmentTest::DoubleStaticFieldAndReturn
.method public hidebysig instance int32
PreIncrementStaticFieldShort() cil managed
{
// Code size 15 (0xf)
.maxstack 8
IL_0000: ldsfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticShortField
IL_0005: ldc.i4.1
IL_0006: add
IL_0007: conv.i2
IL_0008: dup
IL_0009: stsfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticShortField
IL_000e: ret
} // end of method CompoundAssignmentTest::PreIncrementStaticFieldShort
.method public hidebysig instance int32
PostIncrementStaticFieldShort() cil managed
{
// Code size 15 (0xf)
.maxstack 8
IL_0000: ldsfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticShortField
IL_0005: dup
IL_0006: ldc.i4.1
IL_0007: add
IL_0008: conv.i2
IL_0009: stsfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticShortField
IL_000e: ret
} // end of method CompoundAssignmentTest::PostIncrementStaticFieldShort
.method public hidebysig instance void
IncrementStaticFieldShort() cil managed
{
// Code size 14 (0xe)
.maxstack 8
IL_0000: ldsfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticShortField
IL_0005: ldc.i4.1
IL_0006: add
IL_0007: conv.i2
IL_0008: stsfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticShortField
IL_000d: ret
} // end of method CompoundAssignmentTest::IncrementStaticFieldShort
.method public hidebysig instance void
DoubleStaticFieldShort() cil managed
{
// Code size 14 (0xe)
.maxstack 8
IL_0000: ldsfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticShortField
IL_0005: ldc.i4.2
IL_0006: mul
IL_0007: conv.i2
IL_0008: stsfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticShortField
IL_000d: ret
} // end of method CompoundAssignmentTest::DoubleStaticFieldShort
.method public hidebysig instance int16
DoubleStaticFieldAndReturnShort() cil managed
{
// Code size 15 (0xf)
.maxstack 8
IL_0000: ldsfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticShortField
IL_0005: ldc.i4.2
IL_0006: mul
IL_0007: conv.i2
IL_0008: dup
IL_0009: stsfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticShortField
IL_000e: ret
} // end of method CompoundAssignmentTest::DoubleStaticFieldAndReturnShort
.method public hidebysig instance int32
PreIncrementStaticProperty() cil managed
{
@ -836,6 +1477,19 @@ @@ -836,6 +1477,19 @@
IL_000d: ret
} // end of method CompoundAssignmentTest::PreIncrementStaticProperty
.method public hidebysig instance int32
PostIncrementStaticProperty() cil managed
{
// Code size 14 (0xe)
.maxstack 8
IL_0000: call int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::get_StaticProperty()
IL_0005: dup
IL_0006: ldc.i4.1
IL_0007: add
IL_0008: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::set_StaticProperty(int32)
IL_000d: ret
} // end of method CompoundAssignmentTest::PostIncrementStaticProperty
.method public hidebysig instance void
IncrementStaticProperty() cil managed
{
@ -848,6 +1502,72 @@ @@ -848,6 +1502,72 @@
IL_000c: ret
} // end of method CompoundAssignmentTest::IncrementStaticProperty
.method public hidebysig instance void
DoubleStaticProperty() cil managed
{
// Code size 13 (0xd)
.maxstack 8
IL_0000: call int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::get_StaticProperty()
IL_0005: ldc.i4.2
IL_0006: mul
IL_0007: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::set_StaticProperty(int32)
IL_000c: ret
} // end of method CompoundAssignmentTest::DoubleStaticProperty
.method public hidebysig instance int32
DoubleStaticPropertyAndReturn() cil managed
{
// Code size 14 (0xe)
.maxstack 8
IL_0000: call int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::get_StaticProperty()
IL_0005: ldc.i4.2
IL_0006: mul
IL_0007: dup
IL_0008: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::set_StaticProperty(int32)
IL_000d: ret
} // end of method CompoundAssignmentTest::DoubleStaticPropertyAndReturn
.method public hidebysig instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum
PreIncrementStaticPropertyShort() cil managed
{
// Code size 15 (0xf)
.maxstack 8
IL_0000: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::get_StaticShortProperty()
IL_0005: ldc.i4.1
IL_0006: add
IL_0007: conv.i2
IL_0008: dup
IL_0009: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::set_StaticShortProperty(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum)
IL_000e: ret
} // end of method CompoundAssignmentTest::PreIncrementStaticPropertyShort
.method public hidebysig instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum
PostIncrementStaticPropertyShort() cil managed
{
// Code size 15 (0xf)
.maxstack 8
IL_0000: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::get_StaticShortProperty()
IL_0005: dup
IL_0006: ldc.i4.1
IL_0007: add
IL_0008: conv.i2
IL_0009: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::set_StaticShortProperty(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum)
IL_000e: ret
} // end of method CompoundAssignmentTest::PostIncrementStaticPropertyShort
.method public hidebysig instance void
IncrementStaticPropertyShort() cil managed
{
// Code size 14 (0xe)
.maxstack 8
IL_0000: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::get_StaticShortProperty()
IL_0005: ldc.i4.1
IL_0006: add
IL_0007: conv.i2
IL_0008: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::set_StaticShortProperty(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum)
IL_000d: ret
} // end of method CompoundAssignmentTest::IncrementStaticPropertyShort
.method private hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/Item
GetItem(object obj) cil managed
{
@ -871,14 +1591,62 @@ @@ -871,14 +1591,62 @@
IL_000e: ret
} // end of method CompoundAssignmentTest::Issue882
.method private hidebysig instance void
Issue954(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MyEnum& a,
valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MyEnum b) cil managed
{
// Code size 21 (0x15)
.maxstack 8
IL_0000: ldarg.1
IL_0001: ldarg.1
IL_0002: ldind.i4
IL_0003: ldarg.2
IL_0004: rem
IL_0005: stind.i4
IL_0006: ldarg.0
IL_0007: ldarg.0
IL_0008: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::enumField
IL_000d: ldarg.2
IL_000e: rem
IL_000f: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::enumField
IL_0014: ret
} // end of method CompoundAssignmentTest::Issue954
.method private hidebysig instance void
Issue588(uint16 val) cil managed
{
// Code size 31 (0x1f)
.maxstack 4
.locals init (uint16 V_0)
IL_0000: ldarg.0
IL_0001: ldfld class [mscorlib]System.Collections.Generic.Dictionary`2<uint16,uint16> ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::ushortDict
IL_0006: ldarg.0
IL_0007: dup
IL_0008: ldfld uint16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::ushortField
IL_000d: dup
IL_000e: stloc.0
IL_000f: ldc.i4.1
IL_0010: add
IL_0011: conv.u2
IL_0012: stfld uint16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::ushortField
IL_0017: ldloc.0
IL_0018: ldarg.1
IL_0019: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2<uint16,uint16>::Add(!0,
!1)
IL_001e: ret
} // end of method CompoundAssignmentTest::Issue588
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
// Code size 18 (0x12)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.Dictionary`2<uint16,uint16>::.ctor()
IL_0006: stfld class [mscorlib]System.Collections.Generic.Dictionary`2<uint16,uint16> ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::ushortDict
IL_000b: ldarg.0
IL_000c: call instance void [mscorlib]System.Object::.ctor()
IL_0011: ret
} // end of method CompoundAssignmentTest::.ctor
.property int32 StaticProperty()
@ -886,6 +1654,12 @@ @@ -886,6 +1654,12 @@
.get int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::get_StaticProperty()
.set void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::set_StaticProperty(int32)
} // end of property CompoundAssignmentTest::StaticProperty
.property valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum
StaticShortProperty()
{
.get valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::get_StaticShortProperty()
.set void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::set_StaticShortProperty(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum)
} // end of property CompoundAssignmentTest::StaticShortProperty
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest

806
ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.opt.roslyn.il

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
// Microsoft (R) .NET Framework IL Disassembler. Version 4.0.30319.18020
// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0
// Copyright (c) Microsoft Corporation. All rights reserved.
@ -25,14 +25,14 @@ @@ -25,14 +25,14 @@
.ver 0:0:0:0
}
.module CompoundAssignmentTest.dll
// MVID: {6E5749EE-F4C5-4B86-96FC-F4A665551BA6}
// MVID: {EE880025-0C8C-414F-BD89-E5DB86D9B5FA}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x028A0000
// Image base: 0x016C0000
// =============== CLASS MEMBERS DECLARATION ===================
@ -51,6 +51,16 @@ @@ -51,6 +51,16 @@
.field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MyEnum Four = int32(0x00000004)
} // end of class MyEnum
.class auto ansi sealed nested public ShortEnum
extends [mscorlib]System.Enum
{
.field public specialname rtspecialname int16 value__
.field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum None = int16(0x0000)
.field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum One = int16(0x0001)
.field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum Two = int16(0x0002)
.field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum Four = int16(0x0004)
} // end of class ShortEnum
.class sequential ansi sealed nested private beforefieldinit StructContainer
extends [mscorlib]System.ValueType
{
@ -63,8 +73,11 @@ @@ -63,8 +73,11 @@
{
.custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = ( 01 00 04 49 74 65 6D 00 00 ) // ...Item..
.field public int32 Field
.field public int16 ShortField
.field private int32 '<Property>k__BackingField'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.field private uint8 '<ByteProperty>k__BackingField'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.method public hidebysig specialname
instance int32 get_Property() cil managed
{
@ -88,6 +101,29 @@ @@ -88,6 +101,29 @@
IL_0007: ret
} // end of method MutableClass::set_Property
.method public hidebysig specialname
instance uint8 get_ByteProperty() cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld uint8 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::'<ByteProperty>k__BackingField'
IL_0006: ret
} // end of method MutableClass::get_ByteProperty
.method public hidebysig specialname
instance void set_ByteProperty(uint8 'value') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: stfld uint8 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::'<ByteProperty>k__BackingField'
IL_0007: ret
} // end of method MutableClass::set_ByteProperty
.method public hidebysig specialname
instance uint32 get_Item(string name) cil managed
{
@ -121,6 +157,11 @@ @@ -121,6 +157,11 @@
.get instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::get_Property()
.set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::set_Property(int32)
} // end of property MutableClass::Property
.property instance uint8 ByteProperty()
{
.get instance uint8 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::get_ByteProperty()
.set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::set_ByteProperty(uint8)
} // end of property MutableClass::ByteProperty
.property instance uint32 Item(string)
{
.get instance uint32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::get_Item(string)
@ -149,9 +190,15 @@ @@ -149,9 +190,15 @@
.field private int32[] array1
.field private valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/StructContainer field1
.field private valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MyEnum enumField
.field private class [mscorlib]System.Collections.Generic.Dictionary`2<uint16,uint16> ushortDict
.field private uint16 ushortField
.field private valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum shortEnumField
.field public static int32 StaticField
.field public static int16 StaticShortField
.field private static int32 '<StaticProperty>k__BackingField'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.field private static valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum '<StaticShortProperty>k__BackingField'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.method public hidebysig specialname static
int32 get_StaticProperty() cil managed
{
@ -173,6 +220,28 @@ @@ -173,6 +220,28 @@
IL_0006: ret
} // end of method CompoundAssignmentTest::set_StaticProperty
.method public hidebysig specialname static
valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum
get_StaticShortProperty() cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 6 (0x6)
.maxstack 8
IL_0000: ldsfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::'<StaticShortProperty>k__BackingField'
IL_0005: ret
} // end of method CompoundAssignmentTest::get_StaticShortProperty
.method public hidebysig specialname static
void set_StaticShortProperty(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum 'value') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: stsfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::'<StaticShortProperty>k__BackingField'
IL_0006: ret
} // end of method CompoundAssignmentTest::set_StaticShortProperty
.method private hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass
M() cil managed
{
@ -570,33 +639,53 @@ @@ -570,33 +639,53 @@
.method public hidebysig instance void
NestedField() cil managed
{
// Code size 38 (0x26)
// Code size 78 (0x4e)
.maxstack 3
.locals init (int32 V_0)
IL_0000: ldarg.0
IL_0001: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/StructContainer ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::field1
IL_0006: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/StructContainer::HasIndex
IL_000b: brfalse.s IL_0025
IL_000b: brfalse.s IL_004d
IL_000d: ldarg.0
IL_000e: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/StructContainer ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::field1
IL_0013: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/StructContainer::Field
IL_0018: dup
IL_0019: ldind.i4
IL_001a: stloc.0
IL_001b: ldloc.0
IL_001c: ldc.i4.1
IL_001d: add
IL_001a: ldc.i4.2
IL_001b: mul
IL_001c: dup
IL_001d: stloc.0
IL_001e: stind.i4
IL_001f: ldloc.0
IL_0020: call void [mscorlib]System.Console::WriteLine(int32)
IL_0025: ret
IL_0025: ldarg.0
IL_0026: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/StructContainer ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::field1
IL_002b: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/StructContainer::Field
IL_0030: dup
IL_0031: ldind.i4
IL_0032: ldc.i4.1
IL_0033: add
IL_0034: stind.i4
IL_0035: ldarg.0
IL_0036: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/StructContainer ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::field1
IL_003b: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/StructContainer::Field
IL_0040: dup
IL_0041: ldind.i4
IL_0042: stloc.0
IL_0043: ldloc.0
IL_0044: ldc.i4.1
IL_0045: add
IL_0046: stind.i4
IL_0047: ldloc.0
IL_0048: call void [mscorlib]System.Console::WriteLine(int32)
IL_004d: ret
} // end of method CompoundAssignmentTest::NestedField
.method public hidebysig instance void
Enum() cil managed
{
// Code size 30 (0x1e)
// Code size 58 (0x3a)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.0
@ -610,9 +699,55 @@ @@ -610,9 +699,55 @@
IL_0015: ldc.i4.s -5
IL_0017: and
IL_0018: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::enumField
IL_001d: ret
IL_001d: ldarg.0
IL_001e: ldarg.0
IL_001f: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::enumField
IL_0024: ldc.i4.2
IL_0025: add
IL_0026: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::enumField
IL_002b: ldarg.0
IL_002c: ldarg.0
IL_002d: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::enumField
IL_0032: ldc.i4.3
IL_0033: sub
IL_0034: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::enumField
IL_0039: ret
} // end of method CompoundAssignmentTest::Enum
.method public hidebysig instance void
ShortEnumTest() cil managed
{
// Code size 59 (0x3b)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.0
IL_0002: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::shortEnumField
IL_0007: ldc.i4.2
IL_0008: or
IL_0009: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::shortEnumField
IL_000e: ldarg.0
IL_000f: ldarg.0
IL_0010: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::shortEnumField
IL_0015: ldc.i4.4
IL_0016: and
IL_0017: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::shortEnumField
IL_001c: ldarg.0
IL_001d: ldarg.0
IL_001e: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::shortEnumField
IL_0023: ldc.i4.2
IL_0024: add
IL_0025: conv.i2
IL_0026: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::shortEnumField
IL_002b: ldarg.0
IL_002c: ldarg.0
IL_002d: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::shortEnumField
IL_0032: ldc.i4.3
IL_0033: sub
IL_0034: conv.i2
IL_0035: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::shortEnumField
IL_003a: ret
} // end of method CompoundAssignmentTest::ShortEnumTest
.method public hidebysig instance int32
PreIncrementInAddition(int32 i,
int32 j) cil managed
@ -688,6 +823,146 @@ @@ -688,6 +823,146 @@
IL_000c: ret
} // end of method CompoundAssignmentTest::IncrementArrayElement
.method public hidebysig instance void
DoubleArrayElement(int32[] 'array',
int32 pos) cil managed
{
// Code size 13 (0xd)
.maxstack 8
IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: ldelema [mscorlib]System.Int32
IL_0007: dup
IL_0008: ldind.i4
IL_0009: ldc.i4.2
IL_000a: mul
IL_000b: stind.i4
IL_000c: ret
} // end of method CompoundAssignmentTest::DoubleArrayElement
.method public hidebysig instance int32
DoubleArrayElementAndReturn(int32[] 'array',
int32 pos) cil managed
{
// Code size 16 (0x10)
.maxstack 3
.locals init (int32 V_0)
IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: ldelema [mscorlib]System.Int32
IL_0007: dup
IL_0008: ldind.i4
IL_0009: ldc.i4.2
IL_000a: mul
IL_000b: dup
IL_000c: stloc.0
IL_000d: stind.i4
IL_000e: ldloc.0
IL_000f: ret
} // end of method CompoundAssignmentTest::DoubleArrayElementAndReturn
.method public hidebysig instance int32
PreIncrementArrayElementShort(int16[] 'array',
int32 pos) cil managed
{
// Code size 17 (0x11)
.maxstack 3
.locals init (int16 V_0)
IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: ldelema [mscorlib]System.Int16
IL_0007: dup
IL_0008: ldind.i2
IL_0009: ldc.i4.1
IL_000a: sub
IL_000b: conv.i2
IL_000c: stloc.0
IL_000d: ldloc.0
IL_000e: stind.i2
IL_000f: ldloc.0
IL_0010: ret
} // end of method CompoundAssignmentTest::PreIncrementArrayElementShort
.method public hidebysig instance int32
PostIncrementArrayElementShort(int16[] 'array',
int32 pos) cil managed
{
// Code size 17 (0x11)
.maxstack 3
.locals init (int16 V_0)
IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: ldelema [mscorlib]System.Int16
IL_0007: dup
IL_0008: ldind.i2
IL_0009: stloc.0
IL_000a: ldloc.0
IL_000b: ldc.i4.1
IL_000c: add
IL_000d: conv.i2
IL_000e: stind.i2
IL_000f: ldloc.0
IL_0010: ret
} // end of method CompoundAssignmentTest::PostIncrementArrayElementShort
.method public hidebysig instance void
IncrementArrayElementShort(int16[] 'array',
int32 pos) cil managed
{
// Code size 14 (0xe)
.maxstack 8
IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: ldelema [mscorlib]System.Int16
IL_0007: dup
IL_0008: ldind.i2
IL_0009: ldc.i4.1
IL_000a: add
IL_000b: conv.i2
IL_000c: stind.i2
IL_000d: ret
} // end of method CompoundAssignmentTest::IncrementArrayElementShort
.method public hidebysig instance void
DoubleArrayElementShort(int16[] 'array',
int32 pos) cil managed
{
// Code size 14 (0xe)
.maxstack 8
IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: ldelema [mscorlib]System.Int16
IL_0007: dup
IL_0008: ldind.i2
IL_0009: ldc.i4.2
IL_000a: mul
IL_000b: conv.i2
IL_000c: stind.i2
IL_000d: ret
} // end of method CompoundAssignmentTest::DoubleArrayElementShort
.method public hidebysig instance int16
DoubleArrayElementShortAndReturn(int16[] 'array',
int32 pos) cil managed
{
// Code size 17 (0x11)
.maxstack 3
.locals init (int16 V_0)
IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: ldelema [mscorlib]System.Int16
IL_0007: dup
IL_0008: ldind.i2
IL_0009: ldc.i4.2
IL_000a: mul
IL_000b: conv.i2
IL_000c: dup
IL_000d: stloc.0
IL_000e: stind.i2
IL_000f: ldloc.0
IL_0010: ret
} // end of method CompoundAssignmentTest::DoubleArrayElementShortAndReturn
.method public hidebysig instance int32
PreIncrementInstanceField() cil managed
{
@ -707,6 +982,25 @@ @@ -707,6 +982,25 @@
IL_0016: ret
} // end of method CompoundAssignmentTest::PreIncrementInstanceField
.method public hidebysig instance int32
PostIncrementInstanceField() cil managed
{
// Code size 23 (0x17)
.maxstack 3
.locals init (int32 V_0)
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::Field
IL_000c: stloc.0
IL_000d: ldloc.0
IL_000e: ldc.i4.1
IL_000f: add
IL_0010: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::Field
IL_0015: ldloc.0
IL_0016: ret
} // end of method CompoundAssignmentTest::PostIncrementInstanceField
.method public hidebysig instance void
IncrementInstanceField() cil managed
{
@ -722,6 +1016,40 @@ @@ -722,6 +1016,40 @@
IL_0013: ret
} // end of method CompoundAssignmentTest::IncrementInstanceField
.method public hidebysig instance void
DoubleInstanceField() cil managed
{
// Code size 20 (0x14)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::Field
IL_000c: ldc.i4.2
IL_000d: mul
IL_000e: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::Field
IL_0013: ret
} // end of method CompoundAssignmentTest::DoubleInstanceField
.method public hidebysig instance int32
DoubleInstanceFieldAndReturn() cil managed
{
// Code size 23 (0x17)
.maxstack 3
.locals init (int32 V_0)
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::Field
IL_000c: ldc.i4.2
IL_000d: mul
IL_000e: dup
IL_000f: stloc.0
IL_0010: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::Field
IL_0015: ldloc.0
IL_0016: ret
} // end of method CompoundAssignmentTest::DoubleInstanceFieldAndReturn
.method public hidebysig instance int32
PreIncrementInstanceField2(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass m) cil managed
{
@ -740,6 +1068,24 @@ @@ -740,6 +1068,24 @@
IL_0011: ret
} // end of method CompoundAssignmentTest::PreIncrementInstanceField2
.method public hidebysig instance int32
PostIncrementInstanceField2(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass m) cil managed
{
// Code size 18 (0x12)
.maxstack 3
.locals init (int32 V_0)
IL_0000: ldarg.1
IL_0001: dup
IL_0002: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::Field
IL_0007: stloc.0
IL_0008: ldloc.0
IL_0009: ldc.i4.1
IL_000a: add
IL_000b: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::Field
IL_0010: ldloc.0
IL_0011: ret
} // end of method CompoundAssignmentTest::PostIncrementInstanceField2
.method public hidebysig instance void
IncrementInstanceField2(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass m) cil managed
{
@ -754,6 +1100,62 @@ @@ -754,6 +1100,62 @@
IL_000e: ret
} // end of method CompoundAssignmentTest::IncrementInstanceField2
.method public hidebysig instance int32
PreIncrementInstanceFieldShort() cil managed
{
// Code size 24 (0x18)
.maxstack 3
.locals init (int16 V_0)
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: ldfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::ShortField
IL_000c: ldc.i4.1
IL_000d: add
IL_000e: conv.i2
IL_000f: stloc.0
IL_0010: ldloc.0
IL_0011: stfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::ShortField
IL_0016: ldloc.0
IL_0017: ret
} // end of method CompoundAssignmentTest::PreIncrementInstanceFieldShort
.method public hidebysig instance int32
PostIncrementInstanceFieldShort() cil managed
{
// Code size 24 (0x18)
.maxstack 3
.locals init (int16 V_0)
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: ldfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::ShortField
IL_000c: stloc.0
IL_000d: ldloc.0
IL_000e: ldc.i4.1
IL_000f: add
IL_0010: conv.i2
IL_0011: stfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::ShortField
IL_0016: ldloc.0
IL_0017: ret
} // end of method CompoundAssignmentTest::PostIncrementInstanceFieldShort
.method public hidebysig instance void
IncrementInstanceFieldShort() cil managed
{
// Code size 21 (0x15)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: ldfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::ShortField
IL_000c: ldc.i4.1
IL_000d: add
IL_000e: conv.i2
IL_000f: stfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::ShortField
IL_0014: ret
} // end of method CompoundAssignmentTest::IncrementInstanceFieldShort
.method public hidebysig instance int32
PreIncrementInstanceProperty() cil managed
{
@ -773,6 +1175,25 @@ @@ -773,6 +1175,25 @@
IL_0016: ret
} // end of method CompoundAssignmentTest::PreIncrementInstanceProperty
.method public hidebysig instance int32
PostIncrementInstanceProperty() cil managed
{
// Code size 23 (0x17)
.maxstack 3
.locals init (int32 V_0)
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::get_Property()
IL_000c: stloc.0
IL_000d: ldloc.0
IL_000e: ldc.i4.1
IL_000f: add
IL_0010: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::set_Property(int32)
IL_0015: ldloc.0
IL_0016: ret
} // end of method CompoundAssignmentTest::PostIncrementInstanceProperty
.method public hidebysig instance void
IncrementInstanceProperty() cil managed
{
@ -791,6 +1212,135 @@ @@ -791,6 +1212,135 @@
IL_0015: ret
} // end of method CompoundAssignmentTest::IncrementInstanceProperty
.method public hidebysig instance void
DoubleInstanceProperty() cil managed
{
// Code size 20 (0x14)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::get_Property()
IL_000c: ldc.i4.2
IL_000d: mul
IL_000e: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::set_Property(int32)
IL_0013: ret
} // end of method CompoundAssignmentTest::DoubleInstanceProperty
.method public hidebysig instance int32
DoubleInstancePropertyAndReturn() cil managed
{
// Code size 23 (0x17)
.maxstack 3
.locals init (int32 V_0)
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::get_Property()
IL_000c: ldc.i4.2
IL_000d: mul
IL_000e: dup
IL_000f: stloc.0
IL_0010: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::set_Property(int32)
IL_0015: ldloc.0
IL_0016: ret
} // end of method CompoundAssignmentTest::DoubleInstancePropertyAndReturn
.method public hidebysig instance int32
PreIncrementInstancePropertyByte() cil managed
{
// Code size 24 (0x18)
.maxstack 3
.locals init (uint8 V_0)
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: callvirt instance uint8 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::get_ByteProperty()
IL_000c: ldc.i4.1
IL_000d: add
IL_000e: conv.u1
IL_000f: stloc.0
IL_0010: ldloc.0
IL_0011: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::set_ByteProperty(uint8)
IL_0016: ldloc.0
IL_0017: ret
} // end of method CompoundAssignmentTest::PreIncrementInstancePropertyByte
.method public hidebysig instance int32
PostIncrementInstancePropertyByte() cil managed
{
// Code size 24 (0x18)
.maxstack 3
.locals init (uint8 V_0)
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: callvirt instance uint8 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::get_ByteProperty()
IL_000c: stloc.0
IL_000d: ldloc.0
IL_000e: ldc.i4.1
IL_000f: add
IL_0010: conv.u1
IL_0011: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::set_ByteProperty(uint8)
IL_0016: ldloc.0
IL_0017: ret
} // end of method CompoundAssignmentTest::PostIncrementInstancePropertyByte
.method public hidebysig instance void
IncrementInstancePropertyByte() cil managed
{
// Code size 23 (0x17)
.maxstack 3
.locals init (uint8 V_0)
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: callvirt instance uint8 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::get_ByteProperty()
IL_000c: stloc.0
IL_000d: ldloc.0
IL_000e: ldc.i4.1
IL_000f: add
IL_0010: conv.u1
IL_0011: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::set_ByteProperty(uint8)
IL_0016: ret
} // end of method CompoundAssignmentTest::IncrementInstancePropertyByte
.method public hidebysig instance void
DoubleInstancePropertyByte() cil managed
{
// Code size 21 (0x15)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: callvirt instance uint8 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::get_ByteProperty()
IL_000c: ldc.i4.2
IL_000d: mul
IL_000e: conv.u1
IL_000f: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::set_ByteProperty(uint8)
IL_0014: ret
} // end of method CompoundAssignmentTest::DoubleInstancePropertyByte
.method public hidebysig instance int32
DoubleInstancePropertyByteAndReturn() cil managed
{
// Code size 24 (0x18)
.maxstack 3
.locals init (uint8 V_0)
IL_0000: ldarg.0
IL_0001: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::M()
IL_0006: dup
IL_0007: callvirt instance uint8 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::get_ByteProperty()
IL_000c: ldc.i4.2
IL_000d: mul
IL_000e: conv.u1
IL_000f: dup
IL_0010: stloc.0
IL_0011: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MutableClass::set_ByteProperty(uint8)
IL_0016: ldloc.0
IL_0017: ret
} // end of method CompoundAssignmentTest::DoubleInstancePropertyByteAndReturn
.method public hidebysig instance int32
PreIncrementStaticField() cil managed
{
@ -829,6 +1379,99 @@ @@ -829,6 +1379,99 @@
IL_000c: ret
} // end of method CompoundAssignmentTest::IncrementStaticField
.method public hidebysig instance void
DoubleStaticField() cil managed
{
// Code size 13 (0xd)
.maxstack 8
IL_0000: ldsfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticField
IL_0005: ldc.i4.2
IL_0006: mul
IL_0007: stsfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticField
IL_000c: ret
} // end of method CompoundAssignmentTest::DoubleStaticField
.method public hidebysig instance int32
DoubleStaticFieldAndReturn() cil managed
{
// Code size 14 (0xe)
.maxstack 8
IL_0000: ldsfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticField
IL_0005: ldc.i4.2
IL_0006: mul
IL_0007: dup
IL_0008: stsfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticField
IL_000d: ret
} // end of method CompoundAssignmentTest::DoubleStaticFieldAndReturn
.method public hidebysig instance int32
PreIncrementStaticFieldShort() cil managed
{
// Code size 15 (0xf)
.maxstack 8
IL_0000: ldsfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticShortField
IL_0005: ldc.i4.1
IL_0006: add
IL_0007: conv.i2
IL_0008: dup
IL_0009: stsfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticShortField
IL_000e: ret
} // end of method CompoundAssignmentTest::PreIncrementStaticFieldShort
.method public hidebysig instance int32
PostIncrementStaticFieldShort() cil managed
{
// Code size 15 (0xf)
.maxstack 8
IL_0000: ldsfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticShortField
IL_0005: dup
IL_0006: ldc.i4.1
IL_0007: add
IL_0008: conv.i2
IL_0009: stsfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticShortField
IL_000e: ret
} // end of method CompoundAssignmentTest::PostIncrementStaticFieldShort
.method public hidebysig instance void
IncrementStaticFieldShort() cil managed
{
// Code size 14 (0xe)
.maxstack 8
IL_0000: ldsfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticShortField
IL_0005: ldc.i4.1
IL_0006: add
IL_0007: conv.i2
IL_0008: stsfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticShortField
IL_000d: ret
} // end of method CompoundAssignmentTest::IncrementStaticFieldShort
.method public hidebysig instance void
DoubleStaticFieldShort() cil managed
{
// Code size 14 (0xe)
.maxstack 8
IL_0000: ldsfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticShortField
IL_0005: ldc.i4.2
IL_0006: mul
IL_0007: conv.i2
IL_0008: stsfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticShortField
IL_000d: ret
} // end of method CompoundAssignmentTest::DoubleStaticFieldShort
.method public hidebysig instance int16
DoubleStaticFieldAndReturnShort() cil managed
{
// Code size 15 (0xf)
.maxstack 8
IL_0000: ldsfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticShortField
IL_0005: ldc.i4.2
IL_0006: mul
IL_0007: conv.i2
IL_0008: dup
IL_0009: stsfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::StaticShortField
IL_000e: ret
} // end of method CompoundAssignmentTest::DoubleStaticFieldAndReturnShort
.method public hidebysig instance int32
PreIncrementStaticProperty() cil managed
{
@ -842,6 +1485,19 @@ @@ -842,6 +1485,19 @@
IL_000d: ret
} // end of method CompoundAssignmentTest::PreIncrementStaticProperty
.method public hidebysig instance int32
PostIncrementStaticProperty() cil managed
{
// Code size 14 (0xe)
.maxstack 8
IL_0000: call int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::get_StaticProperty()
IL_0005: dup
IL_0006: ldc.i4.1
IL_0007: add
IL_0008: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::set_StaticProperty(int32)
IL_000d: ret
} // end of method CompoundAssignmentTest::PostIncrementStaticProperty
.method public hidebysig instance void
IncrementStaticProperty() cil managed
{
@ -854,6 +1510,72 @@ @@ -854,6 +1510,72 @@
IL_000c: ret
} // end of method CompoundAssignmentTest::IncrementStaticProperty
.method public hidebysig instance void
DoubleStaticProperty() cil managed
{
// Code size 13 (0xd)
.maxstack 8
IL_0000: call int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::get_StaticProperty()
IL_0005: ldc.i4.2
IL_0006: mul
IL_0007: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::set_StaticProperty(int32)
IL_000c: ret
} // end of method CompoundAssignmentTest::DoubleStaticProperty
.method public hidebysig instance int32
DoubleStaticPropertyAndReturn() cil managed
{
// Code size 14 (0xe)
.maxstack 8
IL_0000: call int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::get_StaticProperty()
IL_0005: ldc.i4.2
IL_0006: mul
IL_0007: dup
IL_0008: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::set_StaticProperty(int32)
IL_000d: ret
} // end of method CompoundAssignmentTest::DoubleStaticPropertyAndReturn
.method public hidebysig instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum
PreIncrementStaticPropertyShort() cil managed
{
// Code size 15 (0xf)
.maxstack 8
IL_0000: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::get_StaticShortProperty()
IL_0005: ldc.i4.1
IL_0006: add
IL_0007: conv.i2
IL_0008: dup
IL_0009: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::set_StaticShortProperty(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum)
IL_000e: ret
} // end of method CompoundAssignmentTest::PreIncrementStaticPropertyShort
.method public hidebysig instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum
PostIncrementStaticPropertyShort() cil managed
{
// Code size 15 (0xf)
.maxstack 8
IL_0000: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::get_StaticShortProperty()
IL_0005: dup
IL_0006: ldc.i4.1
IL_0007: add
IL_0008: conv.i2
IL_0009: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::set_StaticShortProperty(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum)
IL_000e: ret
} // end of method CompoundAssignmentTest::PostIncrementStaticPropertyShort
.method public hidebysig instance void
IncrementStaticPropertyShort() cil managed
{
// Code size 14 (0xe)
.maxstack 8
IL_0000: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::get_StaticShortProperty()
IL_0005: ldc.i4.1
IL_0006: add
IL_0007: conv.i2
IL_0008: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::set_StaticShortProperty(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum)
IL_000d: ret
} // end of method CompoundAssignmentTest::IncrementStaticPropertyShort
.method private hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/Item
GetItem(object obj) cil managed
{
@ -874,14 +1596,62 @@ @@ -874,14 +1596,62 @@
IL_000c: ret
} // end of method CompoundAssignmentTest::Issue882
.method private hidebysig instance void
Issue954(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MyEnum& a,
valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MyEnum b) cil managed
{
// Code size 21 (0x15)
.maxstack 8
IL_0000: ldarg.1
IL_0001: ldarg.1
IL_0002: ldind.i4
IL_0003: ldarg.2
IL_0004: rem
IL_0005: stind.i4
IL_0006: ldarg.0
IL_0007: ldarg.0
IL_0008: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::enumField
IL_000d: ldarg.2
IL_000e: rem
IL_000f: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::enumField
IL_0014: ret
} // end of method CompoundAssignmentTest::Issue954
.method private hidebysig instance void
Issue588(uint16 val) cil managed
{
// Code size 31 (0x1f)
.maxstack 4
.locals init (uint16 V_0)
IL_0000: ldarg.0
IL_0001: ldfld class [mscorlib]System.Collections.Generic.Dictionary`2<uint16,uint16> ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::ushortDict
IL_0006: ldarg.0
IL_0007: ldarg.0
IL_0008: ldfld uint16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::ushortField
IL_000d: stloc.0
IL_000e: ldloc.0
IL_000f: ldc.i4.1
IL_0010: add
IL_0011: conv.u2
IL_0012: stfld uint16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::ushortField
IL_0017: ldloc.0
IL_0018: ldarg.1
IL_0019: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2<uint16,uint16>::Add(!0,
!1)
IL_001e: ret
} // end of method CompoundAssignmentTest::Issue588
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
// Code size 18 (0x12)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.Dictionary`2<uint16,uint16>::.ctor()
IL_0006: stfld class [mscorlib]System.Collections.Generic.Dictionary`2<uint16,uint16> ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::ushortDict
IL_000b: ldarg.0
IL_000c: call instance void [mscorlib]System.Object::.ctor()
IL_0011: ret
} // end of method CompoundAssignmentTest::.ctor
.property int32 StaticProperty()
@ -889,6 +1659,12 @@ @@ -889,6 +1659,12 @@
.get int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::get_StaticProperty()
.set void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::set_StaticProperty(int32)
} // end of property CompoundAssignmentTest::StaticProperty
.property valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum
StaticShortProperty()
{
.get valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::get_StaticShortProperty()
.set void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::set_StaticShortProperty(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest/ShortEnum)
} // end of property CompoundAssignmentTest::StaticShortProperty
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest

1014
ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.roslyn.il

File diff suppressed because it is too large Load Diff

68
ICSharpCode.Decompiler.Tests/TestCases/Pretty/InlineAssignmentTest.cs

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.IO;
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
@ -25,15 +26,25 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -25,15 +26,25 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
private int field1;
private static InlineAssignmentTest field2;
private int[] field3;
private short field4;
public int InstanceProperty {
get;
set;
}
public static int StaticProperty {
get;
set;
}
public void SimpleInlineWithLocals()
{
int value;
Console.WriteLine(value = 5);
int index;
Console.WriteLine(this.GetFormat(), index = this.GetIndex());
Console.WriteLine(index);
InlineAssignmentTest value;
Console.WriteLine(this.GetFormat(), value = new InlineAssignmentTest());
Console.WriteLine(value);
InlineAssignmentTest value2;
Console.WriteLine(value2 = new InlineAssignmentTest());
Console.WriteLine(value2);
}
public void SimpleInlineWithFields()
@ -41,24 +52,34 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -41,24 +52,34 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
Console.WriteLine(this.field1 = 5);
Console.WriteLine(InlineAssignmentTest.field2 = new InlineAssignmentTest());
}
public void SimpleInlineWithFields2()
{
Console.WriteLine(this.field1 = 5);
Console.WriteLine(this.field1);
Console.WriteLine(InlineAssignmentTest.field2 = new InlineAssignmentTest());
Console.WriteLine(InlineAssignmentTest.field2);
this.UseShort(this.field4 = 6);
this.UseShort(this.field4 = -10000);
this.UseShort(this.field4 = (short)this.field1);
this.UseShort(this.field4 = this.UseShort(0));
Console.WriteLine(this.field4);
}
// public void ReadLoop1(TextReader r)
// {
// string V_0;
// while ((V_0 = r.ReadLine()) != null)
// {
// Console.WriteLine(V_0);
// }
// }
public short UseShort(short s)
{
Console.WriteLine(s);
return s;
}
public void ReadLoop1(TextReader r)
{
string value;
while ((value = r.ReadLine()) != null) {
Console.WriteLine(value);
}
}
public void AccessArray(int[] a)
{
int num;
@ -91,6 +112,11 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -91,6 +112,11 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
throw new NotImplementedException();
}
public string GetFormat()
{
return "{0}";
}
public int GetValue(int value)
{
return value;
@ -100,5 +126,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -100,5 +126,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
return this.GetArray()[this.GetIndex()] = this.GetValue(this.GetIndex());
}
public int StaticPropertyTest()
{
return InlineAssignmentTest.StaticProperty = this.GetIndex();
}
public int InstancePropertyTest()
{
return this.InstanceProperty = this.GetIndex();
}
}
}

285
ICSharpCode.Decompiler.Tests/TestCases/Pretty/InlineAssignmentTest.il

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
// Microsoft (R) .NET Framework IL Disassembler. Version 4.0.30319.17929
// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0
// Copyright (c) Microsoft Corporation. All rights reserved.
@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly xh5er5kd
.assembly cljdpn4p
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
@ -20,15 +20,15 @@ @@ -20,15 +20,15 @@
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module xh5er5kd.dll
// MVID: {9DBFA28B-BEE8-4796-A203-E73267B1357D}
.module cljdpn4p.dll
// MVID: {4E91830C-4968-4AA2-B516-7FDA32452515}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x023E0000
// Image base: 0x006A0000
// =============== CLASS MEMBERS DECLARATION ===================
@ -39,31 +39,98 @@ @@ -39,31 +39,98 @@
.field private int32 field1
.field private static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest field2
.field private int32[] field3
.field private int16 field4
.field private int32 '<InstanceProperty>k__BackingField'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.field private static int32 '<StaticProperty>k__BackingField'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.method public hidebysig specialname instance int32
get_InstanceProperty() cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 11 (0xb)
.maxstack 1
.locals init (int32 V_0)
IL_0000: ldarg.0
IL_0001: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::'<InstanceProperty>k__BackingField'
IL_0006: stloc.0
IL_0007: br.s IL_0009
IL_0009: ldloc.0
IL_000a: ret
} // end of method InlineAssignmentTest::get_InstanceProperty
.method public hidebysig specialname instance void
set_InstanceProperty(int32 'value') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::'<InstanceProperty>k__BackingField'
IL_0007: ret
} // end of method InlineAssignmentTest::set_InstanceProperty
.method public hidebysig specialname static
int32 get_StaticProperty() cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 10 (0xa)
.maxstack 1
.locals init (int32 V_0)
IL_0000: ldsfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::'<StaticProperty>k__BackingField'
IL_0005: stloc.0
IL_0006: br.s IL_0008
IL_0008: ldloc.0
IL_0009: ret
} // end of method InlineAssignmentTest::get_StaticProperty
.method public hidebysig specialname static
void set_StaticProperty(int32 'value') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: stsfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::'<StaticProperty>k__BackingField'
IL_0006: ret
} // end of method InlineAssignmentTest::set_StaticProperty
.method public hidebysig instance void
SimpleInlineWithLocals() cil managed
{
// Code size 38 (0x26)
.maxstack 2
// Code size 60 (0x3c)
.maxstack 3
.locals init (int32 V_0,
class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest V_1)
IL_0000: nop
IL_0001: ldc.i4.5
IL_0002: dup
IL_0003: stloc.0
IL_0004: call void [mscorlib]System.Console::WriteLine(int32)
IL_0009: nop
IL_000a: ldloc.0
IL_000b: call void [mscorlib]System.Console::WriteLine(int32)
IL_0010: nop
IL_0011: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::.ctor()
IL_0016: dup
IL_0017: stloc.1
IL_0018: call void [mscorlib]System.Console::WriteLine(object)
IL_001d: nop
IL_001e: ldloc.1
IL_001f: call void [mscorlib]System.Console::WriteLine(object)
IL_0024: nop
IL_0025: ret
IL_0001: ldarg.0
IL_0002: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetFormat()
IL_0007: ldarg.0
IL_0008: call instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetIndex()
IL_000d: dup
IL_000e: stloc.0
IL_000f: box [mscorlib]System.Int32
IL_0014: call void [mscorlib]System.Console::WriteLine(string,
object)
IL_0019: nop
IL_001a: ldloc.0
IL_001b: call void [mscorlib]System.Console::WriteLine(int32)
IL_0020: nop
IL_0021: ldarg.0
IL_0022: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetFormat()
IL_0027: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::.ctor()
IL_002c: dup
IL_002d: stloc.1
IL_002e: call void [mscorlib]System.Console::WriteLine(string,
object)
IL_0033: nop
IL_0034: ldloc.1
IL_0035: call void [mscorlib]System.Console::WriteLine(object)
IL_003a: nop
IL_003b: ret
} // end of method InlineAssignmentTest::SimpleInlineWithLocals
.method public hidebysig instance void
@ -92,9 +159,10 @@ @@ -92,9 +159,10 @@
.method public hidebysig instance void
SimpleInlineWithFields2() cil managed
{
// Code size 58 (0x3a)
.maxstack 3
.locals init (int32 V_0)
// Code size 154 (0x9a)
.maxstack 4
.locals init (int32 V_0,
int16 V_1)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.5
@ -116,9 +184,101 @@ @@ -116,9 +184,101 @@
IL_002e: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field2
IL_0033: call void [mscorlib]System.Console::WriteLine(object)
IL_0038: nop
IL_0039: ret
IL_0039: ldarg.0
IL_003a: ldarg.0
IL_003b: ldc.i4.6
IL_003c: dup
IL_003d: stloc.1
IL_003e: stfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field4
IL_0043: ldloc.1
IL_0044: call instance int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::UseShort(int16)
IL_0049: pop
IL_004a: ldarg.0
IL_004b: ldarg.0
IL_004c: ldc.i4 0xffffd8f0
IL_0051: dup
IL_0052: stloc.1
IL_0053: stfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field4
IL_0058: ldloc.1
IL_0059: call instance int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::UseShort(int16)
IL_005e: pop
IL_005f: ldarg.0
IL_0060: ldarg.0
IL_0061: ldarg.0
IL_0062: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field1
IL_0067: conv.i2
IL_0068: dup
IL_0069: stloc.1
IL_006a: stfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field4
IL_006f: ldloc.1
IL_0070: call instance int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::UseShort(int16)
IL_0075: pop
IL_0076: ldarg.0
IL_0077: ldarg.0
IL_0078: ldarg.0
IL_0079: ldc.i4.0
IL_007a: call instance int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::UseShort(int16)
IL_007f: dup
IL_0080: stloc.1
IL_0081: stfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field4
IL_0086: ldloc.1
IL_0087: call instance int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::UseShort(int16)
IL_008c: pop
IL_008d: ldarg.0
IL_008e: ldfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field4
IL_0093: call void [mscorlib]System.Console::WriteLine(int32)
IL_0098: nop
IL_0099: ret
} // end of method InlineAssignmentTest::SimpleInlineWithFields2
.method public hidebysig instance int16
UseShort(int16 s) cil managed
{
// Code size 14 (0xe)
.maxstack 1
.locals init (int16 V_0)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: call void [mscorlib]System.Console::WriteLine(int32)
IL_0007: nop
IL_0008: ldarg.1
IL_0009: stloc.0
IL_000a: br.s IL_000c
IL_000c: ldloc.0
IL_000d: ret
} // end of method InlineAssignmentTest::UseShort
.method public hidebysig instance void
ReadLoop1(class [mscorlib]System.IO.TextReader r) cil managed
{
// Code size 31 (0x1f)
.maxstack 2
.locals init (string V_0,
bool V_1)
IL_0000: nop
IL_0001: br.s IL_000c
IL_0003: nop
IL_0004: ldloc.0
IL_0005: call void [mscorlib]System.Console::WriteLine(string)
IL_000a: nop
IL_000b: nop
IL_000c: ldarg.1
IL_000d: callvirt instance string [mscorlib]System.IO.TextReader::ReadLine()
IL_0012: dup
IL_0013: stloc.0
IL_0014: ldnull
IL_0015: ceq
IL_0017: ldc.i4.0
IL_0018: ceq
IL_001a: stloc.1
IL_001b: ldloc.1
IL_001c: brtrue.s IL_0003
IL_001e: ret
} // end of method InlineAssignmentTest::ReadLoop1
.method public hidebysig instance void
AccessArray(int32[] a) cil managed
{
@ -242,6 +402,21 @@ @@ -242,6 +402,21 @@
IL_0006: throw
} // end of method InlineAssignmentTest::GetArray
.method public hidebysig instance string
GetFormat() cil managed
{
// Code size 11 (0xb)
.maxstack 1
.locals init (string V_0)
IL_0000: nop
IL_0001: ldstr "{0}"
IL_0006: stloc.0
IL_0007: br.s IL_0009
IL_0009: ldloc.0
IL_000a: ret
} // end of method InlineAssignmentTest::GetFormat
.method public hidebysig instance int32
GetValue(int32 'value') cil managed
{
@ -284,6 +459,48 @@ @@ -284,6 +459,48 @@
IL_0021: ret
} // end of method InlineAssignmentTest::ArrayUsageWithMethods
.method public hidebysig instance int32
StaticPropertyTest() cil managed
{
// Code size 19 (0x13)
.maxstack 2
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: call instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetIndex()
IL_0007: dup
IL_0008: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::set_StaticProperty(int32)
IL_000d: nop
IL_000e: stloc.0
IL_000f: br.s IL_0011
IL_0011: ldloc.0
IL_0012: ret
} // end of method InlineAssignmentTest::StaticPropertyTest
.method public hidebysig instance int32
InstancePropertyTest() cil managed
{
// Code size 22 (0x16)
.maxstack 3
.locals init (int32 V_0,
int32 V_1)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.0
IL_0003: call instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetIndex()
IL_0008: dup
IL_0009: stloc.1
IL_000a: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::set_InstanceProperty(int32)
IL_000f: nop
IL_0010: ldloc.1
IL_0011: stloc.0
IL_0012: br.s IL_0014
IL_0014: ldloc.0
IL_0015: ret
} // end of method InlineAssignmentTest::InstancePropertyTest
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
@ -294,10 +511,20 @@ @@ -294,10 +511,20 @@
IL_0006: ret
} // end of method InlineAssignmentTest::.ctor
.property instance int32 InstanceProperty()
{
.get instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::get_InstanceProperty()
.set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::set_InstanceProperty(int32)
} // end of property InlineAssignmentTest::InstanceProperty
.property int32 StaticProperty()
{
.get int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::get_StaticProperty()
.set void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::set_StaticProperty(int32)
} // end of property InlineAssignmentTest::StaticProperty
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest
// =============================================================
// *********** DISASSEMBLY COMPLETE ***********************
// WARNING: Created Win32 resource file ../../Tests/TestCases/Pretty\InlineAssignmentTest.res
// WARNING: Created Win32 resource file ../../../TestCases/Pretty\InlineAssignmentTest.res

231
ICSharpCode.Decompiler.Tests/TestCases/Pretty/InlineAssignmentTest.opt.il

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
// Microsoft (R) .NET Framework IL Disassembler. Version 4.0.30319.17929
// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0
// Copyright (c) Microsoft Corporation. All rights reserved.
@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly b1jpssom
.assembly jfxjxuqt
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
@ -20,15 +20,15 @@ @@ -20,15 +20,15 @@
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module b1jpssom.dll
// MVID: {7C6502B0-8536-4BED-9395-765EB2F77653}
.module jfxjxuqt.dll
// MVID: {862986C8-F9C1-4FF3-8646-A3CA63D29744}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x02B00000
// Image base: 0x010B0000
// =============== CLASS MEMBERS DECLARATION ===================
@ -39,26 +39,83 @@ @@ -39,26 +39,83 @@
.field private int32 field1
.field private static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest field2
.field private int32[] field3
.field private int16 field4
.field private int32 '<InstanceProperty>k__BackingField'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.field private static int32 '<StaticProperty>k__BackingField'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.method public hidebysig specialname instance int32
get_InstanceProperty() cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::'<InstanceProperty>k__BackingField'
IL_0006: ret
} // end of method InlineAssignmentTest::get_InstanceProperty
.method public hidebysig specialname instance void
set_InstanceProperty(int32 'value') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::'<InstanceProperty>k__BackingField'
IL_0007: ret
} // end of method InlineAssignmentTest::set_InstanceProperty
.method public hidebysig specialname static
int32 get_StaticProperty() cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 6 (0x6)
.maxstack 8
IL_0000: ldsfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::'<StaticProperty>k__BackingField'
IL_0005: ret
} // end of method InlineAssignmentTest::get_StaticProperty
.method public hidebysig specialname static
void set_StaticProperty(int32 'value') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: stsfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::'<StaticProperty>k__BackingField'
IL_0006: ret
} // end of method InlineAssignmentTest::set_StaticProperty
.method public hidebysig instance void
SimpleInlineWithLocals() cil managed
{
// Code size 33 (0x21)
.maxstack 2
// Code size 55 (0x37)
.maxstack 3
.locals init (int32 V_0,
class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest V_1)
IL_0000: ldc.i4.5
IL_0001: dup
IL_0002: stloc.0
IL_0003: call void [mscorlib]System.Console::WriteLine(int32)
IL_0008: ldloc.0
IL_0009: call void [mscorlib]System.Console::WriteLine(int32)
IL_000e: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::.ctor()
IL_0013: dup
IL_0014: stloc.1
IL_0015: call void [mscorlib]System.Console::WriteLine(object)
IL_001a: ldloc.1
IL_001b: call void [mscorlib]System.Console::WriteLine(object)
IL_0020: ret
IL_0000: ldarg.0
IL_0001: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetFormat()
IL_0006: ldarg.0
IL_0007: call instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetIndex()
IL_000c: dup
IL_000d: stloc.0
IL_000e: box [mscorlib]System.Int32
IL_0013: call void [mscorlib]System.Console::WriteLine(string,
object)
IL_0018: ldloc.0
IL_0019: call void [mscorlib]System.Console::WriteLine(int32)
IL_001e: ldarg.0
IL_001f: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetFormat()
IL_0024: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::.ctor()
IL_0029: dup
IL_002a: stloc.1
IL_002b: call void [mscorlib]System.Console::WriteLine(string,
object)
IL_0030: ldloc.1
IL_0031: call void [mscorlib]System.Console::WriteLine(object)
IL_0036: ret
} // end of method InlineAssignmentTest::SimpleInlineWithLocals
.method public hidebysig instance void
@ -84,9 +141,13 @@ @@ -84,9 +141,13 @@
.method public hidebysig instance void
SimpleInlineWithFields2() cil managed
{
// Code size 53 (0x35)
.maxstack 3
.locals init (int32 V_0)
// Code size 150 (0x96)
.maxstack 4
.locals init (int32 V_0,
int16 V_1,
int16 V_2,
int16 V_3,
int16 V_4)
IL_0000: ldarg.0
IL_0001: ldc.i4.5
IL_0002: dup
@ -103,9 +164,82 @@ @@ -103,9 +164,82 @@
IL_0025: call void [mscorlib]System.Console::WriteLine(object)
IL_002a: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field2
IL_002f: call void [mscorlib]System.Console::WriteLine(object)
IL_0034: ret
IL_0034: ldarg.0
IL_0035: ldarg.0
IL_0036: ldc.i4.6
IL_0037: dup
IL_0038: stloc.1
IL_0039: stfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field4
IL_003e: ldloc.1
IL_003f: call instance int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::UseShort(int16)
IL_0044: pop
IL_0045: ldarg.0
IL_0046: ldarg.0
IL_0047: ldc.i4 0xffffd8f0
IL_004c: dup
IL_004d: stloc.2
IL_004e: stfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field4
IL_0053: ldloc.2
IL_0054: call instance int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::UseShort(int16)
IL_0059: pop
IL_005a: ldarg.0
IL_005b: ldarg.0
IL_005c: ldarg.0
IL_005d: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field1
IL_0062: conv.i2
IL_0063: dup
IL_0064: stloc.3
IL_0065: stfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field4
IL_006a: ldloc.3
IL_006b: call instance int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::UseShort(int16)
IL_0070: pop
IL_0071: ldarg.0
IL_0072: ldarg.0
IL_0073: ldarg.0
IL_0074: ldc.i4.0
IL_0075: call instance int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::UseShort(int16)
IL_007a: dup
IL_007b: stloc.s V_4
IL_007d: stfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field4
IL_0082: ldloc.s V_4
IL_0084: call instance int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::UseShort(int16)
IL_0089: pop
IL_008a: ldarg.0
IL_008b: ldfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field4
IL_0090: call void [mscorlib]System.Console::WriteLine(int32)
IL_0095: ret
} // end of method InlineAssignmentTest::SimpleInlineWithFields2
.method public hidebysig instance int16
UseShort(int16 s) cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.1
IL_0001: call void [mscorlib]System.Console::WriteLine(int32)
IL_0006: ldarg.1
IL_0007: ret
} // end of method InlineAssignmentTest::UseShort
.method public hidebysig instance void
ReadLoop1(class [mscorlib]System.IO.TextReader r) cil managed
{
// Code size 19 (0x13)
.maxstack 2
.locals init (string V_0)
IL_0000: br.s IL_0008
IL_0002: ldloc.0
IL_0003: call void [mscorlib]System.Console::WriteLine(string)
IL_0008: ldarg.1
IL_0009: callvirt instance string [mscorlib]System.IO.TextReader::ReadLine()
IL_000e: dup
IL_000f: stloc.0
IL_0010: brtrue.s IL_0002
IL_0012: ret
} // end of method InlineAssignmentTest::ReadLoop1
.method public hidebysig instance void
AccessArray(int32[] a) cil managed
{
@ -201,6 +335,15 @@ @@ -201,6 +335,15 @@
IL_0005: throw
} // end of method InlineAssignmentTest::GetArray
.method public hidebysig instance string
GetFormat() cil managed
{
// Code size 6 (0x6)
.maxstack 8
IL_0000: ldstr "{0}"
IL_0005: ret
} // end of method InlineAssignmentTest::GetFormat
.method public hidebysig instance int32
GetValue(int32 'value') cil managed
{
@ -231,6 +374,34 @@ @@ -231,6 +374,34 @@
IL_001c: ret
} // end of method InlineAssignmentTest::ArrayUsageWithMethods
.method public hidebysig instance int32
StaticPropertyTest() cil managed
{
// Code size 13 (0xd)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetIndex()
IL_0006: dup
IL_0007: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::set_StaticProperty(int32)
IL_000c: ret
} // end of method InlineAssignmentTest::StaticPropertyTest
.method public hidebysig instance int32
InstancePropertyTest() cil managed
{
// Code size 16 (0x10)
.maxstack 3
.locals init (int32 V_0)
IL_0000: ldarg.0
IL_0001: ldarg.0
IL_0002: call instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetIndex()
IL_0007: dup
IL_0008: stloc.0
IL_0009: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::set_InstanceProperty(int32)
IL_000e: ldloc.0
IL_000f: ret
} // end of method InlineAssignmentTest::InstancePropertyTest
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
@ -241,10 +412,20 @@ @@ -241,10 +412,20 @@
IL_0006: ret
} // end of method InlineAssignmentTest::.ctor
.property instance int32 InstanceProperty()
{
.get instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::get_InstanceProperty()
.set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::set_InstanceProperty(int32)
} // end of property InlineAssignmentTest::InstanceProperty
.property int32 StaticProperty()
{
.get int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::get_StaticProperty()
.set void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::set_StaticProperty(int32)
} // end of property InlineAssignmentTest::StaticProperty
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest
// =============================================================
// *********** DISASSEMBLY COMPLETE ***********************
// WARNING: Created Win32 resource file ../../Tests/TestCases/Pretty\InlineAssignmentTest.opt.res
// WARNING: Created Win32 resource file ../../../TestCases/Pretty\InlineAssignmentTest.opt.res

431
ICSharpCode.Decompiler.Tests/TestCases/Pretty/InlineAssignmentTest.opt.roslyn.il

@ -0,0 +1,431 @@ @@ -0,0 +1,431 @@
// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0
// Copyright (c) Microsoft Corporation. All rights reserved.
// Metadata version: v4.0.30319
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly InlineAssignmentTest
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
// --- The following custom attribute is added automatically, do not uncomment -------
// .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 )
.permissionset reqmin
= {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module InlineAssignmentTest.dll
// MVID: {2D549318-D869-4294-BA40-CB6EEA5D9CE2}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x02CB0000
// =============== CLASS MEMBERS DECLARATION ===================
.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest
extends [mscorlib]System.Object
{
.field private int32 field1
.field private static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest field2
.field private int32[] field3
.field private int16 field4
.field private int32 '<InstanceProperty>k__BackingField'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.field private static int32 '<StaticProperty>k__BackingField'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.method public hidebysig specialname instance int32
get_InstanceProperty() cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::'<InstanceProperty>k__BackingField'
IL_0006: ret
} // end of method InlineAssignmentTest::get_InstanceProperty
.method public hidebysig specialname instance void
set_InstanceProperty(int32 'value') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::'<InstanceProperty>k__BackingField'
IL_0007: ret
} // end of method InlineAssignmentTest::set_InstanceProperty
.method public hidebysig specialname static
int32 get_StaticProperty() cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 6 (0x6)
.maxstack 8
IL_0000: ldsfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::'<StaticProperty>k__BackingField'
IL_0005: ret
} // end of method InlineAssignmentTest::get_StaticProperty
.method public hidebysig specialname static
void set_StaticProperty(int32 'value') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: stsfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::'<StaticProperty>k__BackingField'
IL_0006: ret
} // end of method InlineAssignmentTest::set_StaticProperty
.method public hidebysig instance void
SimpleInlineWithLocals() cil managed
{
// Code size 55 (0x37)
.maxstack 3
.locals init (int32 V_0,
class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest V_1)
IL_0000: ldarg.0
IL_0001: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetFormat()
IL_0006: ldarg.0
IL_0007: call instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetIndex()
IL_000c: dup
IL_000d: stloc.0
IL_000e: box [mscorlib]System.Int32
IL_0013: call void [mscorlib]System.Console::WriteLine(string,
object)
IL_0018: ldloc.0
IL_0019: call void [mscorlib]System.Console::WriteLine(int32)
IL_001e: ldarg.0
IL_001f: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetFormat()
IL_0024: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::.ctor()
IL_0029: dup
IL_002a: stloc.1
IL_002b: call void [mscorlib]System.Console::WriteLine(string,
object)
IL_0030: ldloc.1
IL_0031: call void [mscorlib]System.Console::WriteLine(object)
IL_0036: ret
} // end of method InlineAssignmentTest::SimpleInlineWithLocals
.method public hidebysig instance void
SimpleInlineWithFields() cil managed
{
// Code size 32 (0x20)
.maxstack 3
.locals init (int32 V_0)
IL_0000: ldarg.0
IL_0001: ldc.i4.5
IL_0002: dup
IL_0003: stloc.0
IL_0004: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field1
IL_0009: ldloc.0
IL_000a: call void [mscorlib]System.Console::WriteLine(int32)
IL_000f: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::.ctor()
IL_0014: dup
IL_0015: stsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field2
IL_001a: call void [mscorlib]System.Console::WriteLine(object)
IL_001f: ret
} // end of method InlineAssignmentTest::SimpleInlineWithFields
.method public hidebysig instance void
SimpleInlineWithFields2() cil managed
{
// Code size 148 (0x94)
.maxstack 4
.locals init (int32 V_0,
int16 V_1)
IL_0000: ldarg.0
IL_0001: ldc.i4.5
IL_0002: dup
IL_0003: stloc.0
IL_0004: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field1
IL_0009: ldloc.0
IL_000a: call void [mscorlib]System.Console::WriteLine(int32)
IL_000f: ldarg.0
IL_0010: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field1
IL_0015: call void [mscorlib]System.Console::WriteLine(int32)
IL_001a: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::.ctor()
IL_001f: dup
IL_0020: stsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field2
IL_0025: call void [mscorlib]System.Console::WriteLine(object)
IL_002a: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field2
IL_002f: call void [mscorlib]System.Console::WriteLine(object)
IL_0034: ldarg.0
IL_0035: ldarg.0
IL_0036: ldc.i4.6
IL_0037: dup
IL_0038: stloc.1
IL_0039: stfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field4
IL_003e: ldloc.1
IL_003f: call instance int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::UseShort(int16)
IL_0044: pop
IL_0045: ldarg.0
IL_0046: ldarg.0
IL_0047: ldc.i4 0xffffd8f0
IL_004c: dup
IL_004d: stloc.1
IL_004e: stfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field4
IL_0053: ldloc.1
IL_0054: call instance int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::UseShort(int16)
IL_0059: pop
IL_005a: ldarg.0
IL_005b: ldarg.0
IL_005c: ldarg.0
IL_005d: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field1
IL_0062: conv.i2
IL_0063: dup
IL_0064: stloc.1
IL_0065: stfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field4
IL_006a: ldloc.1
IL_006b: call instance int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::UseShort(int16)
IL_0070: pop
IL_0071: ldarg.0
IL_0072: ldarg.0
IL_0073: ldarg.0
IL_0074: ldc.i4.0
IL_0075: call instance int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::UseShort(int16)
IL_007a: dup
IL_007b: stloc.1
IL_007c: stfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field4
IL_0081: ldloc.1
IL_0082: call instance int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::UseShort(int16)
IL_0087: pop
IL_0088: ldarg.0
IL_0089: ldfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field4
IL_008e: call void [mscorlib]System.Console::WriteLine(int32)
IL_0093: ret
} // end of method InlineAssignmentTest::SimpleInlineWithFields2
.method public hidebysig instance int16
UseShort(int16 s) cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.1
IL_0001: call void [mscorlib]System.Console::WriteLine(int32)
IL_0006: ldarg.1
IL_0007: ret
} // end of method InlineAssignmentTest::UseShort
.method public hidebysig instance void
ReadLoop1(class [mscorlib]System.IO.TextReader r) cil managed
{
// Code size 19 (0x13)
.maxstack 2
.locals init (string V_0)
IL_0000: br.s IL_0008
IL_0002: ldloc.0
IL_0003: call void [mscorlib]System.Console::WriteLine(string)
IL_0008: ldarg.1
IL_0009: callvirt instance string [mscorlib]System.IO.TextReader::ReadLine()
IL_000e: dup
IL_000f: stloc.0
IL_0010: brtrue.s IL_0002
IL_0012: ret
} // end of method InlineAssignmentTest::ReadLoop1
.method public hidebysig instance void
AccessArray(int32[] a) cil managed
{
// Code size 23 (0x17)
.maxstack 4
.locals init (int32 V_0,
int32 V_1)
IL_0000: ldarg.1
IL_0001: ldc.i4.0
IL_0002: ldelem.i4
IL_0003: dup
IL_0004: stloc.0
IL_0005: call void [mscorlib]System.Console::WriteLine(int32)
IL_000a: ldarg.1
IL_000b: ldloc.0
IL_000c: ldloc.0
IL_000d: dup
IL_000e: stloc.1
IL_000f: stelem.i4
IL_0010: ldloc.1
IL_0011: call void [mscorlib]System.Console::WriteLine(int32)
IL_0016: ret
} // end of method InlineAssignmentTest::AccessArray
.method public hidebysig instance int32
Return(int32& a) cil managed
{
// Code size 7 (0x7)
.maxstack 3
.locals init (int32 V_0)
IL_0000: ldarg.1
IL_0001: ldc.i4.3
IL_0002: dup
IL_0003: stloc.0
IL_0004: stind.i4
IL_0005: ldloc.0
IL_0006: ret
} // end of method InlineAssignmentTest::Return
.method public hidebysig instance int32
Array(int32[] a,
int32 i) cil managed
{
// Code size 8 (0x8)
.maxstack 4
.locals init (int32 V_0)
IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: ldarg.2
IL_0003: dup
IL_0004: stloc.0
IL_0005: stelem.i4
IL_0006: ldloc.0
IL_0007: ret
} // end of method InlineAssignmentTest::Array
.method public hidebysig instance int32
Array2(int32 i) cil managed
{
// Code size 13 (0xd)
.maxstack 4
.locals init (int32 V_0)
IL_0000: ldarg.0
IL_0001: ldfld int32[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field3
IL_0006: ldarg.1
IL_0007: ldc.i4.1
IL_0008: dup
IL_0009: stloc.0
IL_000a: stelem.i4
IL_000b: ldloc.0
IL_000c: ret
} // end of method InlineAssignmentTest::Array2
.method public hidebysig instance int32
GetIndex() cil managed
{
// Code size 14 (0xe)
.maxstack 8
IL_0000: newobj instance void [mscorlib]System.Random::.ctor()
IL_0005: ldc.i4.0
IL_0006: ldc.i4.s 100
IL_0008: callvirt instance int32 [mscorlib]System.Random::Next(int32,
int32)
IL_000d: ret
} // end of method InlineAssignmentTest::GetIndex
.method public hidebysig instance int32[]
GetArray() cil managed
{
// Code size 6 (0x6)
.maxstack 8
IL_0000: newobj instance void [mscorlib]System.NotImplementedException::.ctor()
IL_0005: throw
} // end of method InlineAssignmentTest::GetArray
.method public hidebysig instance string
GetFormat() cil managed
{
// Code size 6 (0x6)
.maxstack 8
IL_0000: ldstr "{0}"
IL_0005: ret
} // end of method InlineAssignmentTest::GetFormat
.method public hidebysig instance int32
GetValue(int32 'value') cil managed
{
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldarg.1
IL_0001: ret
} // end of method InlineAssignmentTest::GetValue
.method public hidebysig instance int32
ArrayUsageWithMethods() cil managed
{
// Code size 29 (0x1d)
.maxstack 4
.locals init (int32 V_0)
IL_0000: ldarg.0
IL_0001: call instance int32[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetArray()
IL_0006: ldarg.0
IL_0007: call instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetIndex()
IL_000c: ldarg.0
IL_000d: ldarg.0
IL_000e: call instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetIndex()
IL_0013: call instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetValue(int32)
IL_0018: dup
IL_0019: stloc.0
IL_001a: stelem.i4
IL_001b: ldloc.0
IL_001c: ret
} // end of method InlineAssignmentTest::ArrayUsageWithMethods
.method public hidebysig instance int32
StaticPropertyTest() cil managed
{
// Code size 13 (0xd)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetIndex()
IL_0006: dup
IL_0007: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::set_StaticProperty(int32)
IL_000c: ret
} // end of method InlineAssignmentTest::StaticPropertyTest
.method public hidebysig instance int32
InstancePropertyTest() cil managed
{
// Code size 16 (0x10)
.maxstack 3
.locals init (int32 V_0)
IL_0000: ldarg.0
IL_0001: ldarg.0
IL_0002: call instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetIndex()
IL_0007: dup
IL_0008: stloc.0
IL_0009: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::set_InstanceProperty(int32)
IL_000e: ldloc.0
IL_000f: ret
} // end of method InlineAssignmentTest::InstancePropertyTest
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method InlineAssignmentTest::.ctor
.property instance int32 InstanceProperty()
{
.get instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::get_InstanceProperty()
.set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::set_InstanceProperty(int32)
} // end of property InlineAssignmentTest::InstanceProperty
.property int32 StaticProperty()
{
.get int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::get_StaticProperty()
.set void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::set_StaticProperty(int32)
} // end of property InlineAssignmentTest::StaticProperty
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest
// =============================================================
// *********** DISASSEMBLY COMPLETE ***********************

524
ICSharpCode.Decompiler.Tests/TestCases/Pretty/InlineAssignmentTest.roslyn.il

@ -0,0 +1,524 @@ @@ -0,0 +1,524 @@
// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0
// Copyright (c) Microsoft Corporation. All rights reserved.
// Metadata version: v4.0.30319
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly InlineAssignmentTest
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
// --- The following custom attribute is added automatically, do not uncomment -------
// .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 )
.permissionset reqmin
= {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module InlineAssignmentTest.dll
// MVID: {370735A1-C3D5-4BD3-8F9B-CC3F81FB734E}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x00BE0000
// =============== CLASS MEMBERS DECLARATION ===================
.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest
extends [mscorlib]System.Object
{
.field private int32 field1
.field private static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest field2
.field private int32[] field3
.field private int16 field4
.field private int32 '<InstanceProperty>k__BackingField'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 )
.field private static int32 '<StaticProperty>k__BackingField'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 )
.method public hidebysig specialname instance int32
get_InstanceProperty() cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::'<InstanceProperty>k__BackingField'
IL_0006: ret
} // end of method InlineAssignmentTest::get_InstanceProperty
.method public hidebysig specialname instance void
set_InstanceProperty(int32 'value') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::'<InstanceProperty>k__BackingField'
IL_0007: ret
} // end of method InlineAssignmentTest::set_InstanceProperty
.method public hidebysig specialname static
int32 get_StaticProperty() cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 6 (0x6)
.maxstack 8
IL_0000: ldsfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::'<StaticProperty>k__BackingField'
IL_0005: ret
} // end of method InlineAssignmentTest::get_StaticProperty
.method public hidebysig specialname static
void set_StaticProperty(int32 'value') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: stsfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::'<StaticProperty>k__BackingField'
IL_0006: ret
} // end of method InlineAssignmentTest::set_StaticProperty
.method public hidebysig instance void
SimpleInlineWithLocals() cil managed
{
// Code size 60 (0x3c)
.maxstack 3
.locals init (int32 V_0,
class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest V_1)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetFormat()
IL_0007: ldarg.0
IL_0008: call instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetIndex()
IL_000d: dup
IL_000e: stloc.0
IL_000f: box [mscorlib]System.Int32
IL_0014: call void [mscorlib]System.Console::WriteLine(string,
object)
IL_0019: nop
IL_001a: ldloc.0
IL_001b: call void [mscorlib]System.Console::WriteLine(int32)
IL_0020: nop
IL_0021: ldarg.0
IL_0022: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetFormat()
IL_0027: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::.ctor()
IL_002c: dup
IL_002d: stloc.1
IL_002e: call void [mscorlib]System.Console::WriteLine(string,
object)
IL_0033: nop
IL_0034: ldloc.1
IL_0035: call void [mscorlib]System.Console::WriteLine(object)
IL_003a: nop
IL_003b: ret
} // end of method InlineAssignmentTest::SimpleInlineWithLocals
.method public hidebysig instance void
SimpleInlineWithFields() cil managed
{
// Code size 35 (0x23)
.maxstack 3
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.5
IL_0003: dup
IL_0004: stloc.0
IL_0005: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field1
IL_000a: ldloc.0
IL_000b: call void [mscorlib]System.Console::WriteLine(int32)
IL_0010: nop
IL_0011: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::.ctor()
IL_0016: dup
IL_0017: stsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field2
IL_001c: call void [mscorlib]System.Console::WriteLine(object)
IL_0021: nop
IL_0022: ret
} // end of method InlineAssignmentTest::SimpleInlineWithFields
.method public hidebysig instance void
SimpleInlineWithFields2() cil managed
{
// Code size 154 (0x9a)
.maxstack 4
.locals init (int32 V_0,
int16 V_1)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.5
IL_0003: dup
IL_0004: stloc.0
IL_0005: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field1
IL_000a: ldloc.0
IL_000b: call void [mscorlib]System.Console::WriteLine(int32)
IL_0010: nop
IL_0011: ldarg.0
IL_0012: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field1
IL_0017: call void [mscorlib]System.Console::WriteLine(int32)
IL_001c: nop
IL_001d: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::.ctor()
IL_0022: dup
IL_0023: stsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field2
IL_0028: call void [mscorlib]System.Console::WriteLine(object)
IL_002d: nop
IL_002e: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field2
IL_0033: call void [mscorlib]System.Console::WriteLine(object)
IL_0038: nop
IL_0039: ldarg.0
IL_003a: ldarg.0
IL_003b: ldc.i4.6
IL_003c: dup
IL_003d: stloc.1
IL_003e: stfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field4
IL_0043: ldloc.1
IL_0044: call instance int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::UseShort(int16)
IL_0049: pop
IL_004a: ldarg.0
IL_004b: ldarg.0
IL_004c: ldc.i4 0xffffd8f0
IL_0051: dup
IL_0052: stloc.1
IL_0053: stfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field4
IL_0058: ldloc.1
IL_0059: call instance int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::UseShort(int16)
IL_005e: pop
IL_005f: ldarg.0
IL_0060: ldarg.0
IL_0061: ldarg.0
IL_0062: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field1
IL_0067: conv.i2
IL_0068: dup
IL_0069: stloc.1
IL_006a: stfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field4
IL_006f: ldloc.1
IL_0070: call instance int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::UseShort(int16)
IL_0075: pop
IL_0076: ldarg.0
IL_0077: ldarg.0
IL_0078: ldarg.0
IL_0079: ldc.i4.0
IL_007a: call instance int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::UseShort(int16)
IL_007f: dup
IL_0080: stloc.1
IL_0081: stfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field4
IL_0086: ldloc.1
IL_0087: call instance int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::UseShort(int16)
IL_008c: pop
IL_008d: ldarg.0
IL_008e: ldfld int16 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field4
IL_0093: call void [mscorlib]System.Console::WriteLine(int32)
IL_0098: nop
IL_0099: ret
} // end of method InlineAssignmentTest::SimpleInlineWithFields2
.method public hidebysig instance int16
UseShort(int16 s) cil managed
{
// Code size 14 (0xe)
.maxstack 1
.locals init (int16 V_0)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: call void [mscorlib]System.Console::WriteLine(int32)
IL_0007: nop
IL_0008: ldarg.1
IL_0009: stloc.0
IL_000a: br.s IL_000c
IL_000c: ldloc.0
IL_000d: ret
} // end of method InlineAssignmentTest::UseShort
.method public hidebysig instance void
ReadLoop1(class [mscorlib]System.IO.TextReader r) cil managed
{
// Code size 28 (0x1c)
.maxstack 2
.locals init (string V_0,
bool V_1)
IL_0000: nop
IL_0001: br.s IL_000c
IL_0003: nop
IL_0004: ldloc.0
IL_0005: call void [mscorlib]System.Console::WriteLine(string)
IL_000a: nop
IL_000b: nop
IL_000c: ldarg.1
IL_000d: callvirt instance string [mscorlib]System.IO.TextReader::ReadLine()
IL_0012: dup
IL_0013: stloc.0
IL_0014: ldnull
IL_0015: cgt.un
IL_0017: stloc.1
IL_0018: ldloc.1
IL_0019: brtrue.s IL_0003
IL_001b: ret
} // end of method InlineAssignmentTest::ReadLoop1
.method public hidebysig instance void
AccessArray(int32[] a) cil managed
{
// Code size 26 (0x1a)
.maxstack 4
.locals init (int32 V_0,
int32 V_1)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: ldc.i4.0
IL_0003: ldelem.i4
IL_0004: dup
IL_0005: stloc.0
IL_0006: call void [mscorlib]System.Console::WriteLine(int32)
IL_000b: nop
IL_000c: ldarg.1
IL_000d: ldloc.0
IL_000e: ldloc.0
IL_000f: dup
IL_0010: stloc.1
IL_0011: stelem.i4
IL_0012: ldloc.1
IL_0013: call void [mscorlib]System.Console::WriteLine(int32)
IL_0018: nop
IL_0019: ret
} // end of method InlineAssignmentTest::AccessArray
.method public hidebysig instance int32
Return(int32& a) cil managed
{
// Code size 12 (0xc)
.maxstack 3
.locals init (int32 V_0,
int32 V_1)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: ldc.i4.3
IL_0003: dup
IL_0004: stloc.0
IL_0005: stind.i4
IL_0006: ldloc.0
IL_0007: stloc.1
IL_0008: br.s IL_000a
IL_000a: ldloc.1
IL_000b: ret
} // end of method InlineAssignmentTest::Return
.method public hidebysig instance int32
Array(int32[] a,
int32 i) cil managed
{
// Code size 13 (0xd)
.maxstack 4
.locals init (int32 V_0,
int32 V_1)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: ldarg.2
IL_0003: ldarg.2
IL_0004: dup
IL_0005: stloc.0
IL_0006: stelem.i4
IL_0007: ldloc.0
IL_0008: stloc.1
IL_0009: br.s IL_000b
IL_000b: ldloc.1
IL_000c: ret
} // end of method InlineAssignmentTest::Array
.method public hidebysig instance int32
Array2(int32 i) cil managed
{
// Code size 18 (0x12)
.maxstack 4
.locals init (int32 V_0,
int32 V_1)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld int32[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::field3
IL_0007: ldarg.1
IL_0008: ldc.i4.1
IL_0009: dup
IL_000a: stloc.0
IL_000b: stelem.i4
IL_000c: ldloc.0
IL_000d: stloc.1
IL_000e: br.s IL_0010
IL_0010: ldloc.1
IL_0011: ret
} // end of method InlineAssignmentTest::Array2
.method public hidebysig instance int32
GetIndex() cil managed
{
// Code size 19 (0x13)
.maxstack 3
.locals init (int32 V_0)
IL_0000: nop
IL_0001: newobj instance void [mscorlib]System.Random::.ctor()
IL_0006: ldc.i4.0
IL_0007: ldc.i4.s 100
IL_0009: callvirt instance int32 [mscorlib]System.Random::Next(int32,
int32)
IL_000e: stloc.0
IL_000f: br.s IL_0011
IL_0011: ldloc.0
IL_0012: ret
} // end of method InlineAssignmentTest::GetIndex
.method public hidebysig instance int32[]
GetArray() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: nop
IL_0001: newobj instance void [mscorlib]System.NotImplementedException::.ctor()
IL_0006: throw
} // end of method InlineAssignmentTest::GetArray
.method public hidebysig instance string
GetFormat() cil managed
{
// Code size 11 (0xb)
.maxstack 1
.locals init (string V_0)
IL_0000: nop
IL_0001: ldstr "{0}"
IL_0006: stloc.0
IL_0007: br.s IL_0009
IL_0009: ldloc.0
IL_000a: ret
} // end of method InlineAssignmentTest::GetFormat
.method public hidebysig instance int32
GetValue(int32 'value') cil managed
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
} // end of method InlineAssignmentTest::GetValue
.method public hidebysig instance int32
ArrayUsageWithMethods() cil managed
{
// Code size 34 (0x22)
.maxstack 4
.locals init (int32 V_0,
int32 V_1)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: call instance int32[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetArray()
IL_0007: ldarg.0
IL_0008: call instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetIndex()
IL_000d: ldarg.0
IL_000e: ldarg.0
IL_000f: call instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetIndex()
IL_0014: call instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetValue(int32)
IL_0019: dup
IL_001a: stloc.0
IL_001b: stelem.i4
IL_001c: ldloc.0
IL_001d: stloc.1
IL_001e: br.s IL_0020
IL_0020: ldloc.1
IL_0021: ret
} // end of method InlineAssignmentTest::ArrayUsageWithMethods
.method public hidebysig instance int32
StaticPropertyTest() cil managed
{
// Code size 19 (0x13)
.maxstack 2
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: call instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetIndex()
IL_0007: dup
IL_0008: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::set_StaticProperty(int32)
IL_000d: nop
IL_000e: stloc.0
IL_000f: br.s IL_0011
IL_0011: ldloc.0
IL_0012: ret
} // end of method InlineAssignmentTest::StaticPropertyTest
.method public hidebysig instance int32
InstancePropertyTest() cil managed
{
// Code size 22 (0x16)
.maxstack 3
.locals init (int32 V_0,
int32 V_1)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.0
IL_0003: call instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::GetIndex()
IL_0008: dup
IL_0009: stloc.0
IL_000a: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::set_InstanceProperty(int32)
IL_000f: nop
IL_0010: ldloc.0
IL_0011: stloc.1
IL_0012: br.s IL_0014
IL_0014: ldloc.1
IL_0015: ret
} // end of method InlineAssignmentTest::InstancePropertyTest
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: nop
IL_0007: ret
} // end of method InlineAssignmentTest::.ctor
.property instance int32 InstanceProperty()
{
.get instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::get_InstanceProperty()
.set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::set_InstanceProperty(int32)
} // end of property InlineAssignmentTest::InstanceProperty
.property int32 StaticProperty()
{
.get int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::get_StaticProperty()
.set void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest::set_StaticProperty(int32)
} // end of property InlineAssignmentTest::StaticProperty
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InlineAssignmentTest
// =============================================================
// *********** DISASSEMBLY COMPLETE ***********************

6
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.cs

@ -388,8 +388,14 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -388,8 +388,14 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public static void ForeachWithRefUsage(List<int> items)
{
foreach (int item in items) {
#if ROSLYN && OPT
// The variable names differs based on whether roslyn optimizes out the 'item' variable
int current = item;
Loops.Operation(ref current);
#else
int num = item;
Loops.Operation(ref num);
#endif
}
}

10
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -109,8 +109,11 @@ namespace ICSharpCode.Decompiler.CSharp @@ -109,8 +109,11 @@ namespace ICSharpCode.Decompiler.CSharp
// CachedDelegateInitialization must run after ConditionDetection and before/in LoopingBlockTransform
// and must run before NullCoalescingTransform
new CachedDelegateInitialization(),
new ILInlining(),
new TransformAssignment(), // must run before CopyPropagation
// Run the assignment transform both before and after copy propagation.
// Before is necessary because inline assignments of constants are otherwise
// copy-propated (turned into two separate assignments of the constant).
// After is necessary because the assigned value might involve null coalescing/etc.
new StatementTransform(new ILInlining(), new TransformAssignment()),
new CopyPropagation(),
new StatementTransform(
// per-block transforms that depend on each other, and thus need to
@ -121,11 +124,12 @@ namespace ICSharpCode.Decompiler.CSharp @@ -121,11 +124,12 @@ namespace ICSharpCode.Decompiler.CSharp
// Inlining must be first, because it doesn't trigger re-runs.
// Any other transform that opens up new inlining opportunities should call RequestRerun().
new ExpressionTransforms(),
new TransformAssignment(), // inline and compound assignments
new NullCoalescingTransform(),
new NullableLiftingStatementTransform(),
new TransformArrayInitializers(),
new TransformCollectionAndObjectInitializers()
)
),
}
},
new ProxyCallReplacer(),

76
ICSharpCode.Decompiler/CSharp/CallBuilder.cs

@ -47,28 +47,32 @@ namespace ICSharpCode.Decompiler.CSharp @@ -47,28 +47,32 @@ namespace ICSharpCode.Decompiler.CSharp
public TranslatedExpression Build(CallInstruction inst)
{
IMethod method = inst.Method;
if (inst is NewObj newobj && IL.Transforms.DelegateConstruction.IsDelegateConstruction(newobj, true)) {
return HandleDelegateConstruction(newobj);
}
return Build(inst.OpCode, inst.Method, inst.Arguments).WithILInstruction(inst);
}
public ExpressionWithResolveResult Build(OpCode callOpCode, IMethod method, IReadOnlyList<ILInstruction> callArguments)
{
// Used for Call, CallVirt and NewObj
TranslatedExpression target;
if (inst.OpCode == OpCode.NewObj) {
if (IL.Transforms.DelegateConstruction.IsDelegateConstruction((NewObj)inst, true)) {
return HandleDelegateConstruction(inst);
}
if (callOpCode == OpCode.NewObj) {
target = default(TranslatedExpression); // no target
} else {
target = expressionBuilder.TranslateTarget(method, inst.Arguments.FirstOrDefault(), inst.OpCode == OpCode.Call);
target = expressionBuilder.TranslateTarget(method, callArguments.FirstOrDefault(), callOpCode == OpCode.Call);
}
int firstParamIndex = (method.IsStatic || inst.OpCode == OpCode.NewObj) ? 0 : 1;
int firstParamIndex = (method.IsStatic || callOpCode == OpCode.NewObj) ? 0 : 1;
// Translate arguments to the expected parameter types
var arguments = new List<TranslatedExpression>(method.Parameters.Count);
Debug.Assert(inst.Arguments.Count == firstParamIndex + method.Parameters.Count);
Debug.Assert(callArguments.Count == firstParamIndex + method.Parameters.Count);
var expectedParameters = method.Parameters.ToList();
bool isExpandedForm = false;
for (int i = 0; i < method.Parameters.Count; i++) {
var parameter = expectedParameters[i];
var arg = expressionBuilder.Translate(inst.Arguments[firstParamIndex + i]);
var arg = expressionBuilder.Translate(callArguments[firstParamIndex + i]);
if (parameter.IsParams && i + 1 == method.Parameters.Count) {
// Parameter is marked params
// If the argument is an array creation, inline all elements into the call and add missing default values.
@ -90,7 +94,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -90,7 +94,7 @@ namespace ICSharpCode.Decompiler.CSharp
expandedArguments.Add(expressionBuilder.GetDefaultValueExpression(elementType).WithoutILInstruction());
}
}
if (IsUnambiguousCall(inst, target, method, Array.Empty<IType>(), expandedArguments) == OverloadResolutionErrors.None) {
if (IsUnambiguousCall(callOpCode, target, method, Array.Empty<IType>(), expandedArguments) == OverloadResolutionErrors.None) {
isExpandedForm = true;
expectedParameters = expandedParameters;
arguments = expandedArguments.SelectList(a => new TranslatedExpression(a.Expression.Detach()));
@ -124,7 +128,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -124,7 +128,7 @@ namespace ICSharpCode.Decompiler.CSharp
ResolveResult rr = new CSharpInvocationResolveResult(target.ResolveResult, method, argumentResolveResults, isExpandedForm: isExpandedForm);
if (inst.OpCode == OpCode.NewObj) {
if (callOpCode == OpCode.NewObj) {
if (settings.AnonymousTypes && method.DeclaringType.IsAnonymousType()) {
var argumentExpressions = arguments.SelectArray(arg => arg.Expression);
AnonymousTypeCreateExpression atce = new AnonymousTypeCreateExpression();
@ -140,11 +144,10 @@ namespace ICSharpCode.Decompiler.CSharp @@ -140,11 +144,10 @@ namespace ICSharpCode.Decompiler.CSharp
}
}
return atce
.WithILInstruction(inst)
.WithRR(rr);
} else {
if (IsUnambiguousCall(inst, target, method, Array.Empty<IType>(), arguments) != OverloadResolutionErrors.None) {
if (IsUnambiguousCall(callOpCode, target, method, Array.Empty<IType>(), arguments) != OverloadResolutionErrors.None) {
for (int i = 0; i < arguments.Count; i++) {
if (settings.AnonymousTypes && expectedParameters[i].Type.ContainsAnonymousType()) {
if (arguments[i].Expression is LambdaExpression lambda) {
@ -155,20 +158,20 @@ namespace ICSharpCode.Decompiler.CSharp @@ -155,20 +158,20 @@ namespace ICSharpCode.Decompiler.CSharp
}
}
}
return new ObjectCreateExpression(expressionBuilder.ConvertType(inst.Method.DeclaringType), arguments.SelectArray(arg => arg.Expression))
.WithILInstruction(inst).WithRR(rr);
return new ObjectCreateExpression(expressionBuilder.ConvertType(method.DeclaringType), arguments.SelectArray(arg => arg.Expression))
.WithRR(rr);
}
} else {
int allowedParamCount = (method.ReturnType.IsKnownType(KnownTypeCode.Void) ? 1 : 0);
if (method.IsAccessor && (method.AccessorOwner.SymbolKind == SymbolKind.Indexer || expectedParameters.Count == allowedParamCount)) {
return HandleAccessorCall(inst, target, method, arguments.ToList());
return HandleAccessorCall(callOpCode == OpCode.CallVirt, target, method, arguments.ToList());
} else if (method.Name == "Invoke" && method.DeclaringType.Kind == TypeKind.Delegate) {
return new InvocationExpression(target, arguments.Select(arg => arg.Expression)).WithILInstruction(inst).WithRR(rr);
return new InvocationExpression(target, arguments.Select(arg => arg.Expression)).WithRR(rr);
} else if (IsDelegateEqualityComparison(method, arguments)) {
return HandleDelegateEqualityComparison(method, arguments)
.WithILInstruction(inst).WithRR(rr);
.WithRR(rr);
} else if (method.IsOperator && method.Name == "op_Implicit" && arguments.Count == 1) {
return HandleImplicitConversion(inst, arguments[0]);
return HandleImplicitConversion(method, arguments[0]);
} else {
bool requireTypeArguments = false;
bool targetCasted = false;
@ -176,7 +179,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -176,7 +179,7 @@ namespace ICSharpCode.Decompiler.CSharp
IType[] typeArguments = Array.Empty<IType>();
OverloadResolutionErrors errors;
while ((errors = IsUnambiguousCall(inst, target, method, typeArguments, arguments)) != OverloadResolutionErrors.None) {
while ((errors = IsUnambiguousCall(callOpCode, target, method, typeArguments, arguments)) != OverloadResolutionErrors.None) {
switch (errors) {
case OverloadResolutionErrors.TypeInferenceFailed:
case OverloadResolutionErrors.WrongNumberOfTypeArguments:
@ -213,7 +216,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -213,7 +216,7 @@ namespace ICSharpCode.Decompiler.CSharp
Expression targetExpr = target.Expression;
string methodName = method.Name;
// HACK : convert this.Dispose() to ((IDisposable)this).Dispose(), if Dispose is an explicitly implemented interface method.
if (inst.Method.IsExplicitInterfaceImplementation && targetExpr is ThisReferenceExpression) {
if (method.IsExplicitInterfaceImplementation && targetExpr is ThisReferenceExpression) {
targetExpr = new CastExpression(expressionBuilder.ConvertType(method.ImplementedInterfaceMembers[0].DeclaringType), targetExpr);
methodName = method.ImplementedInterfaceMembers[0].Name;
}
@ -221,7 +224,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -221,7 +224,7 @@ namespace ICSharpCode.Decompiler.CSharp
if (requireTypeArguments && (!settings.AnonymousTypes || !method.TypeArguments.Any(a => a.ContainsAnonymousType())))
mre.TypeArguments.AddRange(method.TypeArguments.Select(expressionBuilder.ConvertType));
var argumentExpressions = arguments.Select(arg => arg.Expression);
return new InvocationExpression(mre, argumentExpressions).WithILInstruction(inst).WithRR(rr);
return new InvocationExpression(mre, argumentExpressions).WithRR(rr);
}
}
}
@ -271,28 +274,27 @@ namespace ICSharpCode.Decompiler.CSharp @@ -271,28 +274,27 @@ namespace ICSharpCode.Decompiler.CSharp
);
}
private TranslatedExpression HandleImplicitConversion(CallInstruction call, TranslatedExpression argument)
private ExpressionWithResolveResult HandleImplicitConversion(IMethod method, TranslatedExpression argument)
{
var conversions = CSharpConversions.Get(expressionBuilder.compilation);
IType targetType = call.Method.ReturnType;
IType targetType = method.ReturnType;
var conv = conversions.ImplicitConversion(argument.Type, targetType);
if (!(conv.IsUserDefined && conv.Method.Equals(call.Method))) {
if (!(conv.IsUserDefined && conv.Method.Equals(method))) {
// implicit conversion to targetType isn't directly possible, so first insert a cast to the argument type
argument = argument.ConvertTo(call.Method.Parameters[0].Type, expressionBuilder);
argument = argument.ConvertTo(method.Parameters[0].Type, expressionBuilder);
conv = conversions.ImplicitConversion(argument.Type, targetType);
}
return new CastExpression(expressionBuilder.ConvertType(targetType), argument.Expression)
.WithILInstruction(call)
.WithRR(new ConversionResolveResult(targetType, argument.ResolveResult, conv));
}
OverloadResolutionErrors IsUnambiguousCall(ILInstruction inst, TranslatedExpression target, IMethod method, IType[] typeArguments, IList<TranslatedExpression> arguments)
OverloadResolutionErrors IsUnambiguousCall(OpCode callOpCode, TranslatedExpression target, IMethod method, IType[] typeArguments, IList<TranslatedExpression> arguments)
{
var lookup = new MemberLookup(resolver.CurrentTypeDefinition, resolver.CurrentTypeDefinition.ParentAssembly);
var or = new OverloadResolution(resolver.Compilation, arguments.SelectArray(a => a.ResolveResult), typeArguments: typeArguments);
if (inst is NewObj newObj) {
foreach (IMethod ctor in newObj.Method.DeclaringType.GetConstructors()) {
if (lookup.IsAccessible(ctor, allowProtectedAccess: resolver.CurrentTypeDefinition == newObj.Method.DeclaringTypeDefinition)) {
if (callOpCode == OpCode.NewObj) {
foreach (IMethod ctor in method.DeclaringType.GetConstructors()) {
if (lookup.IsAccessible(ctor, allowProtectedAccess: resolver.CurrentTypeDefinition == method.DeclaringTypeDefinition)) {
or.AddCandidate(ctor);
}
}
@ -304,7 +306,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -304,7 +306,7 @@ namespace ICSharpCode.Decompiler.CSharp
}
if (or.BestCandidateErrors != OverloadResolutionErrors.None)
return or.BestCandidateErrors;
if (!IsAppropriateCallTarget(method, or.GetBestCandidateWithSubstitutedTypeArguments(), inst.OpCode == OpCode.CallVirt))
if (!IsAppropriateCallTarget(method, or.GetBestCandidateWithSubstitutedTypeArguments(), callOpCode == OpCode.CallVirt))
return OverloadResolutionErrors.AmbiguousMatch;
return OverloadResolutionErrors.None;
}
@ -327,12 +329,12 @@ namespace ICSharpCode.Decompiler.CSharp @@ -327,12 +329,12 @@ namespace ICSharpCode.Decompiler.CSharp
return true;
}
TranslatedExpression HandleAccessorCall(ILInstruction inst, TranslatedExpression target, IMethod method, IList<TranslatedExpression> arguments)
ExpressionWithResolveResult HandleAccessorCall(bool isVirtCall, TranslatedExpression target, IMethod method, IList<TranslatedExpression> arguments)
{
var lookup = new MemberLookup(resolver.CurrentTypeDefinition, resolver.CurrentTypeDefinition.ParentAssembly);
var result = lookup.Lookup(target.ResolveResult, method.AccessorOwner.Name, EmptyList<IType>.Instance, isInvocation: false);
if (result.IsError || (result is MemberResolveResult && !IsAppropriateCallTarget(method.AccessorOwner, ((MemberResolveResult)result).Member, inst.OpCode == OpCode.CallVirt)))
if (result.IsError || (result is MemberResolveResult && !IsAppropriateCallTarget(method.AccessorOwner, ((MemberResolveResult)result).Member, isVirtCall)))
target = target.ConvertTo(method.AccessorOwner.DeclaringType, expressionBuilder);
var rr = new MemberResolveResult(target.ResolveResult, method.AccessorOwner);
@ -356,12 +358,12 @@ namespace ICSharpCode.Decompiler.CSharp @@ -356,12 +358,12 @@ namespace ICSharpCode.Decompiler.CSharp
op = AssignmentOperatorType.Subtract;
}
}
return new AssignmentExpression(expr, op, value.Expression).WithILInstruction(inst).WithRR(new TypeResolveResult(method.AccessorOwner.ReturnType));
return new AssignmentExpression(expr, op, value.Expression).WithRR(new TypeResolveResult(method.AccessorOwner.ReturnType));
} else {
if (arguments.Count == 0)
return new MemberReferenceExpression(target.Expression, method.AccessorOwner.Name).WithILInstruction(inst).WithRR(rr);
return new MemberReferenceExpression(target.Expression, method.AccessorOwner.Name).WithRR(rr);
else
return new IndexerExpression(target.Expression, arguments.Select(a => a.Expression)).WithILInstruction(inst).WithRR(rr);
return new IndexerExpression(target.Expression, arguments.Select(a => a.Expression)).WithRR(rr);
}
}

19
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -1078,7 +1078,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1078,7 +1078,7 @@ namespace ICSharpCode.Decompiler.CSharp
if (NullableType.IsNullable(value.Type)) {
targetType = NullableType.Create(compilation, targetType);
}
value = value.ConvertTo(targetType, this, inst.CheckForOverflow);
value = value.ConvertTo(targetType, this, inst.CheckForOverflow, allowImplicitConversion: true);
break;
}
case AssignmentOperatorType.Multiply:
@ -1091,7 +1091,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1091,7 +1091,7 @@ namespace ICSharpCode.Decompiler.CSharp
if (NullableType.IsNullable(value.Type)) {
targetType = NullableType.Create(compilation, targetType);
}
value = value.ConvertTo(targetType, this, inst.CheckForOverflow);
value = value.ConvertTo(targetType, this, inst.CheckForOverflow, allowImplicitConversion: true);
break;
}
}
@ -1694,11 +1694,26 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1694,11 +1694,26 @@ namespace ICSharpCode.Decompiler.CSharp
return TranslateObjectAndCollectionInitializer(block);
case BlockType.PostfixOperator:
return TranslatePostfixOperator(block);
case BlockType.CallInlineAssign:
return TranslateSetterCallAssignment(block);
default:
return ErrorExpression("Unknown block type: " + block.Type);
}
}
private TranslatedExpression TranslateSetterCallAssignment(Block block)
{
if (!block.MatchInlineAssignBlock(out var call, out var value)) {
// should never happen unless the ILAst is invalid
return ErrorExpression("Error: MatchInlineAssignBlock() returned false");
}
var arguments = call.Arguments.ToList();
arguments[arguments.Count - 1] = value;
return new CallBuilder(this, typeSystem, settings)
.Build(call.OpCode, call.Method, arguments)
.WithILInstruction(call);
}
TranslatedExpression TranslateObjectAndCollectionInitializer(Block block)
{
var stloc = block.Instructions.FirstOrDefault() as StLoc;

55
ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

@ -463,26 +463,6 @@ namespace ICSharpCode.Decompiler.CSharp @@ -463,26 +463,6 @@ namespace ICSharpCode.Decompiler.CSharp
foreachVariable.Kind = VariableKind.ForeachLocal;
foreachVariable.Name = AssignVariableNames.GenerateForeachVariableName(currentFunction, collectionExpr.Annotation<ILInstruction>(), foreachVariable);
break;
case RequiredGetCurrentTransformation.UninlineAndUseExistingVariable:
// Unwrap stloc chain.
var nestedStores = new Stack<ILVariable>();
var currentInst = instToReplace; // instToReplace is the innermost value of the stloc chain.
while (currentInst.Parent is StLoc stloc) {
// Exclude nested stores to foreachVariable
// we'll insert one store at the beginning of the block.
if (stloc.Variable != foreachVariable && stloc.Parent is StLoc)
nestedStores.Push(stloc.Variable);
currentInst = stloc;
}
// Rebuild the nested store instructions:
ILInstruction reorderedStores = new LdLoc(foreachVariable);
while (nestedStores.Count > 0) {
reorderedStores = new StLoc(nestedStores.Pop(), reorderedStores);
}
currentInst.ReplaceWith(reorderedStores);
body.Instructions.Insert(0, new StLoc(foreachVariable, instToReplace));
// Adjust variable type, kind and name.
goto case RequiredGetCurrentTransformation.UseExistingVariable;
case RequiredGetCurrentTransformation.IntroduceNewVariable:
foreachVariable = currentFunction.RegisterVariable(
VariableKind.ForeachLocal, type,
@ -567,16 +547,6 @@ namespace ICSharpCode.Decompiler.CSharp @@ -567,16 +547,6 @@ namespace ICSharpCode.Decompiler.CSharp
/// </summary>
UseExistingVariable,
/// <summary>
/// Uninline (and possibly reorder) multiple stloc instructions and insert stloc foreachVar(call get_Current()) as first statement in the loop body.
/// <code>
/// ... (stloc foreachVar(stloc otherVar(call get_Current())) ...
/// =>
/// stloc foreachVar(call get_Current())
/// ... (stloc otherVar(ldloc foreachVar)) ...
/// </code>
/// </summary>
UninlineAndUseExistingVariable,
/// <summary>
/// No store was found, thus create a new variable and use it as foreach variable.
/// <code>
/// ... (call get_Current()) ...
@ -617,32 +587,15 @@ namespace ICSharpCode.Decompiler.CSharp @@ -617,32 +587,15 @@ namespace ICSharpCode.Decompiler.CSharp
// the result of call get_Current is casted.
while (inst.Parent is UnboxAny || inst.Parent is CastClass)
inst = inst.Parent;
// Gather all nested assignments to determine the foreach variable.
List<StLoc> nestedStores = new List<StLoc>();
while (inst.Parent is StLoc stloc) {
nestedStores.Add(stloc);
inst = stloc;
}
// No variable was found: we need a new one.
if (nestedStores.Count == 0)
return RequiredGetCurrentTransformation.IntroduceNewVariable;
// One variable was found.
if (nestedStores.Count == 1) {
if (inst.Parent is StLoc stloc) {
// Must be a plain assignment expression and variable must only be used in 'body' + only assigned once.
if (nestedStores[0].Parent == loopBody && VariableIsOnlyUsedInBlock(nestedStores[0], usingContainer)) {
foreachVariable = nestedStores[0].Variable;
if (stloc.Parent == loopBody && VariableIsOnlyUsedInBlock(stloc, usingContainer)) {
foreachVariable = stloc.Variable;
return RequiredGetCurrentTransformation.UseExistingVariable;
}
} else {
// Check if any of the variables is usable as foreach variable.
foreach (var store in nestedStores) {
if (VariableIsOnlyUsedInBlock(store, usingContainer)) {
foreachVariable = store.Variable;
return RequiredGetCurrentTransformation.UninlineAndUseExistingVariable;
}
}
}
// No suitable variable found.
// No suitable variable was found: we need a new one.
return RequiredGetCurrentTransformation.IntroduceNewVariable;
}

4
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -51,8 +51,8 @@ @@ -51,8 +51,8 @@
<ItemGroup>
<PackageReference Include="Humanizer.Core" Version="2.2.0" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="System.Collections.Immutable" Version="1.4.0" />
<PackageReference Include="System.ValueTuple" Version="4.4.0" />
<PackageReference Include="System.Collections.Immutable" Version="1.3.1" />
<PackageReference Include="System.ValueTuple" Version="4.3.0" />
</ItemGroup>
<ItemGroup>

35
ICSharpCode.Decompiler/IL/ILTypeExtensions.cs

@ -127,5 +127,40 @@ namespace ICSharpCode.Decompiler.IL @@ -127,5 +127,40 @@ namespace ICSharpCode.Decompiler.IL
{
return primitiveType.GetStackType().IsIntegerType();
}
/// <summary>
/// Infers the C# type for an IL instruction.
///
/// Returns SpecialType.UnknownType for unsupported instructions.
/// </summary>
public static IType InferType(this ILInstruction inst)
{
switch (inst) {
case NewObj newObj:
return newObj.Method.DeclaringType;
case Call call:
return call.Method.ReturnType;
case CallVirt callVirt:
return callVirt.Method.ReturnType;
case CallIndirect calli:
return calli.ReturnType;
case LdObj ldobj:
return ldobj.Type;
case StObj stobj:
return stobj.Type;
case LdLoc ldloc:
return ldloc.Variable.Type;
case StLoc stloc:
return stloc.Variable.Type;
case LdLoca ldloca:
return new TypeSystem.ByReferenceType(ldloca.Variable.Type);
case LdFlda ldflda:
return new TypeSystem.ByReferenceType(ldflda.Field.Type);
case LdsFlda ldsflda:
return new TypeSystem.ByReferenceType(ldsflda.Field.Type);
default:
return SpecialType.UnknownType;
}
}
}
}

17
ICSharpCode.Decompiler/IL/ILVariable.cs

@ -335,8 +335,23 @@ namespace ICSharpCode.Decompiler.IL @@ -335,8 +335,23 @@ namespace ICSharpCode.Decompiler.IL
{
output.WriteReference(this.Name, this, isLocal: true);
}
/// <summary>
/// Gets whether this variable occurs within the specified instruction.
/// </summary>
internal bool IsUsedWithin(ILInstruction inst)
{
if (inst is IInstructionWithVariableOperand iwvo && iwvo.Variable == this) {
return true;
}
foreach (var child in inst.Children) {
if (IsUsedWithin(child))
return true;
}
return false;
}
}
public interface IInstructionWithVariableOperand
{
ILVariable Variable { get; set; }

117
ICSharpCode.Decompiler/IL/Instructions.cs

@ -93,7 +93,8 @@ namespace ICSharpCode.Decompiler.IL @@ -93,7 +93,8 @@ namespace ICSharpCode.Decompiler.IL
LdLoc,
/// <summary>Loads the address of a local variable. (ldarga/ldloca)</summary>
LdLoca,
/// <summary>Stores a value into a local variable. (starg/stloc)</summary>
/// <summary>Stores a value into a local variable. (IL: starg/stloc)
/// Evaluates to the value that was stored (for byte/short variables: evaluates to the truncated value, sign/zero extended back to I4 based on variable.Type.GetSign())</summary>
StLoc,
/// <summary>Stores the value into an anonymous temporary variable, and returns the address of that variable.</summary>
AddressOf,
@ -137,7 +138,8 @@ namespace ICSharpCode.Decompiler.IL @@ -137,7 +138,8 @@ namespace ICSharpCode.Decompiler.IL
IsInst,
/// <summary>Indirect load (ref/pointer dereference).</summary>
LdObj,
/// <summary>Indirect store (store to ref/pointer).</summary>
/// <summary>Indirect store (store to ref/pointer).
/// Evaluates to the value that was stored (when using type byte/short: evaluates to the truncated value, sign/zero extended back to I4 based on type.GetSign())</summary>
StObj,
/// <summary>Boxes a value.</summary>
Box,
@ -941,9 +943,12 @@ namespace ICSharpCode.Decompiler.IL @@ -941,9 +943,12 @@ namespace ICSharpCode.Decompiler.IL
clone.Value = this.value.Clone();
return clone;
}
readonly IType type;
IType type;
/// <summary>Returns the type operand.</summary>
public IType Type { get { return type; } }
public IType Type {
get { return type; }
set { type = value; InvalidateFlags(); }
}
public override StackType ResultType { get { return type.GetStackType(); } }
public override void AcceptVisitor(ILVisitor visitor)
{
@ -2217,7 +2222,8 @@ namespace ICSharpCode.Decompiler.IL @@ -2217,7 +2222,8 @@ namespace ICSharpCode.Decompiler.IL
}
namespace ICSharpCode.Decompiler.IL
{
/// <summary>Stores a value into a local variable. (starg/stloc)</summary>
/// <summary>Stores a value into a local variable. (IL: starg/stloc)
/// Evaluates to the value that was stored (for byte/short variables: evaluates to the truncated value, sign/zero extended back to I4 based on variable.Type.GetSign())</summary>
public sealed partial class StLoc : ILInstruction, IStoreInstruction
{
public StLoc(ILVariable variable, ILInstruction value) : base(OpCode.StLoc)
@ -2811,9 +2817,12 @@ namespace ICSharpCode.Decompiler.IL @@ -2811,9 +2817,12 @@ namespace ICSharpCode.Decompiler.IL
{
this.type = type;
}
readonly IType type;
IType type;
/// <summary>Returns the type operand.</summary>
public IType Type { get { return type; } }
public IType Type {
get { return type; }
set { type = value; InvalidateFlags(); }
}
public override StackType ResultType { get { return StackType.O; } }
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
@ -3347,9 +3356,12 @@ namespace ICSharpCode.Decompiler.IL @@ -3347,9 +3356,12 @@ namespace ICSharpCode.Decompiler.IL
{
this.type = type;
}
readonly IType type;
IType type;
/// <summary>Returns the type operand.</summary>
public IType Type { get { return type; } }
public IType Type {
get { return type; }
set { type = value; InvalidateFlags(); }
}
public override StackType ResultType { get { return type.GetStackType(); } }
protected override InstructionFlags ComputeFlags()
{
@ -3398,9 +3410,12 @@ namespace ICSharpCode.Decompiler.IL @@ -3398,9 +3410,12 @@ namespace ICSharpCode.Decompiler.IL
{
this.type = type;
}
readonly IType type;
IType type;
/// <summary>Returns the type operand.</summary>
public IType Type { get { return type; } }
public IType Type {
get { return type; }
set { type = value; InvalidateFlags(); }
}
public override StackType ResultType { get { return StackType.O; } }
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
@ -3488,9 +3503,12 @@ namespace ICSharpCode.Decompiler.IL @@ -3488,9 +3503,12 @@ namespace ICSharpCode.Decompiler.IL
clone.Target = this.target.Clone();
return clone;
}
readonly IType type;
IType type;
/// <summary>Returns the type operand.</summary>
public IType Type { get { return type; } }
public IType Type {
get { return type; }
set { type = value; InvalidateFlags(); }
}
/// <summary>Gets/Sets whether the memory access is volatile.</summary>
public bool IsVolatile { get; set; }
/// <summary>Returns the alignment specified by the 'unaligned' prefix; or 0 if there was no 'unaligned' prefix.</summary>
@ -3540,7 +3558,8 @@ namespace ICSharpCode.Decompiler.IL @@ -3540,7 +3558,8 @@ namespace ICSharpCode.Decompiler.IL
}
namespace ICSharpCode.Decompiler.IL
{
/// <summary>Indirect store (store to ref/pointer).</summary>
/// <summary>Indirect store (store to ref/pointer).
/// Evaluates to the value that was stored (when using type byte/short: evaluates to the truncated value, sign/zero extended back to I4 based on type.GetSign())</summary>
public sealed partial class StObj : ILInstruction, ISupportsVolatilePrefix, ISupportsUnalignedPrefix
{
public StObj(ILInstruction target, ILInstruction value, IType type) : base(OpCode.StObj)
@ -3613,9 +3632,12 @@ namespace ICSharpCode.Decompiler.IL @@ -3613,9 +3632,12 @@ namespace ICSharpCode.Decompiler.IL
clone.Value = this.value.Clone();
return clone;
}
readonly IType type;
IType type;
/// <summary>Returns the type operand.</summary>
public IType Type { get { return type; } }
public IType Type {
get { return type; }
set { type = value; InvalidateFlags(); }
}
/// <summary>Gets/Sets whether the memory access is volatile.</summary>
public bool IsVolatile { get; set; }
/// <summary>Returns the alignment specified by the 'unaligned' prefix; or 0 if there was no 'unaligned' prefix.</summary>
@ -3674,9 +3696,12 @@ namespace ICSharpCode.Decompiler.IL @@ -3674,9 +3696,12 @@ namespace ICSharpCode.Decompiler.IL
{
this.type = type;
}
readonly IType type;
IType type;
/// <summary>Returns the type operand.</summary>
public IType Type { get { return type; } }
public IType Type {
get { return type; }
set { type = value; InvalidateFlags(); }
}
public override StackType ResultType { get { return StackType.O; } }
protected override InstructionFlags ComputeFlags()
{
@ -3725,9 +3750,12 @@ namespace ICSharpCode.Decompiler.IL @@ -3725,9 +3750,12 @@ namespace ICSharpCode.Decompiler.IL
{
this.type = type;
}
readonly IType type;
IType type;
/// <summary>Returns the type operand.</summary>
public IType Type { get { return type; } }
public IType Type {
get { return type; }
set { type = value; InvalidateFlags(); }
}
public override StackType ResultType { get { return StackType.Ref; } }
protected override InstructionFlags ComputeFlags()
{
@ -3776,9 +3804,12 @@ namespace ICSharpCode.Decompiler.IL @@ -3776,9 +3804,12 @@ namespace ICSharpCode.Decompiler.IL
{
this.type = type;
}
readonly IType type;
IType type;
/// <summary>Returns the type operand.</summary>
public IType Type { get { return type; } }
public IType Type {
get { return type; }
set { type = value; InvalidateFlags(); }
}
public override StackType ResultType { get { return type.GetStackType(); } }
protected override InstructionFlags ComputeFlags()
{
@ -3852,9 +3883,12 @@ namespace ICSharpCode.Decompiler.IL @@ -3852,9 +3883,12 @@ namespace ICSharpCode.Decompiler.IL
this.Indices = new InstructionCollection<ILInstruction>(this, 0);
this.Indices.AddRange(indices);
}
readonly IType type;
IType type;
/// <summary>Returns the type operand.</summary>
public IType Type { get { return type; } }
public IType Type {
get { return type; }
set { type = value; InvalidateFlags(); }
}
public static readonly SlotInfo IndicesSlot = new SlotInfo("Indices", canInlineInto: true);
public InstructionCollection<ILInstruction> Indices { get; private set; }
protected sealed override int GetChildCount()
@ -3942,9 +3976,12 @@ namespace ICSharpCode.Decompiler.IL @@ -3942,9 +3976,12 @@ namespace ICSharpCode.Decompiler.IL
{
this.type = type;
}
readonly IType type;
IType type;
/// <summary>Returns the type operand.</summary>
public IType Type { get { return type; } }
public IType Type {
get { return type; }
set { type = value; InvalidateFlags(); }
}
public override StackType ResultType { get { return type.GetStackType(); } }
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
@ -4055,9 +4092,12 @@ namespace ICSharpCode.Decompiler.IL @@ -4055,9 +4092,12 @@ namespace ICSharpCode.Decompiler.IL
{
this.type = type;
}
readonly IType type;
IType type;
/// <summary>Returns the type operand.</summary>
public IType Type { get { return type; } }
public IType Type {
get { return type; }
set { type = value; InvalidateFlags(); }
}
public override StackType ResultType { get { return StackType.I4; } }
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
@ -4177,9 +4217,12 @@ namespace ICSharpCode.Decompiler.IL @@ -4177,9 +4217,12 @@ namespace ICSharpCode.Decompiler.IL
this.Indices = new InstructionCollection<ILInstruction>(this, 1);
this.Indices.AddRange(indices);
}
readonly IType type;
IType type;
/// <summary>Returns the type operand.</summary>
public IType Type { get { return type; } }
public IType Type {
get { return type; }
set { type = value; InvalidateFlags(); }
}
public static readonly SlotInfo ArraySlot = new SlotInfo("Array", canInlineInto: true);
ILInstruction array;
public ILInstruction Array {
@ -4464,9 +4507,12 @@ namespace ICSharpCode.Decompiler.IL @@ -4464,9 +4507,12 @@ namespace ICSharpCode.Decompiler.IL
{
this.type = type;
}
readonly IType type;
IType type;
/// <summary>Returns the type operand.</summary>
public IType Type { get { return type; } }
public IType Type {
get { return type; }
set { type = value; InvalidateFlags(); }
}
public override StackType ResultType { get { return StackType.O; } }
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
@ -4534,9 +4580,12 @@ namespace ICSharpCode.Decompiler.IL @@ -4534,9 +4580,12 @@ namespace ICSharpCode.Decompiler.IL
{
this.type = type;
}
readonly IType type;
IType type;
/// <summary>Returns the type operand.</summary>
public IType Type { get { return type; } }
public IType Type {
get { return type; }
set { type = value; InvalidateFlags(); }
}
public override StackType ResultType { get { return StackType.Ref; } }
protected override InstructionFlags ComputeFlags()
{

15
ICSharpCode.Decompiler/IL/Instructions.tt

@ -150,7 +150,8 @@ @@ -150,7 +150,8 @@
CustomClassName("LdLoc"), NoArguments, HasVariableOperand("Load"), ResultType("variable.StackType")),
new OpCode("ldloca", "Loads the address of a local variable. (ldarga/ldloca)",
CustomClassName("LdLoca"), NoArguments, ResultType("Ref"), HasVariableOperand("Address")),
new OpCode("stloc", "Stores a value into a local variable. (starg/stloc)",
new OpCode("stloc", "Stores a value into a local variable. (IL: starg/stloc)" + Environment.NewLine
+ "Evaluates to the value that was stored (for byte/short variables: evaluates to the truncated value, sign/zero extended back to I4 based on variable.Type.GetSign())",
CustomClassName("StLoc"), HasVariableOperand("Store"), CustomArguments("value"),
ResultType("variable.StackType")),
new OpCode("addressof", "Stores the value into an anonymous temporary variable, and returns the address of that variable.",
@ -204,10 +205,11 @@ @@ -204,10 +205,11 @@
new OpCode("ldobj", "Indirect load (ref/pointer dereference).",
CustomClassName("LdObj"), CustomArguments("target"), HasTypeOperand, MemoryAccess, CustomWriteToButKeepOriginal,
SupportsVolatilePrefix, SupportsUnalignedPrefix, MayThrow, ResultType("type.GetStackType()")),
new OpCode("stobj", "Indirect store (store to ref/pointer).",
new OpCode("stobj", "Indirect store (store to ref/pointer)." + Environment.NewLine
+ "Evaluates to the value that was stored (when using type byte/short: evaluates to the truncated value, sign/zero extended back to I4 based on type.GetSign())",
CustomClassName("StObj"), CustomArguments("target", "value"), HasTypeOperand, MemoryAccess, CustomWriteToButKeepOriginal,
SupportsVolatilePrefix, SupportsUnalignedPrefix, MayThrow, ResultType("type.GetStackType()")),
new OpCode("box", "Boxes a value.",
Unary, HasTypeOperand, MemoryAccess, MayThrow, ResultType("O")),
new OpCode("unbox", "Compute address inside box.",
@ -937,12 +939,15 @@ protected override void Disconnected() @@ -937,12 +939,15 @@ protected override void Disconnected()
static Action<OpCode> HasTypeOperand = opCode => {
opCode.ConstructorParameters.Add("IType type");
opCode.Members.Add("readonly IType type;");
opCode.Members.Add("IType type;");
opCode.ConstructorBody.Add("this.type = type;");
opCode.MatchParameters.Add(new MatchParamInfo { TypeName = "IType", Name = "type", FieldName = "Type" });
opCode.PerformMatchConditions.Add("type.Equals(o.type)");
opCode.Members.Add("/// <summary>Returns the type operand.</summary>" + Environment.NewLine
+ "public IType Type { get { return type; } }");
+ "public IType Type {" + Environment.NewLine
+ "\tget { return type; }" + Environment.NewLine
+ "\tset { type = value; InvalidateFlags(); }" + Environment.NewLine
+ "}");
opCode.GenerateWriteTo = true;
opCode.WriteOperand.Add("output.Write(' ');");
opCode.WriteOperand.Add("type.WriteTo(output);");

62
ICSharpCode.Decompiler/IL/Instructions/Block.cs

@ -108,8 +108,13 @@ namespace ICSharpCode.Decompiler.IL @@ -108,8 +108,13 @@ namespace ICSharpCode.Decompiler.IL
// only the last instruction may have an unreachable endpoint
Debug.Assert(!Instructions[i].HasFlag(InstructionFlags.EndPointUnreachable));
}
if (this.Type == BlockType.ControlFlow) {
Debug.Assert(finalInstruction.OpCode == OpCode.Nop);
switch (this.Type) {
case BlockType.ControlFlow:
Debug.Assert(finalInstruction.OpCode == OpCode.Nop);
break;
case BlockType.CallInlineAssign:
Debug.Assert(MatchInlineAssignBlock(out _, out _));
break;
}
}
@ -251,13 +256,62 @@ namespace ICSharpCode.Decompiler.IL @@ -251,13 +256,62 @@ namespace ICSharpCode.Decompiler.IL
}
return inst;
}
public bool MatchInlineAssignBlock(out CallInstruction call, out ILInstruction value)
{
call = null;
value = null;
if (this.Type != BlockType.CallInlineAssign)
return false;
if (this.Instructions.Count != 1)
return false;
call = this.Instructions[0] as CallInstruction;
if (call == null || call.Arguments.Count == 0)
return false;
if (!call.Arguments.Last().MatchStLoc(out var tmp, out value))
return false;
if (!(tmp.IsSingleDefinition && tmp.LoadCount == 1))
return false;
return this.FinalInstruction.MatchLdLoc(tmp);
}
}
public enum BlockType {
public enum BlockType
{
/// <summary>
/// Block is used for control flow.
/// All blocks in block containers must have this type.
/// Control flow blocks cannot evaluate to a value (FinalInstruction must be Nop).
/// </summary>
ControlFlow,
/// <summary>
/// Block is used for array initializers, e.g. `new int[] { expr1, expr2 }`.
/// </summary>
ArrayInitializer,
CollectionInitializer,
ObjectInitializer,
PostfixOperator
/// <summary>
/// Block is used for postfix operator on local variable.
/// </summary>
/// <remarks>
/// Postfix operators on non-locals use CompoundAssignmentInstruction with CompoundAssignmentType.EvaluatesToOldValue.
/// </remarks>
PostfixOperator,
/// <summary>
/// Block is used for using the result of a property setter inline.
/// Example: <code>Use(this.Property = value);</code>
/// This is only for inline assignments to property or indexers; other inline assignments work
/// by using the result value of the stloc/stobj instructions.
///
/// Constructed by TransformAssignment.
/// Can be deconstructed using Block.MatchInlineAssignBlock().
/// </summary>
/// <example>
/// Block {
/// call setter(..., stloc s(...))
/// final: ldloc s
/// }
/// </example>
CallInlineAssign
}
}

14
ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs

@ -85,6 +85,18 @@ namespace ICSharpCode.Decompiler.IL @@ -85,6 +85,18 @@ namespace ICSharpCode.Decompiler.IL
return false;
type = NullableType.GetUnderlyingType(type);
}
if (type.Kind == TypeKind.Enum) {
switch (binary.Operator) {
case BinaryNumericOperator.Add:
case BinaryNumericOperator.Sub:
case BinaryNumericOperator.BitAnd:
case BinaryNumericOperator.BitOr:
case BinaryNumericOperator.BitXor:
break; // OK
default:
return false; // operator not supported on enum types
}
}
if (binary.Sign != Sign.None) {
if (type.GetSign() != binary.Sign)
return false;
@ -95,7 +107,7 @@ namespace ICSharpCode.Decompiler.IL @@ -95,7 +107,7 @@ namespace ICSharpCode.Decompiler.IL
internal static bool IsValidCompoundAssignmentTarget(ILInstruction inst)
{
switch (inst.OpCode) {
case OpCode.LdLoc:
// case OpCode.LdLoc: -- not valid -- does not mark the variable as written to
case OpCode.LdObj:
return true;
case OpCode.Call:

4
ICSharpCode.Decompiler/IL/Instructions/InstructionCollection.cs

@ -140,6 +140,10 @@ namespace ICSharpCode.Decompiler.IL @@ -140,6 +140,10 @@ namespace ICSharpCode.Decompiler.IL
/// </remarks>
public int IndexOf(T item)
{
if (item == null) {
// InstructionCollection can't contain nulls
return -1;
}
// If this collection is the item's primary position, we can use ChildIndex:
int index = item.ChildIndex - firstChildIndex;
if (index >= 0 && index < list.Count && list[index] == item)

8
ICSharpCode.Decompiler/IL/Instructions/MemoryInstructions.cs

@ -43,7 +43,7 @@ namespace ICSharpCode.Decompiler.IL @@ -43,7 +43,7 @@ namespace ICSharpCode.Decompiler.IL
if (this.MatchLdFld(out var target, out var field)) {
ILRange.WriteTo(output, options);
output.Write("ldfld ");
Disassembler.DisassemblerHelpers.WriteOperand(output, field);
field.WriteTo(output);
output.Write('(');
target.WriteTo(output, options);
output.Write(')');
@ -51,7 +51,7 @@ namespace ICSharpCode.Decompiler.IL @@ -51,7 +51,7 @@ namespace ICSharpCode.Decompiler.IL
} else if (this.MatchLdsFld(out field)) {
ILRange.WriteTo(output, options);
output.Write("ldsfld ");
Disassembler.DisassemblerHelpers.WriteOperand(output, field);
field.WriteTo(output);
return;
}
}
@ -67,7 +67,7 @@ namespace ICSharpCode.Decompiler.IL @@ -67,7 +67,7 @@ namespace ICSharpCode.Decompiler.IL
if (this.MatchStFld(out var target, out var field, out var value)) {
ILRange.WriteTo(output, options);
output.Write("stfld ");
Disassembler.DisassemblerHelpers.WriteOperand(output, field);
field.WriteTo(output);
output.Write('(');
target.WriteTo(output, options);
output.Write(", ");
@ -77,7 +77,7 @@ namespace ICSharpCode.Decompiler.IL @@ -77,7 +77,7 @@ namespace ICSharpCode.Decompiler.IL
} else if (this.MatchStsFld(out field, out value)) {
ILRange.WriteTo(output, options);
output.Write("stsfld ");
Disassembler.DisassemblerHelpers.WriteOperand(output, field);
field.WriteTo(output);
output.Write('(');
value.WriteTo(output, options);
output.Write(')');

17
ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs

@ -359,18 +359,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -359,18 +359,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (!variableType.IsKnownType(KnownTypeCode.Object))
return variableType;
switch (inst) {
case NewObj newObj:
return newObj.Method.DeclaringType;
case Call call:
return call.Method.ReturnType;
case CallVirt callVirt:
return callVirt.Method.ReturnType;
case CallIndirect calli:
return calli.ReturnType;
default:
return context.TypeSystem.Compilation.FindType(inst.ResultType.ToKnownTypeCode());
}
IType inferredType = inst.InferType();
if (inferredType.Kind != TypeKind.Unknown)
return inferredType;
else
return variableType;
}
internal static string GenerateForeachVariableName(ILFunction function, ILInstruction valueContext, ILVariable existingVariable = null)

17
ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs

@ -16,9 +16,11 @@ @@ -16,9 +16,11 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Diagnostics;
using System.Linq;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
namespace ICSharpCode.Decompiler.IL.Transforms
{
@ -277,20 +279,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -277,20 +279,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
context.RequestRerun();
return;
}
if (inst.Value is BinaryNumericInstruction binary
&& binary.Left.MatchLdObj(out ILInstruction target, out IType t)
&& inst.Target.Match(target).Success
&& SemanticHelper.IsPure(target.Flags)
&& CompoundAssignmentInstruction.IsBinaryCompatibleWithType(binary, t))
{
context.Step("compound assignment", inst);
// stobj(target, binary.op(ldobj(target), ...))
// => compound.op(target, ...)
inst.ReplaceWith(new CompoundAssignmentInstruction(
binary, binary.Left, binary.Right,
t, CompoundAssignmentType.EvaluatesToNewValue));
}
TransformAssignment.HandleStObjCompoundAssign(inst, context);
}
protected internal override void VisitIfInstruction(IfInstruction inst)

571
ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs

@ -17,38 +17,36 @@ @@ -17,38 +17,36 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Diagnostics;
using System.Linq;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.IL.Transforms
{
/// <summary>
/// Constructs compound assignments and inline assignments.
/// </summary>
public class TransformAssignment : IBlockTransform
public class TransformAssignment : IStatementTransform
{
BlockTransformContext context;
StatementTransformContext context;
void IBlockTransform.Run(Block block, BlockTransformContext context)
void IStatementTransform.Run(Block block, int pos, StatementTransformContext context)
{
this.context = context;
for (int i = block.Instructions.Count - 1; i >= 0; i--) {
if (TransformPostIncDecOperatorOnAddress(block, i) || TransformPostIncDecOnStaticField(block, i) || TransformCSharp4PostIncDecOperatorOnAddress(block, i)) {
block.Instructions.RemoveAt(i);
continue;
}
if (TransformPostIncDecOperator(block, i)) {
block.Instructions.RemoveAt(i);
continue;
}
if (TransformInlineAssignmentStObj(block, i))
continue;
if (TransformInlineCompoundAssignmentCall(block, i))
continue;
if (TransformRoslynCompoundAssignmentCall(block, i))
continue;
if (TransformRoslynPostIncDecOperatorOnAddress(block, i))
continue;
if (TransformInlineAssignmentStObjOrCall(block, pos) || TransformInlineAssignmentLocal(block, pos)) {
// both inline assignments create a top-level stloc which might affect inlining
context.RequestRerun();
return;
}
if (TransformPostIncDecOperatorWithInlineStore(block, pos)
|| TransformPostIncDecOperator(block, pos)
|| TransformPostIncDecOperatorLocal(block, pos))
{
// again, new top-level stloc might need inlining:
context.RequestRerun();
return;
}
}
@ -56,127 +54,138 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -56,127 +54,138 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// stloc s(value)
/// stloc l(ldloc s)
/// stobj(..., ldloc s)
/// where ... is pure and does not use s or l,
/// and where neither the 'stloc s' nor the 'stobj' truncates
/// -->
/// stloc l(stobj (..., value))
/// </code>
/// e.g. used for inline assignment to instance field
///
/// -or-
///
/// <code>
/// stloc s(value)
/// stobj (..., ldloc s)
/// where ... is pure and does not use s, and where the 'stobj' does not truncate
/// -->
/// stloc s(stobj (..., value))
/// </code>
bool TransformInlineAssignmentStObj(Block block, int i)
/// e.g. used for inline assignment to static field
///
/// -or-
///
/// <code>
/// stloc s(value)
/// call set_Property(..., ldloc s)
/// where the '...' arguments are pure and not using 's'
/// -->
/// stloc s(Block InlineAssign { call set_Property(..., stloc i(value)); final: ldloc i })
/// new temporary 'i' has type of the property; transform only valid if 'stloc i' doesn't truncate
/// </code>
bool TransformInlineAssignmentStObjOrCall(Block block, int pos)
{
var inst = block.Instructions[i] as StLoc;
var inst = block.Instructions[pos] as StLoc;
// in some cases it can be a compiler-generated local
if (inst == null || (inst.Variable.Kind != VariableKind.StackSlot && inst.Variable.Kind != VariableKind.Local))
return false;
var nextInst = block.Instructions.ElementAtOrDefault(i + 1);
ILInstruction replacement;
StObj fieldStore;
if (IsImplicitTruncation(inst.Value, inst.Variable.Type)) {
// 'stloc s' is implicitly truncating the value
return false;
}
ILVariable local;
if (nextInst is StLoc) { // instance fields
var localStore = (StLoc)nextInst;
if (localStore.Variable.Kind == VariableKind.StackSlot || !localStore.Value.MatchLdLoc(inst.Variable))
int nextPos;
if (block.Instructions[pos + 1] is StLoc localStore) { // with extra local
if (localStore.Variable.Kind != VariableKind.Local || !localStore.Value.MatchLdLoc(inst.Variable))
return false;
// if we're using an extra local, we'll delete "s", so check that that doesn't have any additional uses
if (!(inst.Variable.IsSingleDefinition && inst.Variable.LoadCount == 2))
return false;
local = localStore.Variable;
nextPos = pos + 2;
} else {
local = inst.Variable;
localStore = null;
nextPos = pos + 1;
}
if (block.Instructions[nextPos] is StObj stobj) {
if (!stobj.Value.MatchLdLoc(inst.Variable))
return false;
if (!SemanticHelper.IsPure(stobj.Target.Flags) || inst.Variable.IsUsedWithin(stobj.Target))
return false;
if (IsImplicitTruncation(inst.Value, stobj.Type)) {
// 'stobj' is implicitly truncating the value
return false;
var memberStore = block.Instructions.ElementAtOrDefault(i + 2);
if (memberStore is StObj) {
fieldStore = memberStore as StObj;
if (!fieldStore.Value.MatchLdLoc(inst.Variable))
}
context.Step("Inline assignment stobj", stobj);
block.Instructions.Remove(localStore);
block.Instructions.Remove(stobj);
stobj.Value = inst.Value;
inst.ReplaceWith(new StLoc(local, stobj));
// note: our caller will trigger a re-run, which will call HandleStObjCompoundAssign if applicable
return true;
} else if (block.Instructions[nextPos] is CallInstruction call) {
// call must be a setter call:
if (!(call.OpCode == OpCode.Call || call.OpCode == OpCode.CallVirt))
return false;
if (call.ResultType != StackType.Void || call.Arguments.Count == 0)
return false;
if (!call.Method.Equals((call.Method.AccessorOwner as IProperty)?.Setter))
return false;
if (!call.Arguments.Last().MatchLdLoc(inst.Variable))
return false;
foreach (var arg in call.Arguments.SkipLast(1)) {
if (!SemanticHelper.IsPure(arg.Flags) || inst.Variable.IsUsedWithin(arg))
return false;
replacement = new StObj(fieldStore.Target, inst.Value, fieldStore.Type);
} else { // otherwise it must be local
return TransformInlineAssignmentLocal(block, i);
}
context.Step("Inline assignment to instance field", fieldStore);
local = localStore.Variable;
block.Instructions.RemoveAt(i + 1);
} else if (nextInst is StObj) { // static fields
fieldStore = (StObj)nextInst;
if (!fieldStore.Value.MatchLdLoc(inst.Variable) || (fieldStore.Target.MatchLdFlda(out var target, out _) && target.MatchLdLoc(inst.Variable)))
if (IsImplicitTruncation(inst.Value, call.Method.Parameters.Last().Type)) {
// setter call is implicitly truncating the value
return false;
context.Step("Inline assignment to static field", fieldStore);
local = inst.Variable;
replacement = new StObj(fieldStore.Target, inst.Value, fieldStore.Type);
}
// stloc s(Block InlineAssign { call set_Property(..., stloc i(value)); final: ldloc i })
context.Step("Inline assignment call", call);
block.Instructions.Remove(localStore);
block.Instructions.Remove(call);
var newVar = context.Function.RegisterVariable(VariableKind.StackSlot, call.Method.Parameters.Last().Type);
call.Arguments[call.Arguments.Count - 1] = new StLoc(newVar, inst.Value);
var inlineBlock = new Block(BlockType.CallInlineAssign) {
Instructions = { call },
FinalInstruction = new LdLoc(newVar)
};
inst.ReplaceWith(new StLoc(local, inlineBlock));
// because the ExpressionTransforms don't look into inline blocks, manually trigger HandleCallCompoundAssign
if (HandleCallCompoundAssign(call, context)) {
// if we did construct a compound assignment, it should have made our inline block redundant:
if (inlineBlock.Instructions.Single().MatchStLoc(newVar, out var compoundAssign)) {
Debug.Assert(newVar.IsSingleDefinition && newVar.LoadCount == 1);
inlineBlock.ReplaceWith(compoundAssign);
}
}
return true;
} else {
return false;
}
block.Instructions.RemoveAt(i + 1);
inst.ReplaceWith(new StLoc(local, replacement));
return true;
}
/// <code>
/// stloc s(binary(callvirt(getter), value))
/// callvirt (setter, ldloc s)
/// (followed by single usage of s in next instruction)
/// -->
/// stloc s(compound.op.new(callvirt(getter), value))
/// </code>
bool TransformInlineCompoundAssignmentCall(Block block, int i)
static ILInstruction UnwrapSmallIntegerConv(ILInstruction inst, out Conv conv)
{
var mainStLoc = block.Instructions[i] as StLoc;
// in some cases it can be a compiler-generated local
if (mainStLoc == null || (mainStLoc.Variable.Kind != VariableKind.StackSlot && mainStLoc.Variable.Kind != VariableKind.Local))
return false;
BinaryNumericInstruction binary = mainStLoc.Value as BinaryNumericInstruction;
ILVariable localVariable = mainStLoc.Variable;
if (!localVariable.IsSingleDefinition)
return false;
if (localVariable.LoadCount != 2)
return false;
var getterCall = binary?.Left as CallInstruction;
var setterCall = block.Instructions.ElementAtOrDefault(i + 1) as CallInstruction;
if (!MatchingGetterAndSetterCalls(getterCall, setterCall))
return false;
if (!setterCall.Arguments.Last().MatchLdLoc(localVariable))
return false;
var next = block.Instructions.ElementAtOrDefault(i + 2);
if (next == null)
return false;
if (next.Descendants.Where(d => d.MatchLdLoc(localVariable)).Count() != 1)
return false;
if (!CompoundAssignmentInstruction.IsBinaryCompatibleWithType(binary, getterCall.Method.ReturnType))
return false;
context.Step($"Inline compound assignment to '{getterCall.Method.AccessorOwner.Name}'", setterCall);
block.Instructions.RemoveAt(i + 1); // remove setter call
binary.ReplaceWith(new CompoundAssignmentInstruction(
binary, getterCall, binary.Right,
getterCall.Method.ReturnType, CompoundAssignmentType.EvaluatesToNewValue));
return true;
conv = inst as Conv;
if (conv != null && conv.Kind == ConversionKind.Truncate && conv.TargetType.IsSmallIntegerType()) {
// for compound assignments to small integers, the compiler emits a "conv" instruction
return conv.Argument;
} else {
return inst;
}
}
/// <summary>
/// Roslyn compound assignment that's not inline within another instruction.
/// </summary>
bool TransformRoslynCompoundAssignmentCall(Block block, int i)
static bool ValidateCompoundAssign(BinaryNumericInstruction binary, Conv conv, IType targetType)
{
// stloc variable(callvirt get_Property(ldloc obj))
// callvirt set_Property(ldloc obj, binary.op(ldloc variable, ldc.i4 1))
// => compound.op.new(callvirt get_Property(ldloc obj), ldc.i4 1)
if (!(block.Instructions[i] is StLoc stloc))
return false;
if (!(stloc.Variable.IsSingleDefinition && stloc.Variable.LoadCount == 1))
return false;
var getterCall = stloc.Value as CallInstruction;
var setterCall = block.Instructions[i + 1] as CallInstruction;
if (!(MatchingGetterAndSetterCalls(getterCall, setterCall)))
return false;
var binary = setterCall.Arguments.Last() as BinaryNumericInstruction;
if (binary == null || !binary.Left.MatchLdLoc(stloc.Variable))
return false;
if (!CompoundAssignmentInstruction.IsBinaryCompatibleWithType(binary, getterCall.Method.ReturnType))
if (!CompoundAssignmentInstruction.IsBinaryCompatibleWithType(binary, targetType))
return false;
context.Step($"Compound assignment to '{getterCall.Method.AccessorOwner.Name}'", setterCall);
block.Instructions.RemoveAt(i + 1); // remove setter call
stloc.ReplaceWith(new CompoundAssignmentInstruction(
binary, getterCall, binary.Right,
getterCall.Method.ReturnType, CompoundAssignmentType.EvaluatesToNewValue));
if (conv != null && !(conv.TargetType == targetType.ToPrimitiveType() && conv.CheckForOverflow == binary.CheckForOverflow))
return false; // conv does not match binary operation
return true;
}
static bool MatchingGetterAndSetterCalls(CallInstruction getterCall, CallInstruction setterCall)
{
if (getterCall == null || setterCall == null || !IsSameMember(getterCall.Method.AccessorOwner, setterCall.Method.AccessorOwner))
@ -206,21 +215,31 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -206,21 +215,31 @@ namespace ICSharpCode.Decompiler.IL.Transforms
internal static bool HandleCallCompoundAssign(CallInstruction setterCall, StatementTransformContext context)
{
// callvirt set_Property(ldloc S_1, binary.op(callvirt get_Property(ldloc S_1), value))
// ==> compound.op.new(callvirt(callvirt get_Property(ldloc S_1)), value)
// ==> compound.op.new(callvirt get_Property(ldloc S_1), value)
var setterValue = setterCall.Arguments.LastOrDefault();
var storeInSetter = setterValue as StLoc;
if (storeInSetter != null) {
// callvirt set_Property(ldloc S_1, stloc v(binary.op(callvirt get_Property(ldloc S_1), value)))
// ==> stloc v(compound.op.new(callvirt(callvirt get_Property(ldloc S_1)), value))
// ==> stloc v(compound.op.new(callvirt get_Property(ldloc S_1), value))
setterValue = storeInSetter.Value;
}
setterValue = UnwrapSmallIntegerConv(setterValue, out var conv);
if (!(setterValue is BinaryNumericInstruction binary))
return false;
var getterCall = binary.Left as CallInstruction;
if (!MatchingGetterAndSetterCalls(getterCall, setterCall))
return false;
if (!CompoundAssignmentInstruction.IsBinaryCompatibleWithType(binary, getterCall.Method.ReturnType))
IType targetType = getterCall.Method.ReturnType;
if (!ValidateCompoundAssign(binary, conv, targetType))
return false;
if (storeInSetter != null && storeInSetter.Variable.Type.IsSmallIntegerType()) {
// 'stloc v' implicitly truncates.
// Ensure that type of 'v' must match type of the property:
if (storeInSetter.Variable.Type.GetSize() != targetType.GetSize())
return false;
if (storeInSetter.Variable.Type.GetSign() != targetType.GetSign())
return false;
}
context.Step($"Compound assignment to '{getterCall.Method.AccessorOwner.Name}'", setterCall);
ILInstruction newInst = new CompoundAssignmentInstruction(
binary, getterCall, binary.Right,
@ -234,28 +253,122 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -234,28 +253,122 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return true;
}
/// <summary>
/// stobj(target, binary.op(ldobj(target), ...))
/// where target is pure
/// => compound.op(target, ...)
/// </summary>
/// <remarks>
/// Called by ExpressionTransforms.
/// </remarks>
internal static bool HandleStObjCompoundAssign(StObj inst, ILTransformContext context)
{
if (!(UnwrapSmallIntegerConv(inst.Value, out var conv) is BinaryNumericInstruction binary))
return false;
if (!(binary.Left is LdObj ldobj))
return false;
if (!inst.Target.Match(ldobj.Target).Success)
return false;
if (!SemanticHelper.IsPure(ldobj.Target.Flags))
return false;
// ldobj.Type may just be 'int' (due to ldind.i4) when we're actually operating on a 'ref MyEnum'.
// Try to determine the real type of the object we're modifying:
IType targetType = ldobj.Target.InferType();
if (targetType.Kind == TypeKind.Pointer || targetType.Kind == TypeKind.ByReference) {
targetType = ((TypeWithElementType)targetType).ElementType;
if (targetType.Kind == TypeKind.Unknown || targetType.GetSize() != ldobj.Type.GetSize()) {
targetType = ldobj.Type;
}
} else {
targetType = ldobj.Type;
}
if (!ValidateCompoundAssign(binary, conv, targetType))
return false;
context.Step("compound assignment", inst);
inst.ReplaceWith(new CompoundAssignmentInstruction(
binary, binary.Left, binary.Right,
targetType, CompoundAssignmentType.EvaluatesToNewValue));
return true;
}
/// <code>
/// stloc s(value)
/// stloc l(ldloc s)
/// where neither 'stloc s' nor 'stloc l' truncates the value
/// -->
/// stloc s(stloc l(value))
/// </code>
bool TransformInlineAssignmentLocal(Block block, int i)
bool TransformInlineAssignmentLocal(Block block, int pos)
{
var inst = block.Instructions[i] as StLoc;
var nextInst = block.Instructions.ElementAtOrDefault(i + 1) as StLoc;
var inst = block.Instructions[pos] as StLoc;
var nextInst = block.Instructions.ElementAtOrDefault(pos + 1) as StLoc;
if (inst == null || nextInst == null)
return false;
if (nextInst.Variable.Kind == VariableKind.StackSlot || !nextInst.Value.MatchLdLoc(inst.Variable))
if (inst.Variable.Kind != VariableKind.StackSlot)
return false;
Debug.Assert(!inst.Variable.Type.IsSmallIntegerType());
if (!(nextInst.Variable.Kind == VariableKind.Local || nextInst.Variable.Kind == VariableKind.Parameter))
return false;
if (!nextInst.Value.MatchLdLoc(inst.Variable))
return false;
if (IsImplicitTruncation(inst.Value, inst.Variable.Type)) {
// 'stloc s' is implicitly truncating the stack value
return false;
}
if (IsImplicitTruncation(inst.Value, nextInst.Variable.Type)) {
// 'stloc l' is implicitly truncating the stack value
return false;
}
context.Step("Inline assignment to local variable", inst);
var value = inst.Value;
var var = nextInst.Variable;
var stackVar = inst.Variable;
block.Instructions.RemoveAt(i);
block.Instructions.RemoveAt(pos);
nextInst.ReplaceWith(new StLoc(stackVar, new StLoc(var, value)));
return true;
}
/// <summary>
/// Gets whether 'stobj type(..., value)' would evaluate to a different value than 'value'
/// due to implicit truncation.
/// </summary>
bool IsImplicitTruncation(ILInstruction value, IType type)
{
if (!type.IsSmallIntegerType()) {
// Implicit truncation in ILAst only happens for small integer types;
// other types of implicit truncation in IL cause the ILReader to insert
// conv instructions.
return false;
}
// With small integer types, test whether the value might be changed by
// truncation (based on type.GetSize()) followed by sign/zero extension (based on type.GetSign()).
// (it's OK to have false-positives here if we're unsure)
if (value.MatchLdcI4(out int val)) {
switch (type.GetEnumUnderlyingType().GetDefinition()?.KnownTypeCode) {
case KnownTypeCode.Boolean:
return !(val == 0 || val == 1);
case KnownTypeCode.Byte:
return !(val >= byte.MinValue && val <= byte.MaxValue);
case KnownTypeCode.SByte:
return !(val >= sbyte.MinValue && val <= sbyte.MaxValue);
case KnownTypeCode.Int16:
return !(val >= short.MinValue && val <= short.MaxValue);
case KnownTypeCode.UInt16:
case KnownTypeCode.Char:
return !(val >= ushort.MinValue && val <= ushort.MaxValue);
}
} else if (value is Conv conv) {
return conv.TargetType != type.ToPrimitiveType();
} else if (value is Comp) {
return false; // comp returns 0 or 1, which always fits
} else {
IType inferredType = value.InferType();
if (inferredType.Kind != TypeKind.Unknown) {
return !(inferredType.GetSize() <= type.GetSize() && inferredType.GetSign() == type.GetSign());
}
}
return true;
}
/// <code>
/// stloc s(ldloc l)
@ -267,10 +380,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -267,10 +380,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// final: ldloc s2
/// })
/// </code>
bool TransformPostIncDecOperator(Block block, int i)
bool TransformPostIncDecOperatorLocal(Block block, int pos)
{
var inst = block.Instructions[i] as StLoc;
var nextInst = block.Instructions.ElementAtOrDefault(i + 1) as StLoc;
var inst = block.Instructions[pos] as StLoc;
var nextInst = block.Instructions.ElementAtOrDefault(pos + 1) as StLoc;
if (inst == null || nextInst == null || !inst.Value.MatchLdLoc(out var l) || !ILVariableEqualityComparer.Instance.Equals(l, nextInst.Variable))
return false;
var binary = nextInst.Value as BinaryNumericInstruction;
@ -280,158 +393,142 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -280,158 +393,142 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return false;
if ((binary.Operator != BinaryNumericOperator.Add && binary.Operator != BinaryNumericOperator.Sub) || !binary.Left.MatchLdLoc(inst.Variable) || !binary.Right.MatchLdcI4(1))
return false;
context.Step($"TransformPostIncDecOperator", inst);
context.Step($"TransformPostIncDecOperatorLocal", inst);
var tempStore = context.Function.RegisterVariable(VariableKind.StackSlot, inst.Variable.Type);
var assignment = new Block(BlockType.PostfixOperator);
assignment.Instructions.Add(new StLoc(tempStore, new LdLoc(nextInst.Variable)));
assignment.Instructions.Add(new StLoc(nextInst.Variable, new BinaryNumericInstruction(binary.Operator, new LdLoc(tempStore), new LdcI4(1), binary.CheckForOverflow, binary.Sign)));
assignment.FinalInstruction = new LdLoc(tempStore);
nextInst.ReplaceWith(new StLoc(inst.Variable, assignment));
inst.Value = assignment;
block.Instructions.RemoveAt(pos + 1); // remove nextInst
return true;
}
/// ldaddress ::= ldelema | ldflda | ldsflda;
/// <code>
/// stloc s(ldaddress)
/// stloc l(ldobj(ldloc s))
/// stobj(ldloc s, binary.op(ldloc l, ldc.i4 1))
/// -->
/// stloc l(compound.op.old(ldobj(ldaddress), ldc.i4 1))
/// </code>
bool TransformPostIncDecOperatorOnAddress(Block block, int i)
/// <summary>
/// Gets whether 'inst' is a possible store for use as a compound store.
/// </summary>
bool IsCompoundStore(ILInstruction inst, out IType storeType, out ILInstruction value)
{
var inst = block.Instructions[i] as StLoc;
var nextInst = block.Instructions.ElementAtOrDefault(i + 1) as StLoc;
var stobj = block.Instructions.ElementAtOrDefault(i + 2) as StObj;
if (inst == null || nextInst == null || stobj == null)
return false;
if (!inst.Variable.IsSingleDefinition || inst.Variable.LoadCount != 2)
return false;
if (!(inst.Value is LdElema || inst.Value is LdFlda || inst.Value is LdsFlda))
return false;
ILInstruction target;
IType targetType;
if (nextInst.Variable.Kind == VariableKind.StackSlot || !nextInst.Value.MatchLdObj(out target, out targetType) || !target.MatchLdLoc(inst.Variable))
return false;
if (!stobj.Target.MatchLdLoc(inst.Variable))
value = null;
storeType = null;
if (inst is StObj stobj) {
storeType = stobj.Type;
value = stobj.Value;
return SemanticHelper.IsPure(stobj.Target.Flags);
} else if (inst is CallInstruction call && (call.OpCode == OpCode.Call || call.OpCode == OpCode.CallVirt)) {
if (call.Method.Parameters.Count == 0) {
return false;
}
foreach (var arg in call.Arguments.SkipLast(1)) {
if (!SemanticHelper.IsPure(arg.Flags)) {
return false;
}
}
storeType = call.Method.Parameters.Last().Type;
value = call.Arguments.Last();
return IsSameMember(call.Method, (call.Method.AccessorOwner as IProperty)?.Setter);
} else {
return false;
var binary = stobj.Value as BinaryNumericInstruction;
if (binary == null || !binary.Left.MatchLdLoc(nextInst.Variable) || !binary.Right.MatchLdcI4(1)
|| (binary.Operator != BinaryNumericOperator.Add && binary.Operator != BinaryNumericOperator.Sub))
}
}
bool IsMatchingCompoundLoad(ILInstruction load, ILInstruction store, ILVariable forbiddenVariable)
{
if (load is LdObj ldobj && store is StObj stobj) {
Debug.Assert(SemanticHelper.IsPure(stobj.Target.Flags));
if (!SemanticHelper.IsPure(ldobj.Target.Flags))
return false;
if (forbiddenVariable.IsUsedWithin(ldobj.Target))
return false;
return ldobj.Target.Match(stobj.Target).Success;
} else if (MatchingGetterAndSetterCalls(load as CallInstruction, store as CallInstruction)) {
if (forbiddenVariable.IsUsedWithin(load))
return false;
return true;
} else {
return false;
context.Step($"TransformPostIncDecOperator", inst);
var assignment = new CompoundAssignmentInstruction(binary, new LdObj(inst.Value, targetType), binary.Right, targetType, CompoundAssignmentType.EvaluatesToOldValue);
stobj.ReplaceWith(new StLoc(nextInst.Variable, assignment));
block.Instructions.RemoveAt(i + 1);
return true;
}
}
/// <code>
/// stloc l(ldobj(ldflda(target)))
/// stobj(ldflda(target), binary.op(ldloc l, ldc.i4 1))
/// stobj(target, binary.add(stloc l(ldobj(target)), ldc.i4 1))
/// where target is pure and does not use 'l', and the 'stloc l' does not truncate
/// -->
/// compound.op.old(ldobj(ldflda(target)), ldc.i4 1)
/// stloc l(compound.op.old(ldobj(target), ldc.i4 1))
///
/// -or-
///
/// call set_Prop(args..., binary.add(stloc l(call get_Prop(args...)), ldc.i4 1))
/// where args.. are pure and do not use 'l', and the 'stloc l' does not truncate
/// -->
/// stloc l(compound.op.old(call get_Prop(target), ldc.i4 1))
/// </code>
bool TransformRoslynPostIncDecOperatorOnAddress(Block block, int i)
/// <remarks>
/// Even though this transform operates only on a single expression, it's not an expression transform
/// as the result value of the expression changes (this is OK only for statements in a block).
/// </remarks>
bool TransformPostIncDecOperatorWithInlineStore(Block block, int pos)
{
var inst = block.Instructions[i] as StLoc;
var stobj = block.Instructions.ElementAtOrDefault(i + 1) as StObj;
if (inst == null || stobj == null)
var store = block.Instructions[pos];
if (!IsCompoundStore(store, out var targetType, out var value))
return false;
if (!inst.Variable.IsSingleDefinition || inst.Variable.LoadCount != 1)
var binary = UnwrapSmallIntegerConv(value, out var conv) as BinaryNumericInstruction;
if (binary == null || !binary.Right.MatchLdcI4(1))
return false;
if (!inst.Value.MatchLdObj(out var loadTarget, out var loadType) || !loadTarget.MatchLdFlda(out var fieldTarget, out var field))
if (!(binary.Operator == BinaryNumericOperator.Add || binary.Operator == BinaryNumericOperator.Sub))
return false;
if (!stobj.Target.MatchLdFlda(out var fieldTarget2, out var field2))
if (!(binary.Left is StLoc stloc))
return false;
if (!fieldTarget.Match(fieldTarget2).Success || !field.Equals(field2))
if (!(stloc.Variable.Kind == VariableKind.Local || stloc.Variable.Kind == VariableKind.StackSlot))
return false;
var binary = stobj.Value as BinaryNumericInstruction;
if (binary == null || !binary.Left.MatchLdLoc(inst.Variable) || !binary.Right.MatchLdcI4(1)
|| (binary.Operator != BinaryNumericOperator.Add && binary.Operator != BinaryNumericOperator.Sub))
if (!IsMatchingCompoundLoad(stloc.Value, store, stloc.Variable))
return false;
context.Step("TransformRoslynPostIncDecOperator", inst);
stobj.ReplaceWith(new CompoundAssignmentInstruction(binary, inst.Value, binary.Right, loadType, CompoundAssignmentType.EvaluatesToOldValue));
block.Instructions.RemoveAt(i);
return true;
}
/// <code>
/// stloc s(ldflda)
/// stloc s2(ldobj(ldflda(ldloc s)))
/// stloc l(ldloc s2)
/// stobj (ldflda(ldloc s), binary.add(ldloc s2, ldc.i4 1))
/// -->
/// stloc l(compound.op.old(ldobj(ldflda(ldflda)), ldc.i4 1))
/// </code>
bool TransformCSharp4PostIncDecOperatorOnAddress(Block block, int i)
{
var baseFieldAddress = block.Instructions[i] as StLoc;
var fieldValue = block.Instructions.ElementAtOrDefault(i + 1) as StLoc;
var fieldValueCopyToLocal = block.Instructions.ElementAtOrDefault(i + 2) as StLoc;
var stobj = block.Instructions.ElementAtOrDefault(i + 3) as StObj;
if (baseFieldAddress == null || fieldValue == null || fieldValueCopyToLocal == null || stobj == null)
return false;
if (baseFieldAddress.Variable.Kind != VariableKind.StackSlot || fieldValue.Variable.Kind != VariableKind.StackSlot || fieldValueCopyToLocal.Variable.Kind != VariableKind.Local)
return false;
IType t;
IField targetField;
ILInstruction targetFieldLoad, baseFieldAddressLoad2;
if (!fieldValue.Value.MatchLdObj(out targetFieldLoad, out t))
return false;
ILInstruction baseAddress;
if (baseFieldAddress.Value is LdFlda) {
IField targetField2;
ILInstruction baseFieldAddressLoad3;
if (!targetFieldLoad.MatchLdFlda(out baseFieldAddressLoad2, out targetField) || !baseFieldAddressLoad2.MatchLdLoc(baseFieldAddress.Variable))
return false;
if (!stobj.Target.MatchLdFlda(out baseFieldAddressLoad3, out targetField2) || !baseFieldAddressLoad3.MatchLdLoc(baseFieldAddress.Variable) || !IsSameMember(targetField, targetField2))
return false;
baseAddress = new LdFlda(baseFieldAddress.Value, targetField);
} else if (baseFieldAddress.Value is LdElema) {
if (!targetFieldLoad.MatchLdLoc(baseFieldAddress.Variable) || !stobj.Target.MatchLdLoc(baseFieldAddress.Variable))
return false;
baseAddress = baseFieldAddress.Value;
} else {
if (!ValidateCompoundAssign(binary, conv, targetType))
return false;
}
BinaryNumericInstruction binary = stobj.Value as BinaryNumericInstruction;
if (binary == null || !binary.Left.MatchLdLoc(fieldValue.Variable) || !binary.Right.MatchLdcI4(1)
|| (binary.Operator != BinaryNumericOperator.Add && binary.Operator != BinaryNumericOperator.Sub))
return false;
context.Step($"TransformCSharp4PostIncDecOperatorOnAddress", baseFieldAddress);
var assignment = new CompoundAssignmentInstruction(binary, new LdObj(baseAddress, t), binary.Right, t, CompoundAssignmentType.EvaluatesToOldValue);
stobj.ReplaceWith(new StLoc(fieldValueCopyToLocal.Variable, assignment));
block.Instructions.RemoveAt(i + 2);
block.Instructions.RemoveAt(i + 1);
if (IsImplicitTruncation(stloc.Value, stloc.Variable.Type))
return false;
context.Step("TransformPostIncDecOperatorWithInlineStore", store);
block.Instructions[pos] = new StLoc(stloc.Variable, new CompoundAssignmentInstruction(
binary, stloc.Value, binary.Right, targetType, CompoundAssignmentType.EvaluatesToOldValue));
return true;
}
/// <code>
/// stloc s(ldobj(ldsflda))
/// stobj (ldsflda, binary.op(ldloc s, ldc.i4 1))
/// stloc l(ldobj(target))
/// stobj(target, binary.op(ldloc l, ldc.i4 1))
/// target is pure and does not use 'l', 'stloc does not truncate'
/// -->
/// stloc s(compound.op.old(ldobj(ldsflda), ldc.i4 1))
/// stloc l(compound.op.old(ldobj(target), ldc.i4 1))
/// </code>
bool TransformPostIncDecOnStaticField(Block block, int i)
/// <remarks>
/// This pattern occurs with legacy csc for static fields, and with Roslyn for most post-increments.
/// </remarks>
bool TransformPostIncDecOperator(Block block, int i)
{
var inst = block.Instructions[i] as StLoc;
var stobj = block.Instructions.ElementAtOrDefault(i + 1) as StObj;
if (inst == null || stobj == null)
var store = block.Instructions.ElementAtOrDefault(i + 1);
if (inst == null || store == null)
return false;
ILInstruction target;
IType type;
IField field, field2;
if (inst.Variable.Kind != VariableKind.StackSlot || !inst.Value.MatchLdObj(out target, out type) || !target.MatchLdsFlda(out field))
if (!IsCompoundStore(store, out var targetType, out var value))
return false;
if (!stobj.Target.MatchLdsFlda(out field2) || !IsSameMember(field, field2))
if (!IsMatchingCompoundLoad(inst.Value, store, inst.Variable))
return false;
var binary = stobj.Value as BinaryNumericInstruction;
var binary = UnwrapSmallIntegerConv(value, out var conv) as BinaryNumericInstruction;
if (binary == null || !binary.Left.MatchLdLoc(inst.Variable) || !binary.Right.MatchLdcI4(1))
return false;
context.Step($"TransformPostIncDecOnStaticField", inst);
var assignment = new CompoundAssignmentInstruction(binary, inst.Value, binary.Right, type, CompoundAssignmentType.EvaluatesToOldValue);
stobj.ReplaceWith(new StLoc(inst.Variable, assignment));
if (!(binary.Operator == BinaryNumericOperator.Add || binary.Operator == BinaryNumericOperator.Sub))
return false;
if (!ValidateCompoundAssign(binary, conv, targetType))
return false;
if (IsImplicitTruncation(value, targetType))
return false;
context.Step("TransformPostIncDecOperator", inst);
inst.Value = new CompoundAssignmentInstruction(binary, inst.Value, binary.Right, targetType, CompoundAssignmentType.EvaluatesToOldValue);
block.Instructions.RemoveAt(i + 1);
if (inst.Variable.IsSingleDefinition && inst.Variable.LoadCount == 0) {
// dead store -> it was a statement-level post-increment
inst.ReplaceWith(inst.Value);
}
return true;
}

3
ICSharpCode.Decompiler/TypeSystem/TypeUtils.cs

@ -106,7 +106,8 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -106,7 +106,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// </summary>
public static bool IsSmallIntegerType(this IType type)
{
return GetSize(type) < 4;
int size = GetSize(type);
return size > 0 && size < 4;
}
/// <summary>

Loading…
Cancel
Save