Browse Source

Add support for ref fields.

pull/2749/head
Siegfried Pammer 3 years ago
parent
commit
5f324de10b
  1. 32
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  2. 11
      ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

32
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -357,16 +357,17 @@ namespace ICSharpCode.Decompiler.CSharp @@ -357,16 +357,17 @@ namespace ICSharpCode.Decompiler.CSharp
mrr = new MemberResolveResult(target.ResolveResult, field);
}
if (requireTarget)
{
return new MemberReferenceExpression(target, field.Name)
.WithRR(mrr);
}
else
var expr = requireTarget
? new MemberReferenceExpression(target, field.Name).WithRR(mrr)
: new IdentifierExpression(field.Name).WithRR(mrr);
if (field.Type.Kind == TypeKind.ByReference)
{
return new IdentifierExpression(field.Name)
.WithRR(mrr);
expr = new DirectionExpression(FieldDirection.Ref, expr)
.WithRR(new ByReferenceResolveResult(mrr, ReferenceKind.Ref));
}
return expr;
}
TranslatedExpression IsType(IsInst inst)
@ -2798,7 +2799,20 @@ namespace ICSharpCode.Decompiler.CSharp @@ -2798,7 +2799,20 @@ namespace ICSharpCode.Decompiler.CSharp
{
value = Translate(inst.Value, typeHint: target.Type);
}
return Assignment(target, value).WithILInstruction(inst);
if (target.Expression is DirectionExpression dirExpr && target.ResolveResult is ByReferenceResolveResult lhsRefRR)
{
// ref (re-)assignment, emit "ref (a = ref b)".
target = target.UnwrapChild(dirExpr.Expression);
value = value.ConvertTo(lhsRefRR.Type, this, allowImplicitConversion: true);
var assign = new AssignmentExpression(target.Expression, value.Expression)
.WithRR(new OperatorResolveResult(target.Type, ExpressionType.Assign, lhsRefRR, value.ResolveResult));
return new DirectionExpression(FieldDirection.Ref, assign)
.WithoutILInstruction().WithRR(lhsRefRR);
}
else
{
return Assignment(target, value).WithILInstruction(inst);
}
}
private TranslatedExpression UnalignedStObj(StObj inst)

11
ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

@ -120,6 +120,17 @@ namespace ICSharpCode.Decompiler.CSharp @@ -120,6 +120,17 @@ namespace ICSharpCode.Decompiler.CSharp
return new ExpressionStatement(expr).WithILInstruction(inst);
}
protected internal override TranslatedStatement VisitStObj(StObj inst)
{
var expr = exprBuilder.Translate(inst);
// strip top-level ref on ref re-assignment
if (expr.Expression is DirectionExpression dirExpr)
{
expr = expr.UnwrapChild(dirExpr.Expression);
}
return new ExpressionStatement(expr).WithILInstruction(inst);
}
protected internal override TranslatedStatement VisitNop(Nop inst)
{
var stmt = new EmptyStatement();

Loading…
Cancel
Save