Browse Source

Improve on #1085 by setting UnknownType.IsReferenceType in more cases.

pull/1108/head
Daniel Grunwald 8 years ago
parent
commit
0e9a163345
  1. 12
      ICSharpCode.Decompiler/IL/ILReader.cs
  2. 39
      ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs
  3. 2
      ICSharpCode.Decompiler/TypeSystem/IDecompilerTypeSystem.cs
  4. 4
      ICSharpCode.Decompiler/TypeSystem/SpecializingDecompilerTypeSystem.cs

12
ICSharpCode.Decompiler/IL/ILReader.cs

@ -78,7 +78,7 @@ namespace ICSharpCode.Decompiler.IL @@ -78,7 +78,7 @@ namespace ICSharpCode.Decompiler.IL
this.currentStack = ImmutableStack<ILVariable>.Empty;
this.unionFind = new UnionFind<ILVariable>();
this.stackMismatchPairs = new List<(ILVariable, ILVariable)>();
this.methodReturnStackType = typeSystem.Resolve(body.Method.ReturnType).GetStackType();
this.methodReturnStackType = typeSystem.Resolve(body.Method.ReturnType, isFromSignature: true).GetStackType();
InitParameterVariables();
this.localVariables = body.Variables.SelectArray(CreateILVariable);
if (body.InitLocals) {
@ -130,7 +130,7 @@ namespace ICSharpCode.Decompiler.IL @@ -130,7 +130,7 @@ namespace ICSharpCode.Decompiler.IL
ILVariable CreateILVariable(Cil.VariableDefinition v)
{
VariableKind kind = IsPinned(v.VariableType) ? VariableKind.PinnedLocal : VariableKind.Local;
ILVariable ilVar = new ILVariable(kind, typeSystem.Resolve(v.VariableType), v.Index);
ILVariable ilVar = new ILVariable(kind, typeSystem.Resolve(v.VariableType, isFromSignature: true), v.Index);
if (!UseDebugSymbols || debugInfo == null || !debugInfo.TryGetName(v, out string name)) {
ilVar.Name = "V_" + v.Index;
ilVar.HasGeneratedName = true;
@ -164,10 +164,10 @@ namespace ICSharpCode.Decompiler.IL @@ -164,10 +164,10 @@ namespace ICSharpCode.Decompiler.IL
parameterType = new ByReferenceType(parameterType);
}
} else {
parameterType = typeSystem.Resolve(p.ParameterType);
parameterType = typeSystem.Resolve(p.ParameterType, isFromSignature: true);
}
} else {
parameterType = typeSystem.Resolve(p.ParameterType);
parameterType = typeSystem.Resolve(p.ParameterType, isFromSignature: true);
}
Debug.Assert(!parameterType.IsUnbound());
if (parameterType.IsUnbound()) {
@ -1283,12 +1283,12 @@ namespace ICSharpCode.Decompiler.IL @@ -1283,12 +1283,12 @@ namespace ICSharpCode.Decompiler.IL
var parameterTypes = new IType[signature.Parameters.Count];
var arguments = new ILInstruction[parameterTypes.Length];
for (int i = signature.Parameters.Count - 1; i >= 0; i--) {
parameterTypes[i] = typeSystem.Resolve(signature.Parameters[i].ParameterType);
parameterTypes[i] = typeSystem.Resolve(signature.Parameters[i].ParameterType, isFromSignature: true);
arguments[i] = Pop(parameterTypes[i].GetStackType());
}
var call = new CallIndirect(
signature.CallingConvention,
typeSystem.Resolve(signature.ReturnType),
typeSystem.Resolve(signature.ReturnType, isFromSignature: true),
parameterTypes.ToImmutableArray(),
arguments,
functionPointer

39
ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs

@ -136,7 +136,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -136,7 +136,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
#region Resolve Type
public IType Resolve(TypeReference typeReference)
public IType Resolve(TypeReference typeReference, bool isFromSignature = false)
{
if (typeReference == null)
return SpecialType.UnknownType;
@ -144,15 +144,22 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -144,15 +144,22 @@ namespace ICSharpCode.Decompiler.TypeSystem
// But PinnedType can be nested within modopt, so we'll also skip those.
while (typeReference is OptionalModifierType || typeReference is RequiredModifierType) {
typeReference = ((TypeSpecification)typeReference).ElementType;
isFromSignature = true;
}
if (typeReference is SentinelType || typeReference is PinnedType) {
typeReference = ((TypeSpecification)typeReference).ElementType;
isFromSignature = true;
}
ITypeReference typeRef;
lock (typeReferenceCecilLoader)
typeRef = typeReferenceCecilLoader.ReadTypeReference(typeReference);
typeRef = typeReferenceCecilLoader.ReadTypeReference(typeReference, isFromSignature: isFromSignature);
return typeRef.Resolve(context);
}
IType ResolveInSignature(TypeReference typeReference)
{
return Resolve(typeReference, isFromSignature: true);
}
#endregion
#region Resolve Field
@ -166,7 +173,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -166,7 +173,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
field = FindNonGenericField(fieldReference);
if (fieldReference.DeclaringType.IsGenericInstance) {
var git = (GenericInstanceType)fieldReference.DeclaringType;
var typeArguments = git.GenericArguments.SelectArray(Resolve);
var typeArguments = git.GenericArguments.SelectArray(ResolveInSignature);
field = (IField)field.Specialize(new TypeParameterSubstitution(typeArguments, null));
}
fieldLookupCache.Add(fieldReference, field);
@ -226,18 +233,18 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -226,18 +233,18 @@ namespace ICSharpCode.Decompiler.TypeSystem
if (methodReference.CallingConvention == MethodCallingConvention.VarArg) {
method = new VarArgInstanceMethod(
method,
methodReference.Parameters.SkipWhile(p => !p.ParameterType.IsSentinel).Select(p => Resolve(p.ParameterType))
methodReference.Parameters.SkipWhile(p => !p.ParameterType.IsSentinel).Select(p => ResolveInSignature(p.ParameterType))
);
} else if (methodReference.IsGenericInstance || methodReference.DeclaringType.IsGenericInstance) {
IReadOnlyList<IType> classTypeArguments = null;
IReadOnlyList<IType> methodTypeArguments = null;
if (methodReference.IsGenericInstance) {
var gim = ((GenericInstanceMethod)methodReference);
methodTypeArguments = gim.GenericArguments.SelectArray(Resolve);
methodTypeArguments = gim.GenericArguments.SelectArray(ResolveInSignature);
}
if (methodReference.DeclaringType.IsGenericInstance) {
var git = (GenericInstanceType)methodReference.DeclaringType;
classTypeArguments = git.GenericArguments.SelectArray(Resolve);
classTypeArguments = git.GenericArguments.SelectArray(ResolveInSignature);
}
method = method.Specialize(new TypeParameterSubstitution(classTypeArguments, methodTypeArguments));
}
@ -261,21 +268,23 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -261,21 +268,23 @@ namespace ICSharpCode.Decompiler.TypeSystem
methods = typeDef.GetMethods(m => m.Name == methodReference.Name, GetMemberOptions.IgnoreInheritedMembers)
.Concat(typeDef.GetAccessors(m => m.Name == methodReference.Name, GetMemberOptions.IgnoreInheritedMembers));
}
foreach (var method in methods) {
if (GetCecil(method) == methodReference)
return method;
if (methodReference.MetadataToken.TokenType == TokenType.Method) {
foreach (var method in methods) {
if (method.MetadataToken == methodReference.MetadataToken)
return method;
}
}
IType[] parameterTypes;
if (methodReference.CallingConvention == MethodCallingConvention.VarArg) {
parameterTypes = methodReference.Parameters
.TakeWhile(p => !p.ParameterType.IsSentinel)
.Select(p => Resolve(p.ParameterType))
.Select(p => ResolveInSignature(p.ParameterType))
.Concat(new[] { SpecialType.ArgList })
.ToArray();
} else {
parameterTypes = methodReference.Parameters.SelectArray(p => Resolve(p.ParameterType));
parameterTypes = methodReference.Parameters.SelectArray(p => ResolveInSignature(p.ParameterType));
}
var returnType = Resolve(methodReference.ReturnType);
var returnType = ResolveInSignature(methodReference.ReturnType);
foreach (var method in methods) {
if (method.TypeParameters.Count != methodReference.GenericParameters.Count)
continue;
@ -362,7 +371,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -362,7 +371,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
property = FindNonGenericProperty(propertyReference);
if (propertyReference.DeclaringType.IsGenericInstance) {
var git = (GenericInstanceType)propertyReference.DeclaringType;
var typeArguments = git.GenericArguments.SelectArray(Resolve);
var typeArguments = git.GenericArguments.SelectArray(ResolveInSignature);
property = (IProperty)property.Specialize(new TypeParameterSubstitution(typeArguments, null));
}
propertyLookupCache.Add(propertyReference, property);
@ -376,7 +385,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -376,7 +385,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
ITypeDefinition typeDef = Resolve(propertyReference.DeclaringType).GetDefinition();
if (typeDef == null)
return null;
var parameterTypes = propertyReference.Parameters.SelectArray(p => Resolve(p.ParameterType));
var parameterTypes = propertyReference.Parameters.SelectArray(p => ResolveInSignature(p.ParameterType));
var returnType = Resolve(propertyReference.PropertyType);
foreach (IProperty property in typeDef.Properties) {
if (property.Name == propertyReference.Name
@ -399,7 +408,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -399,7 +408,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
ev = FindNonGenericEvent(eventReference);
if (eventReference.DeclaringType.IsGenericInstance) {
var git = (GenericInstanceType)eventReference.DeclaringType;
var typeArguments = git.GenericArguments.SelectArray(Resolve);
var typeArguments = git.GenericArguments.SelectArray(ResolveInSignature);
ev = (IEvent)ev.Specialize(new TypeParameterSubstitution(typeArguments, null));
}
eventLookupCache.Add(eventReference, ev);

2
ICSharpCode.Decompiler/TypeSystem/IDecompilerTypeSystem.cs

@ -30,7 +30,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -30,7 +30,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
TypeDefinition GetCecil(ITypeDefinition typeDefinition);
MemberReference GetCecil(IMember member);
IType Resolve(TypeReference typeReference);
IType Resolve(TypeReference typeReference, bool isFromSignature = false);
IField Resolve(FieldReference fieldReference);
IMethod Resolve(MethodReference methodReference);

4
ICSharpCode.Decompiler/TypeSystem/SpecializingDecompilerTypeSystem.cs

@ -51,9 +51,9 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -51,9 +51,9 @@ namespace ICSharpCode.Decompiler.TypeSystem
get { return substitution; }
}
public IType Resolve(Mono.Cecil.TypeReference typeReference)
public IType Resolve(Mono.Cecil.TypeReference typeReference, bool isFromSignature)
{
return context.Resolve(typeReference).AcceptVisitor(substitution);
return context.Resolve(typeReference, isFromSignature).AcceptVisitor(substitution);
}
public IField Resolve(Mono.Cecil.FieldReference fieldReference)

Loading…
Cancel
Save