From 6774b3c3ccbf8aa80b9bd5202b797f008666bc8e Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Mon, 25 Jul 2016 23:44:48 +0200 Subject: [PATCH] Add struct TranslationContext to ExpressionBuilder --- .../CSharp/ExpressionBuilder.cs | 92 ++-- .../CSharp/TranslationContext.cs | 30 + .../ICSharpCode.Decompiler.csproj | 1 + ICSharpCode.Decompiler/IL/Instructions.cs | 514 ++++++++++++++++++ ICSharpCode.Decompiler/IL/Instructions.tt | 20 + .../IL/Instructions/ILInstruction.cs | 5 + 6 files changed, 616 insertions(+), 46 deletions(-) create mode 100644 ICSharpCode.Decompiler/CSharp/TranslationContext.cs diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index 9976857db..3bb3746fe 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -59,7 +59,7 @@ namespace ICSharpCode.Decompiler.CSharp /// * If the IL instruction evaluates to a non-integer type, the C# type of the resulting expression shall match the IL stack type, /// and the evaluated values shall be the same. /// - class ExpressionBuilder : ILVisitor + class ExpressionBuilder : ILVisitor { readonly IDecompilerTypeSystem typeSystem; readonly ITypeResolveContext decompilationContext; @@ -111,7 +111,7 @@ namespace ICSharpCode.Decompiler.CSharp public TranslatedExpression Translate(ILInstruction inst) { Debug.Assert(inst != null); - var cexpr = inst.AcceptVisitor(this); + var cexpr = inst.AcceptVisitor(this, new TranslationContext()); #if DEBUG if (inst.ResultType != StackType.Void && cexpr.Type.Kind != TypeKind.Unknown) { if (inst.ResultType.IsIntegerType()) { @@ -176,7 +176,7 @@ namespace ICSharpCode.Decompiler.CSharp .WithRR(new TypeIsResolveResult(arg.ResolveResult, inst.Type, compilation.FindType(TypeCode.Boolean))); } - protected internal override TranslatedExpression VisitIsInst(IsInst inst) + protected internal override TranslatedExpression VisitIsInst(IsInst inst, TranslationContext context) { var arg = Translate(inst.Argument); return new AsExpression(arg.Expression, ConvertType(inst.Type)) @@ -184,12 +184,12 @@ namespace ICSharpCode.Decompiler.CSharp .WithRR(new ConversionResolveResult(inst.Type, arg.ResolveResult, Conversion.TryCast)); } - protected internal override TranslatedExpression VisitNewObj(NewObj inst) + protected internal override TranslatedExpression VisitNewObj(NewObj inst, TranslationContext context) { return HandleCallInstruction(inst); } - protected internal override TranslatedExpression VisitNewArr(NewArr inst) + protected internal override TranslatedExpression VisitNewArr(NewArr inst, TranslationContext context) { var dimensions = inst.Indices.Count; var args = inst.Indices.Select(arg => TranslateArrayIndex(arg)).ToArray(); @@ -204,7 +204,7 @@ namespace ICSharpCode.Decompiler.CSharp .WithRR(new ArrayCreateResolveResult(new ArrayType(compilation, inst.Type, dimensions), args.Select(a => a.ResolveResult).ToList(), new ResolveResult[0])); } - protected internal override TranslatedExpression VisitLocAlloc(LocAlloc inst) + protected internal override TranslatedExpression VisitLocAlloc(LocAlloc inst, TranslationContext context) { var byteType = compilation.FindType(KnownTypeCode.Byte); return new StackAllocExpression { @@ -213,75 +213,75 @@ namespace ICSharpCode.Decompiler.CSharp }.WithILInstruction(inst).WithRR(new ResolveResult(new PointerType(byteType))); } - protected internal override TranslatedExpression VisitLdcI4(LdcI4 inst) + protected internal override TranslatedExpression VisitLdcI4(LdcI4 inst, TranslationContext context) { return new PrimitiveExpression(inst.Value) .WithILInstruction(inst) .WithRR(new ConstantResolveResult(compilation.FindType(KnownTypeCode.Int32), inst.Value)); } - protected internal override TranslatedExpression VisitLdcI8(LdcI8 inst) + protected internal override TranslatedExpression VisitLdcI8(LdcI8 inst, TranslationContext context) { return new PrimitiveExpression(inst.Value) .WithILInstruction(inst) .WithRR(new ConstantResolveResult(compilation.FindType(KnownTypeCode.Int64), inst.Value)); } - protected internal override TranslatedExpression VisitLdcF(LdcF inst) + protected internal override TranslatedExpression VisitLdcF(LdcF inst, TranslationContext context) { return new PrimitiveExpression(inst.Value) .WithILInstruction(inst) .WithRR(new ConstantResolveResult(compilation.FindType(KnownTypeCode.Double), inst.Value)); } - protected internal override TranslatedExpression VisitLdcDecimal(LdcDecimal inst) + protected internal override TranslatedExpression VisitLdcDecimal(LdcDecimal inst, TranslationContext context) { return new PrimitiveExpression(inst.Value) .WithILInstruction(inst) .WithRR(new ConstantResolveResult(compilation.FindType(KnownTypeCode.Decimal), inst.Value)); } - protected internal override TranslatedExpression VisitLdStr(LdStr inst) + protected internal override TranslatedExpression VisitLdStr(LdStr inst, TranslationContext context) { return new PrimitiveExpression(inst.Value) .WithILInstruction(inst) .WithRR(new ConstantResolveResult(compilation.FindType(KnownTypeCode.String), inst.Value)); } - protected internal override TranslatedExpression VisitLdNull(LdNull inst) + protected internal override TranslatedExpression VisitLdNull(LdNull inst, TranslationContext context) { return new NullReferenceExpression() .WithILInstruction(inst) .WithRR(new ConstantResolveResult(SpecialType.NullType, null)); } - protected internal override TranslatedExpression VisitDefaultValue(DefaultValue inst) + protected internal override TranslatedExpression VisitDefaultValue(DefaultValue inst, TranslationContext context) { return new DefaultValueExpression(ConvertType(inst.Type)) .WithILInstruction(inst) .WithRR(new ConstantResolveResult(inst.Type, null)); } - protected internal override TranslatedExpression VisitSizeOf(SizeOf inst) + protected internal override TranslatedExpression VisitSizeOf(SizeOf inst, TranslationContext context) { return new SizeOfExpression(ConvertType(inst.Type)) .WithILInstruction(inst) .WithRR(new SizeOfResolveResult(compilation.FindType(KnownTypeCode.Int32), inst.Type, null)); } - protected internal override TranslatedExpression VisitLdTypeToken(LdTypeToken inst) + protected internal override TranslatedExpression VisitLdTypeToken(LdTypeToken inst, TranslationContext context) { return new TypeOfExpression(ConvertType(inst.Type)).Member("TypeHandle") .WithILInstruction(inst) .WithRR(new TypeOfResolveResult(compilation.FindType(new TopLevelTypeName("System", "RuntimeTypeHandle")), inst.Type)); } - protected internal override TranslatedExpression VisitLogicNot(LogicNot inst) + protected internal override TranslatedExpression VisitLogicNot(LogicNot inst, TranslationContext context) { return LogicNot(TranslateCondition(inst.Argument)).WithILInstruction(inst); } - protected internal override TranslatedExpression VisitBitNot(BitNot inst) + protected internal override TranslatedExpression VisitBitNot(BitNot inst, TranslationContext context) { var argument = Translate(inst.Argument); @@ -326,7 +326,7 @@ namespace ICSharpCode.Decompiler.CSharp readonly HashSet loadedVariablesSet = new HashSet(); - protected internal override TranslatedExpression VisitLdLoc(LdLoc inst) + protected internal override TranslatedExpression VisitLdLoc(LdLoc inst, TranslationContext context) { if (inst.Variable.Kind == VariableKind.StackSlot && inst.Variable.IsSingleDefinition) { loadedVariablesSet.Add(inst.Variable); @@ -334,7 +334,7 @@ namespace ICSharpCode.Decompiler.CSharp return ConvertVariable(inst.Variable).WithILInstruction(inst); } - protected internal override TranslatedExpression VisitLdLoca(LdLoca inst) + protected internal override TranslatedExpression VisitLdLoca(LdLoca inst, TranslationContext context) { var expr = ConvertVariable(inst.Variable).WithILInstruction(inst); // Note that we put the instruction on the IdentifierExpression instead of the DirectionExpression, @@ -344,7 +344,7 @@ namespace ICSharpCode.Decompiler.CSharp .WithRR(new ByReferenceResolveResult(expr.ResolveResult, isOut: false)); } - protected internal override TranslatedExpression VisitStLoc(StLoc inst) + protected internal override TranslatedExpression VisitStLoc(StLoc inst, TranslationContext context) { var translatedValue = Translate(inst.Value); if (inst.Variable.Kind == VariableKind.StackSlot && inst.Variable.IsSingleDefinition @@ -355,7 +355,7 @@ namespace ICSharpCode.Decompiler.CSharp return Assignment(ConvertVariable(inst.Variable).WithoutILInstruction(), translatedValue).WithILInstruction(inst); } - protected internal override TranslatedExpression VisitComp(Comp inst) + protected internal override TranslatedExpression VisitComp(Comp inst, TranslationContext context) { if (inst.Kind.IsEqualityOrInequality()) { bool negateOutput; @@ -474,7 +474,7 @@ namespace ICSharpCode.Decompiler.CSharp .WithRR(new OperatorResolveResult(left.Type, ExpressionType.Assign, left.ResolveResult, right.ResolveResult)); } - protected internal override TranslatedExpression VisitBinaryNumericInstruction(BinaryNumericInstruction inst) + protected internal override TranslatedExpression VisitBinaryNumericInstruction(BinaryNumericInstruction inst, TranslationContext context) { switch (inst.Operator) { case BinaryNumericOperator.Add: @@ -597,7 +597,7 @@ namespace ICSharpCode.Decompiler.CSharp return result; } - protected internal override TranslatedExpression VisitCompoundAssignmentInstruction(CompoundAssignmentInstruction inst) + protected internal override TranslatedExpression VisitCompoundAssignmentInstruction(CompoundAssignmentInstruction inst, TranslationContext context) { switch (inst.Operator) { case BinaryNumericOperator.Add: @@ -699,7 +699,7 @@ namespace ICSharpCode.Decompiler.CSharp } } - protected internal override TranslatedExpression VisitConv(Conv inst) + protected internal override TranslatedExpression VisitConv(Conv inst, TranslationContext context) { var arg = Translate(inst.Argument); StackType inputStackType = inst.Argument.ResultType; @@ -805,12 +805,12 @@ namespace ICSharpCode.Decompiler.CSharp } } - protected internal override TranslatedExpression VisitCall(Call inst) + protected internal override TranslatedExpression VisitCall(Call inst, TranslationContext context) { return HandleCallInstruction(inst); } - protected internal override TranslatedExpression VisitCallVirt(CallVirt inst) + protected internal override TranslatedExpression VisitCallVirt(CallVirt inst, TranslationContext context) { return HandleCallInstruction(inst); } @@ -1141,7 +1141,7 @@ namespace ICSharpCode.Decompiler.CSharp return false; } - protected internal override TranslatedExpression VisitLdObj(LdObj inst) + protected internal override TranslatedExpression VisitLdObj(LdObj inst, TranslationContext context) { var target = Translate(inst.Target); if (target.Expression is DirectionExpression && TypeUtils.IsCompatibleTypeForMemoryAccess(target.Type, inst.Type)) { @@ -1164,7 +1164,7 @@ namespace ICSharpCode.Decompiler.CSharp } } - protected internal override TranslatedExpression VisitStObj(StObj inst) + protected internal override TranslatedExpression VisitStObj(StObj inst, TranslationContext context) { var target = Translate(inst.Target); var value = Translate(inst.Value); @@ -1184,7 +1184,7 @@ namespace ICSharpCode.Decompiler.CSharp return Assignment(result, value).WithILInstruction(inst); } - protected internal override TranslatedExpression VisitLdLen(LdLen inst) + protected internal override TranslatedExpression VisitLdLen(LdLen inst, TranslationContext context) { TranslatedExpression arrayExpr = Translate(inst.Array); if (arrayExpr.Type.Kind != TypeKind.Array) { @@ -1201,21 +1201,21 @@ namespace ICSharpCode.Decompiler.CSharp } } - protected internal override TranslatedExpression VisitLdFlda(LdFlda inst) + protected internal override TranslatedExpression VisitLdFlda(LdFlda inst, TranslationContext context) { var expr = ConvertField(inst.Field, inst.Target); return new DirectionExpression(FieldDirection.Ref, expr) .WithoutILInstruction().WithRR(new ResolveResult(new ByReferenceType(expr.Type))); } - protected internal override TranslatedExpression VisitLdsFlda(LdsFlda inst) + protected internal override TranslatedExpression VisitLdsFlda(LdsFlda inst, TranslationContext context) { var expr = ConvertField(inst.Field); return new DirectionExpression(FieldDirection.Ref, expr) .WithoutILInstruction().WithRR(new ResolveResult(new ByReferenceType(expr.Type))); } - protected internal override TranslatedExpression VisitLdElema(LdElema inst) + protected internal override TranslatedExpression VisitLdElema(LdElema inst, TranslationContext context) { TranslatedExpression arrayExpr = Translate(inst.Array); var arrayType = arrayExpr.Type as ArrayType; @@ -1236,7 +1236,7 @@ namespace ICSharpCode.Decompiler.CSharp return Translate(i).ConvertTo(compilation.FindType(stackType), this); } - protected internal override TranslatedExpression VisitUnboxAny(UnboxAny inst) + protected internal override TranslatedExpression VisitUnboxAny(UnboxAny inst, TranslationContext context) { var arg = Translate(inst.Argument); if (arg.Type.IsReferenceType != true) { @@ -1248,7 +1248,7 @@ namespace ICSharpCode.Decompiler.CSharp .WithRR(new ConversionResolveResult(inst.Type, arg.ResolveResult, Conversion.UnboxingConversion)); } - protected internal override TranslatedExpression VisitUnbox(Unbox inst) + protected internal override TranslatedExpression VisitUnbox(Unbox inst, TranslationContext context) { var arg = Translate(inst.Argument); var castExpression = new CastExpression(ConvertType(inst.Type), arg.Expression) @@ -1258,7 +1258,7 @@ namespace ICSharpCode.Decompiler.CSharp .WithRR(new ConversionResolveResult(new ByReferenceType(inst.Type), arg.ResolveResult, Conversion.UnboxingConversion)); } - protected internal override TranslatedExpression VisitBox(Box inst) + protected internal override TranslatedExpression VisitBox(Box inst, TranslationContext context) { var obj = compilation.FindType(KnownTypeCode.Object); var arg = Translate(inst.Argument).ConvertTo(inst.Type, this); @@ -1267,19 +1267,19 @@ namespace ICSharpCode.Decompiler.CSharp .WithRR(new ConversionResolveResult(obj, arg.ResolveResult, Conversion.BoxingConversion)); } - protected internal override TranslatedExpression VisitCastClass(CastClass inst) + protected internal override TranslatedExpression VisitCastClass(CastClass inst, TranslationContext context) { return Translate(inst.Argument).ConvertTo(inst.Type, this); } - protected internal override TranslatedExpression VisitArglist(Arglist inst) + protected internal override TranslatedExpression VisitArglist(Arglist inst, TranslationContext context) { return new UndocumentedExpression { UndocumentedExpressionType = UndocumentedExpressionType.ArgListAccess } .WithILInstruction(inst) .WithRR(new TypeResolveResult(compilation.FindType(new TopLevelTypeName("System", "RuntimeArgumentHandle")))); } - protected internal override TranslatedExpression VisitMakeRefAny(MakeRefAny inst) + protected internal override TranslatedExpression VisitMakeRefAny(MakeRefAny inst, TranslationContext context) { var arg = Translate(inst.Argument).Expression; if (arg is DirectionExpression) { @@ -1293,7 +1293,7 @@ namespace ICSharpCode.Decompiler.CSharp .WithRR(new TypeResolveResult(compilation.FindType(new TopLevelTypeName("System", "TypedReference")))); } - protected internal override TranslatedExpression VisitRefAnyType(RefAnyType inst) + protected internal override TranslatedExpression VisitRefAnyType(RefAnyType inst, TranslationContext context) { return new UndocumentedExpression { UndocumentedExpressionType = UndocumentedExpressionType.RefType, @@ -1303,7 +1303,7 @@ namespace ICSharpCode.Decompiler.CSharp .WithRR(new TypeResolveResult(compilation.FindType(new TopLevelTypeName("System", "RuntimeTypeHandle")))); } - protected internal override TranslatedExpression VisitRefAnyValue(RefAnyValue inst) + protected internal override TranslatedExpression VisitRefAnyValue(RefAnyValue inst, TranslationContext context) { var expr = new UndocumentedExpression { UndocumentedExpressionType = UndocumentedExpressionType.RefValue, @@ -1313,7 +1313,7 @@ namespace ICSharpCode.Decompiler.CSharp .WithRR(new ByReferenceResolveResult(inst.Type, false)); } - protected internal override TranslatedExpression VisitBlock(Block block) + protected internal override TranslatedExpression VisitBlock(Block block, TranslationContext context) { switch (block.Type) { case BlockType.ArrayInitializer: @@ -1321,7 +1321,7 @@ namespace ICSharpCode.Decompiler.CSharp case BlockType.CompoundOperator: return TranslateCompoundOperator(block); default: - return base.VisitBlock(block); + return ErrorExpression("Unknown block type: " + block.Type); } } @@ -1398,7 +1398,7 @@ namespace ICSharpCode.Decompiler.CSharp .WithRR(resolver.WithCheckForOverflow(inst.CheckForOverflow).ResolveUnaryOperator(op, target.ResolveResult)); } - protected internal override TranslatedExpression VisitIfInstruction(IfInstruction inst) + protected internal override TranslatedExpression VisitIfInstruction(IfInstruction inst, TranslationContext context) { var condition = TranslateCondition(inst.Condition); var trueBranch = Translate(inst.TrueInst); @@ -1414,7 +1414,7 @@ namespace ICSharpCode.Decompiler.CSharp .WithRR(new ResolveResult(targetType)); } - protected internal override TranslatedExpression VisitAddressOf(AddressOf inst) + protected internal override TranslatedExpression VisitAddressOf(AddressOf inst, TranslationContext context) { // HACK: this is only correct if the argument is an R-value; otherwise we're missing the copy to the temporary var value = Translate(inst.Value); @@ -1423,7 +1423,7 @@ namespace ICSharpCode.Decompiler.CSharp .WithRR(new ByReferenceResolveResult(value.ResolveResult, false)); } - protected internal override TranslatedExpression VisitInvalidInstruction(InvalidInstruction inst) + protected internal override TranslatedExpression VisitInvalidInstruction(InvalidInstruction inst, TranslationContext context) { string message = "Invalid IL"; if (inst.ILRange.Start != 0) { @@ -1435,7 +1435,7 @@ namespace ICSharpCode.Decompiler.CSharp return ErrorExpression(message); } - protected override TranslatedExpression Default(ILInstruction inst) + protected override TranslatedExpression Default(ILInstruction inst, TranslationContext context) { return ErrorExpression("OpCode not supported: " + inst.OpCode); } diff --git a/ICSharpCode.Decompiler/CSharp/TranslationContext.cs b/ICSharpCode.Decompiler/CSharp/TranslationContext.cs new file mode 100644 index 000000000..58d901ffc --- /dev/null +++ b/ICSharpCode.Decompiler/CSharp/TranslationContext.cs @@ -0,0 +1,30 @@ +// Copyright (c) 2016 Daniel Grunwald +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; + +namespace ICSharpCode.Decompiler.CSharp +{ + /// + /// Context struct passed in to ExpressionBuilder.Visit() methods. + /// + public struct TranslationContext + { + + } +} diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj index 80f64d403..b5d858c26 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj @@ -64,6 +64,7 @@ + diff --git a/ICSharpCode.Decompiler/IL/Instructions.cs b/ICSharpCode.Decompiler/IL/Instructions.cs index 4e6bf709b..e7033ad32 100644 --- a/ICSharpCode.Decompiler/IL/Instructions.cs +++ b/ICSharpCode.Decompiler/IL/Instructions.cs @@ -447,6 +447,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitInvalidInstruction(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitInvalidInstruction(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as InvalidInstruction; @@ -469,6 +473,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitNop(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitNop(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as Nop; @@ -536,6 +544,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitILFunction(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitILFunction(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as ILFunction; @@ -555,6 +567,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitBlockContainer(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitBlockContainer(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as BlockContainer; @@ -574,6 +590,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitBlock(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitBlock(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as Block; @@ -713,6 +733,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitPinnedRegion(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitPinnedRegion(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as PinnedRegion; @@ -735,6 +759,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLogicNot(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitLogicNot(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as LogicNot; @@ -754,6 +782,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitBinaryNumericInstruction(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitBinaryNumericInstruction(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as BinaryNumericInstruction; @@ -840,6 +872,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitCompoundAssignmentInstruction(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitCompoundAssignmentInstruction(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as CompoundAssignmentInstruction; @@ -862,6 +898,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitBitNot(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitBitNot(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as BitNot; @@ -884,6 +924,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitArglist(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitArglist(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as Arglist; @@ -903,6 +947,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitBranch(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitBranch(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as Branch; @@ -922,6 +970,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLeave(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitLeave(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as Leave; @@ -1021,6 +1073,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitIfInstruction(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitIfInstruction(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as IfInstruction; @@ -1040,6 +1096,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitSwitchInstruction(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitSwitchInstruction(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as SwitchInstruction; @@ -1106,6 +1166,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitSwitchSection(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitSwitchSection(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as SwitchSection; @@ -1125,6 +1189,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitTryCatch(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitTryCatch(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as TryCatch; @@ -1238,6 +1306,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitTryCatchHandler(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitTryCatchHandler(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as TryCatchHandler; @@ -1257,6 +1329,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitTryFinally(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitTryFinally(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as TryFinally; @@ -1276,6 +1352,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitTryFault(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitTryFault(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as TryFault; @@ -1307,6 +1387,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitDebugBreak(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitDebugBreak(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as DebugBreak; @@ -1326,6 +1410,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitComp(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitComp(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as Comp; @@ -1348,6 +1436,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitCall(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitCall(this, context); + } } /// Virtual method call. @@ -1365,6 +1457,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitCallVirt(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitCallVirt(this, context); + } } /// Checks that the input float is not NaN or infinite. @@ -1391,6 +1487,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitCkfinite(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitCkfinite(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as Ckfinite; @@ -1410,6 +1510,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitConv(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitConv(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as Conv; @@ -1478,6 +1582,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdLoc(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitLdLoc(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as LdLoc; @@ -1537,6 +1645,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdLoca(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitLdLoca(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as LdLoca; @@ -1656,6 +1768,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitStLoc(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitStLoc(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as StLoc; @@ -1742,6 +1858,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitAddressOf(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitAddressOf(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as AddressOf; @@ -1772,6 +1892,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdStr(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitLdStr(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as LdStr; @@ -1802,6 +1926,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdcI4(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitLdcI4(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as LdcI4; @@ -1832,6 +1960,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdcI8(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitLdcI8(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as LdcI8; @@ -1862,6 +1994,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdcF(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitLdcF(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as LdcF; @@ -1892,6 +2028,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdcDecimal(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitLdcDecimal(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as LdcDecimal; @@ -1914,6 +2054,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdNull(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitLdNull(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as LdNull; @@ -1946,6 +2090,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdFtn(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitLdFtn(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as LdFtn; @@ -1990,6 +2138,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdVirtFtn(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitLdVirtFtn(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as LdVirtFtn; @@ -2022,6 +2174,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdTypeToken(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitLdTypeToken(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as LdTypeToken; @@ -2054,6 +2210,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdMemberToken(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitLdMemberToken(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as LdMemberToken; @@ -2085,6 +2245,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLocAlloc(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitLocAlloc(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as LocAlloc; @@ -2104,6 +2268,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitReturn(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitReturn(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as Return; @@ -2197,6 +2365,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdFlda(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitLdFlda(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as LdFlda; @@ -2229,6 +2401,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdsFlda(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitLdsFlda(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as LdsFlda; @@ -2273,6 +2449,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitCastClass(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitCastClass(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as CastClass; @@ -2308,6 +2488,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitIsInst(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitIsInst(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as IsInst; @@ -2408,6 +2592,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdObj(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitLdObj(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as LdObj; @@ -2528,6 +2716,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitStObj(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitStObj(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as StObj; @@ -2572,6 +2764,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitBox(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitBox(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as Box; @@ -2616,6 +2812,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitUnbox(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitUnbox(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as Unbox; @@ -2660,6 +2860,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitUnboxAny(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitUnboxAny(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as UnboxAny; @@ -2682,6 +2886,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitNewObj(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitNewObj(this, context); + } } /// Creates an array instance. @@ -2762,6 +2970,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitNewArr(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitNewArr(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as NewArr; @@ -2794,6 +3006,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitDefaultValue(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitDefaultValue(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as DefaultValue; @@ -2825,6 +3041,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitThrow(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitThrow(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as Throw; @@ -2856,6 +3076,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitRethrow(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitRethrow(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as Rethrow; @@ -2888,6 +3112,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitSizeOf(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitSizeOf(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as SizeOf; @@ -2962,6 +3190,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdLen(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitLdLen(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as LdLen; @@ -3070,6 +3302,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdElema(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitLdElema(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as LdElema; @@ -3157,6 +3393,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitArrayToPointer(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitArrayToPointer(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as ArrayToPointer; @@ -3192,6 +3432,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitMakeRefAny(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitMakeRefAny(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as MakeRefAny; @@ -3214,6 +3458,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitRefAnyType(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitRefAnyType(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as RefAnyType; @@ -3258,6 +3506,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitRefAnyValue(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitRefAnyValue(this, context); + } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { var o = other as RefAnyValue; @@ -3789,6 +4041,268 @@ namespace ICSharpCode.Decompiler.IL return Default(inst); } } + + /// + /// Base class for visitor pattern. + /// + public abstract class ILVisitor + { + /// Called by Visit*() methods that were not overridden + protected abstract T Default(ILInstruction inst, C context); + + protected internal virtual T VisitInvalidInstruction(InvalidInstruction inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitNop(Nop inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitILFunction(ILFunction function, C context) + { + return Default(function, context); + } + protected internal virtual T VisitBlockContainer(BlockContainer container, C context) + { + return Default(container, context); + } + protected internal virtual T VisitBlock(Block block, C context) + { + return Default(block, context); + } + protected internal virtual T VisitPinnedRegion(PinnedRegion inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitLogicNot(LogicNot inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitBinaryNumericInstruction(BinaryNumericInstruction inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitCompoundAssignmentInstruction(CompoundAssignmentInstruction inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitBitNot(BitNot inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitArglist(Arglist inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitBranch(Branch inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitLeave(Leave inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitIfInstruction(IfInstruction inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitSwitchInstruction(SwitchInstruction inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitSwitchSection(SwitchSection inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitTryCatch(TryCatch inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitTryCatchHandler(TryCatchHandler inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitTryFinally(TryFinally inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitTryFault(TryFault inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitDebugBreak(DebugBreak inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitComp(Comp inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitCall(Call inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitCallVirt(CallVirt inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitCkfinite(Ckfinite inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitConv(Conv inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitLdLoc(LdLoc inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitLdLoca(LdLoca inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitStLoc(StLoc inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitAddressOf(AddressOf inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitLdStr(LdStr inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitLdcI4(LdcI4 inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitLdcI8(LdcI8 inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitLdcF(LdcF inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitLdcDecimal(LdcDecimal inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitLdNull(LdNull inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitLdFtn(LdFtn inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitLdVirtFtn(LdVirtFtn inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitLdTypeToken(LdTypeToken inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitLdMemberToken(LdMemberToken inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitLocAlloc(LocAlloc inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitReturn(Return inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitLdFlda(LdFlda inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitLdsFlda(LdsFlda inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitCastClass(CastClass inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitIsInst(IsInst inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitLdObj(LdObj inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitStObj(StObj inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitBox(Box inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitUnbox(Unbox inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitUnboxAny(UnboxAny inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitNewObj(NewObj inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitNewArr(NewArr inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitDefaultValue(DefaultValue inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitThrow(Throw inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitRethrow(Rethrow inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitSizeOf(SizeOf inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitLdLen(LdLen inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitLdElema(LdElema inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitArrayToPointer(ArrayToPointer inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitMakeRefAny(MakeRefAny inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitRefAnyType(RefAnyType inst, C context) + { + return Default(inst, context); + } + protected internal virtual T VisitRefAnyValue(RefAnyValue inst, C context) + { + return Default(inst, context); + } + } partial class BinaryComparisonInstruction { diff --git a/ICSharpCode.Decompiler/IL/Instructions.tt b/ICSharpCode.Decompiler/IL/Instructions.tt index 5d1186216..ce516e286 100644 --- a/ICSharpCode.Decompiler/IL/Instructions.tt +++ b/ICSharpCode.Decompiler/IL/Instructions.tt @@ -254,6 +254,10 @@ namespace ICSharpCode.Decompiler.IL { return visitor.Visit<#=opCode.Name#>(this); } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.Visit<#=opCode.Name#>(this, context); + } <# } #> <# if (opCode.GeneratePerformMatch) { #> protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) @@ -297,6 +301,22 @@ namespace ICSharpCode.Decompiler.IL } <# } #> } + + /// + /// Base class for visitor pattern. + /// + public abstract class ILVisitor + { + /// Called by Visit*() methods that were not overridden + protected abstract T Default(ILInstruction inst, C context); + +<# foreach (OpCode opCode in opCodes) { #> + protected internal virtual T Visit<#=opCode.Name#>(<#=opCode.Name#> <#=opCode.VariableName#>, C context) + { + return Default(<#=opCode.VariableName#>, context); + } +<# } #> + } partial class BinaryComparisonInstruction { diff --git a/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs index 70f3196dc..172f25e42 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs @@ -221,6 +221,11 @@ namespace ICSharpCode.Decompiler.IL /// public abstract T AcceptVisitor(ILVisitor visitor); + /// + /// Calls the Visit*-method on the visitor corresponding to the concrete type of this instruction. + /// + public abstract T AcceptVisitor(ILVisitor visitor, C context); + /// /// Gets the child nodes of this instruction. ///