Browse Source

Add support for calling methods on pointers (ptr->ToString()).

pull/100/head
Daniel Grunwald 14 years ago
parent
commit
3759b614cf
  1. 16
      ICSharpCode.Decompiler/Ast/Transforms/IntroduceUnsafeModifier.cs
  2. 4
      ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs
  3. 19
      ICSharpCode.Decompiler/Tests/UnsafeCode.cs
  4. 2
      ILSpy/ILAstLanguage.cs

16
ICSharpCode.Decompiler/Ast/Transforms/IntroduceUnsafeModifier.cs

@ -46,5 +46,21 @@ namespace ICSharpCode.Decompiler.Ast.Transforms @@ -46,5 +46,21 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
else
return base.VisitUnaryOperatorExpression(unaryOperatorExpression, data);
}
public override bool VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, object data)
{
bool result = base.VisitMemberReferenceExpression(memberReferenceExpression, data);
UnaryOperatorExpression uoe = memberReferenceExpression.Target as UnaryOperatorExpression;
if (uoe != null && uoe.Operator == UnaryOperatorType.Dereference) {
PointerReferenceExpression pre = new PointerReferenceExpression();
pre.Target = uoe.Expression.Detach();
pre.MemberName = memberReferenceExpression.MemberName;
memberReferenceExpression.TypeArguments.MoveTo(pre.TypeArguments);
pre.CopyAnnotationsFrom(uoe);
pre.CopyAnnotationsFrom(memberReferenceExpression);
memberReferenceExpression.ReplaceWith(pre);
}
return result;
}
}
}

4
ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs

@ -192,6 +192,8 @@ namespace ICSharpCode.Decompiler.ILAst @@ -192,6 +192,8 @@ namespace ICSharpCode.Decompiler.ILAst
Instruction constraint = expr.GetPrefix(Code.Constrained);
if (constraint != null)
InferTypeForExpression(expr.Arguments[i], new ByReferenceType((TypeReference)constraint.Operand));
else if (method.DeclaringType.IsValueType)
InferTypeForExpression(expr.Arguments[i], new ByReferenceType(method.DeclaringType));
else
InferTypeForExpression(expr.Arguments[i], method.DeclaringType);
} else {
@ -291,7 +293,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -291,7 +293,7 @@ namespace ICSharpCode.Decompiler.ILAst
// An integer can be stored in any other integer of the same size.
int infoAmount = GetInformationAmount(elementType);
if (infoAmount == 1) infoAmount = 8;
if (infoAmount == GetInformationAmount(operandType))
if (infoAmount == GetInformationAmount(operandType) && IsSigned(elementType) != null && IsSigned(operandType) != null)
operandType = elementType;
}
if (forceInferChildren) {

19
ICSharpCode.Decompiler/Tests/UnsafeCode.cs

@ -37,4 +37,23 @@ public class UnsafeCode @@ -37,4 +37,23 @@ public class UnsafeCode
}
}
}
public unsafe void PutDoubleIntoLongArray1(long[] array, int index, double val)
{
fixed (long* l = array) {
((double*)l)[index] = val;
}
}
public unsafe void PutDoubleIntoLongArray2(long[] array, int index, double val)
{
fixed (long* l = &array[index]) {
*(double*)l = val;
}
}
public unsafe string PointerReferenceExpression(double* d)
{
return d->ToString();
}
}

2
ILSpy/ILAstLanguage.cs

@ -66,6 +66,8 @@ namespace ICSharpCode.ILSpy @@ -66,6 +66,8 @@ namespace ICSharpCode.ILSpy
output.WriteDefinition(v.Name, v);
if (v.Type != null) {
output.Write(" : ");
if (v.IsPinned)
output.Write("pinned ");
v.Type.WriteTo(output, true, true);
}
output.WriteLine();

Loading…
Cancel
Save