From 72bb24167e544099c4a5880247b72edd3662baec Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Tue, 22 Feb 2011 00:57:31 +0100 Subject: [PATCH] Use ILCode instead of Code in type analysis. --- ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs | 292 +++++++++---------- 1 file changed, 146 insertions(+), 146 deletions(-) diff --git a/ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs b/ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs index d1ccc1249..ba7833cd1 100644 --- a/ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs +++ b/ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs @@ -106,6 +106,7 @@ namespace Decompiler TypeReference DoInferTypeForExpression(ILExpression expr, TypeReference expectedType, bool forceInferChildren = false) { switch (expr.Code) { + #region Logical operators case ILCode.LogicNot: if (forceInferChildren) { InferTypeForExpression(expr.Arguments.Single(), typeSystem.Boolean); @@ -118,10 +119,9 @@ namespace Decompiler InferTypeForExpression(expr.Arguments[0], typeSystem.Boolean); } return typeSystem.Boolean; - } - switch ((Code)expr.Code) { + #endregion #region Variable load/store - case Code.Stloc: + case ILCode.Stloc: { ILVariable v = (ILVariable)expr.Operand; if (forceInferChildren || v.Type == null) { @@ -131,7 +131,7 @@ namespace Decompiler } return v.Type; } - case Code.Ldloc: + case ILCode.Ldloc: { ILVariable v = (ILVariable)expr.Operand; if (v.Type == null) { @@ -143,20 +143,20 @@ namespace Decompiler } return v.Type; } - case Code.Starg: + case ILCode.Starg: if (forceInferChildren) InferTypeForExpression(expr.Arguments.Single(), ((ParameterReference)expr.Operand).ParameterType); return null; - case Code.Ldarg: + case ILCode.Ldarg: return ((ParameterReference)expr.Operand).ParameterType; - case Code.Ldloca: + case ILCode.Ldloca: return new ByReferenceType(((ILVariable)expr.Operand).Type); - case Code.Ldarga: + case ILCode.Ldarga: return new ByReferenceType(((ParameterReference)expr.Operand).ParameterType); #endregion #region Call / NewObj - case Code.Call: - case Code.Callvirt: + case ILCode.Call: + case ILCode.Callvirt: { MethodReference method = (MethodReference)expr.Operand; if (forceInferChildren) { @@ -174,7 +174,7 @@ namespace Decompiler } return SubstituteTypeArgs(method.ReturnType, method); } - case Code.Newobj: + case ILCode.Newobj: { MethodReference ctor = (MethodReference)expr.Operand; if (forceInferChildren) { @@ -186,139 +186,139 @@ namespace Decompiler } #endregion #region Load/Store Fields - case Code.Ldfld: + case ILCode.Ldfld: if (forceInferChildren) InferTypeForExpression(expr.Arguments[0], ((FieldReference)expr.Operand).DeclaringType); return GetFieldType((FieldReference)expr.Operand); - case Code.Ldsfld: + case ILCode.Ldsfld: return GetFieldType((FieldReference)expr.Operand); - case Code.Ldflda: - case Code.Ldsflda: + case ILCode.Ldflda: + case ILCode.Ldsflda: return new ByReferenceType(GetFieldType((FieldReference)expr.Operand)); - case Code.Stfld: + case ILCode.Stfld: if (forceInferChildren) { InferTypeForExpression(expr.Arguments[0], ((FieldReference)expr.Operand).DeclaringType); InferTypeForExpression(expr.Arguments[1], GetFieldType((FieldReference)expr.Operand)); } return null; - case Code.Stsfld: + case ILCode.Stsfld: if (forceInferChildren) InferTypeForExpression(expr.Arguments[0], GetFieldType((FieldReference)expr.Operand)); return null; #endregion #region Reference/Pointer instructions - case Code.Ldind_I: - case Code.Ldind_I1: - case Code.Ldind_I2: - case Code.Ldind_I4: - case Code.Ldind_I8: - case Code.Ldind_U1: - case Code.Ldind_U2: - case Code.Ldind_U4: - case Code.Ldind_R4: - case Code.Ldind_R8: - case Code.Ldind_Ref: + case ILCode.Ldind_I: + case ILCode.Ldind_I1: + case ILCode.Ldind_I2: + case ILCode.Ldind_I4: + case ILCode.Ldind_I8: + case ILCode.Ldind_U1: + case ILCode.Ldind_U2: + case ILCode.Ldind_U4: + case ILCode.Ldind_R4: + case ILCode.Ldind_R8: + case ILCode.Ldind_Ref: return UnpackPointer(InferTypeForExpression(expr.Arguments[0], null)); - case Code.Stind_I1: - case Code.Stind_I2: - case Code.Stind_I4: - case Code.Stind_I8: - case Code.Stind_R4: - case Code.Stind_R8: - case Code.Stind_I: - case Code.Stind_Ref: + case ILCode.Stind_I1: + case ILCode.Stind_I2: + case ILCode.Stind_I4: + case ILCode.Stind_I8: + case ILCode.Stind_R4: + case ILCode.Stind_R8: + case ILCode.Stind_I: + case ILCode.Stind_Ref: if (forceInferChildren) { TypeReference elementType = UnpackPointer(InferTypeForExpression(expr.Arguments[0], null)); InferTypeForExpression(expr.Arguments[1], elementType); } return null; - case Code.Ldobj: + case ILCode.Ldobj: return (TypeReference)expr.Operand; - case Code.Stobj: + case ILCode.Stobj: if (forceInferChildren) { InferTypeForExpression(expr.Arguments[1], (TypeReference)expr.Operand); } return null; - case Code.Initobj: + case ILCode.Initobj: return null; - case Code.Localloc: + case ILCode.Localloc: return typeSystem.IntPtr; #endregion #region Arithmetic instructions - case Code.Not: // bitwise complement - case Code.Neg: + case ILCode.Not: // bitwise complement + case ILCode.Neg: return InferTypeForExpression(expr.Arguments.Single(), expectedType); - case Code.Add: - case Code.Sub: - case Code.Mul: - case Code.Or: - case Code.And: - case Code.Xor: + case ILCode.Add: + case ILCode.Sub: + case ILCode.Mul: + case ILCode.Or: + case ILCode.And: + case ILCode.Xor: return InferArgumentsInBinaryOperator(expr, null); - case Code.Add_Ovf: - case Code.Sub_Ovf: - case Code.Mul_Ovf: - case Code.Div: - case Code.Rem: + case ILCode.Add_Ovf: + case ILCode.Sub_Ovf: + case ILCode.Mul_Ovf: + case ILCode.Div: + case ILCode.Rem: return InferArgumentsInBinaryOperator(expr, true); - case Code.Add_Ovf_Un: - case Code.Sub_Ovf_Un: - case Code.Mul_Ovf_Un: - case Code.Div_Un: - case Code.Rem_Un: + case ILCode.Add_Ovf_Un: + case ILCode.Sub_Ovf_Un: + case ILCode.Mul_Ovf_Un: + case ILCode.Div_Un: + case ILCode.Rem_Un: return InferArgumentsInBinaryOperator(expr, false); - case Code.Shl: - case Code.Shr: + case ILCode.Shl: + case ILCode.Shr: if (forceInferChildren) InferTypeForExpression(expr.Arguments[1], typeSystem.Int32); return InferTypeForExpression(expr.Arguments[0], typeSystem.Int32); - case Code.Shr_Un: + case ILCode.Shr_Un: if (forceInferChildren) InferTypeForExpression(expr.Arguments[1], typeSystem.Int32); return InferTypeForExpression(expr.Arguments[0], typeSystem.UInt32); #endregion #region Constant loading instructions - case Code.Ldnull: + case ILCode.Ldnull: return typeSystem.Object; - case Code.Ldstr: + case ILCode.Ldstr: return typeSystem.String; - case Code.Ldftn: - case Code.Ldvirtftn: + case ILCode.Ldftn: + case ILCode.Ldvirtftn: return typeSystem.IntPtr; - case Code.Ldc_I4: + case ILCode.Ldc_I4: return (IsIntegerOrEnum(expectedType) || expectedType == typeSystem.Boolean) ? expectedType : typeSystem.Int32; - case Code.Ldc_I8: + case ILCode.Ldc_I8: return (IsIntegerOrEnum(expectedType)) ? expectedType : typeSystem.Int64; - case Code.Ldc_R4: + case ILCode.Ldc_R4: return typeSystem.Single; - case Code.Ldc_R8: + case ILCode.Ldc_R8: return typeSystem.Double; - case Code.Ldtoken: + case ILCode.Ldtoken: if (expr.Operand is TypeReference) return new TypeReference("System", "RuntimeTypeHandle", module, module, true); else if (expr.Operand is FieldReference) return new TypeReference("System", "RuntimeFieldHandle", module, module, true); else return new TypeReference("System", "RuntimeMethodHandle", module, module, true); - case Code.Arglist: + case ILCode.Arglist: return new TypeReference("System", "RuntimeArgumentHandle", module, module, true); #endregion #region Array instructions - case Code.Newarr: + case ILCode.Newarr: if (forceInferChildren) InferTypeForExpression(expr.Arguments.Single(), typeSystem.Int32); return new ArrayType((TypeReference)expr.Operand); - case Code.Ldlen: + case ILCode.Ldlen: return typeSystem.Int32; - case Code.Ldelem_U1: - case Code.Ldelem_U2: - case Code.Ldelem_U4: - case Code.Ldelem_I1: - case Code.Ldelem_I2: - case Code.Ldelem_I4: - case Code.Ldelem_I8: - case Code.Ldelem_I: - case Code.Ldelem_Ref: + case ILCode.Ldelem_U1: + case ILCode.Ldelem_U2: + case ILCode.Ldelem_U4: + case ILCode.Ldelem_I1: + case ILCode.Ldelem_I2: + case ILCode.Ldelem_I4: + case ILCode.Ldelem_I8: + case ILCode.Ldelem_I: + case ILCode.Ldelem_Ref: { ArrayType arrayType = InferTypeForExpression(expr.Arguments[0], null) as ArrayType; if (forceInferChildren) { @@ -327,27 +327,27 @@ namespace Decompiler } return arrayType != null ? arrayType.ElementType : null; } - case Code.Ldelem_Any: + case ILCode.Ldelem_Any: if (forceInferChildren) { InferTypeForExpression(expr.Arguments[1], typeSystem.Int32); } return (TypeReference)expr.Operand; - case Code.Ldelema: + case ILCode.Ldelema: { ArrayType arrayType = InferTypeForExpression(expr.Arguments[0], null) as ArrayType; if (forceInferChildren) InferTypeForExpression(expr.Arguments[1], typeSystem.Int32); return arrayType != null ? new ByReferenceType(arrayType.ElementType) : null; } - case Code.Stelem_I: - case Code.Stelem_I1: - case Code.Stelem_I2: - case Code.Stelem_I4: - case Code.Stelem_I8: - case Code.Stelem_R4: - case Code.Stelem_R8: - case Code.Stelem_Ref: - case Code.Stelem_Any: + case ILCode.Stelem_I: + case ILCode.Stelem_I1: + case ILCode.Stelem_I2: + case ILCode.Stelem_I4: + case ILCode.Stelem_I8: + case ILCode.Stelem_R4: + case ILCode.Stelem_R8: + case ILCode.Stelem_Ref: + case ILCode.Stelem_Any: if (forceInferChildren) { ArrayType arrayType = InferTypeForExpression(expr.Arguments[0], null) as ArrayType; InferTypeForExpression(expr.Arguments[1], typeSystem.Int32); @@ -358,107 +358,107 @@ namespace Decompiler return null; #endregion #region Conversion instructions - case Code.Conv_I1: - case Code.Conv_Ovf_I1: + case ILCode.Conv_I1: + case ILCode.Conv_Ovf_I1: return (GetInformationAmount(expectedType) == 8 && IsSigned(expectedType) == true) ? expectedType : typeSystem.SByte; - case Code.Conv_I2: - case Code.Conv_Ovf_I2: + case ILCode.Conv_I2: + case ILCode.Conv_Ovf_I2: return (GetInformationAmount(expectedType) == 16 && IsSigned(expectedType) == true) ? expectedType : typeSystem.Int16; - case Code.Conv_I4: - case Code.Conv_Ovf_I4: + case ILCode.Conv_I4: + case ILCode.Conv_Ovf_I4: return (GetInformationAmount(expectedType) == 32 && IsSigned(expectedType) == true) ? expectedType : typeSystem.Int32; - case Code.Conv_I8: - case Code.Conv_Ovf_I8: + case ILCode.Conv_I8: + case ILCode.Conv_Ovf_I8: return (GetInformationAmount(expectedType) == 64 && IsSigned(expectedType) == true) ? expectedType : typeSystem.Int64; - case Code.Conv_U1: - case Code.Conv_Ovf_U1: + case ILCode.Conv_U1: + case ILCode.Conv_Ovf_U1: return (GetInformationAmount(expectedType) == 8 && IsSigned(expectedType) == false) ? expectedType : typeSystem.Byte; - case Code.Conv_U2: - case Code.Conv_Ovf_U2: + case ILCode.Conv_U2: + case ILCode.Conv_Ovf_U2: return (GetInformationAmount(expectedType) == 16 && IsSigned(expectedType) == false) ? expectedType : typeSystem.UInt16; - case Code.Conv_U4: - case Code.Conv_Ovf_U4: + case ILCode.Conv_U4: + case ILCode.Conv_Ovf_U4: return (GetInformationAmount(expectedType) == 32 && IsSigned(expectedType) == false) ? expectedType : typeSystem.UInt32; - case Code.Conv_U8: - case Code.Conv_Ovf_U8: + case ILCode.Conv_U8: + case ILCode.Conv_Ovf_U8: return (GetInformationAmount(expectedType) == 64 && IsSigned(expectedType) == false) ? expectedType : typeSystem.UInt64; - case Code.Conv_I: - case Code.Conv_Ovf_I: + case ILCode.Conv_I: + case ILCode.Conv_Ovf_I: return (GetInformationAmount(expectedType) == nativeInt && IsSigned(expectedType) == true) ? expectedType : typeSystem.IntPtr; - case Code.Conv_U: - case Code.Conv_Ovf_U: + case ILCode.Conv_U: + case ILCode.Conv_Ovf_U: return (GetInformationAmount(expectedType) == nativeInt && IsSigned(expectedType) == false) ? expectedType : typeSystem.UIntPtr; - case Code.Conv_R4: + case ILCode.Conv_R4: return typeSystem.Single; - case Code.Conv_R8: + case ILCode.Conv_R8: return typeSystem.Double; - case Code.Conv_R_Un: + case ILCode.Conv_R_Un: return (expectedType == typeSystem.Single) ? typeSystem.Single : typeSystem.Double; - case Code.Castclass: - case Code.Isinst: - case Code.Unbox_Any: + case ILCode.Castclass: + case ILCode.Isinst: + case ILCode.Unbox_Any: return (TypeReference)expr.Operand; - case Code.Box: + case ILCode.Box: if (forceInferChildren) InferTypeForExpression(expr.Arguments.Single(), (TypeReference)expr.Operand); return (TypeReference)expr.Operand; #endregion #region Comparison instructions - case Code.Ceq: + case ILCode.Ceq: if (forceInferChildren) InferArgumentsInBinaryOperator(expr, null); return typeSystem.Boolean; - case Code.Clt: - case Code.Cgt: + case ILCode.Clt: + case ILCode.Cgt: if (forceInferChildren) InferArgumentsInBinaryOperator(expr, true); return typeSystem.Boolean; - case Code.Clt_Un: - case Code.Cgt_Un: + case ILCode.Clt_Un: + case ILCode.Cgt_Un: if (forceInferChildren) InferArgumentsInBinaryOperator(expr, false); return typeSystem.Boolean; #endregion #region Branch instructions - case Code.Beq: - case Code.Bne_Un: + case ILCode.Beq: + case ILCode.Bne_Un: if (forceInferChildren) InferArgumentsInBinaryOperator(expr, null); return null; - case Code.Brtrue: - case Code.Brfalse: + case ILCode.Brtrue: + case ILCode.Brfalse: if (forceInferChildren) InferTypeForExpression(expr.Arguments.Single(), typeSystem.Boolean); return null; - case Code.Blt: - case Code.Ble: - case Code.Bgt: - case Code.Bge: + case ILCode.Blt: + case ILCode.Ble: + case ILCode.Bgt: + case ILCode.Bge: if (forceInferChildren) InferArgumentsInBinaryOperator(expr, true); return null; - case Code.Blt_Un: - case Code.Ble_Un: - case Code.Bgt_Un: - case Code.Bge_Un: + case ILCode.Blt_Un: + case ILCode.Ble_Un: + case ILCode.Bgt_Un: + case ILCode.Bge_Un: if (forceInferChildren) InferArgumentsInBinaryOperator(expr, false); return null; - case Code.Br: - case Code.Leave: - case Code.Endfinally: - case Code.Switch: - case Code.Throw: - case Code.Rethrow: + case ILCode.Br: + case ILCode.Leave: + case ILCode.Endfinally: + case ILCode.Switch: + case ILCode.Throw: + case ILCode.Rethrow: return null; - case Code.Ret: + case ILCode.Ret: if (forceInferChildren && expr.Arguments.Count == 1) InferTypeForExpression(expr.Arguments[0], context.CurrentMethod.ReturnType); return null; #endregion - case Code.Pop: + case ILCode.Pop: return null; - case Code.Dup: + case ILCode.Dup: return InferTypeForExpression(expr.Arguments.Single(), expectedType); default: Debug.WriteLine("Type Inference: Can't handle " + expr.Code.GetName());