diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
index 5ac2c3195..cb79b976c 100644
--- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
+++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
@@ -168,6 +168,13 @@ namespace ICSharpCode.Decompiler.CSharp
.WithRR(new ConstantResolveResult(SpecialType.NullType, null));
}
+ protected internal override TranslatedExpression VisitLdTypeToken(LdTypeToken inst)
+ {
+ return new TypeOfExpression(ConvertType(inst.Type))
+ .WithILInstruction(inst)
+ .WithRR(new TypeResolveResult(compilation.FindType(typeof(Type))));
+ }
+
protected internal override TranslatedExpression VisitLogicNot(LogicNot inst)
{
return LogicNot(TranslateCondition(inst.Argument)).WithILInstruction(inst);
diff --git a/ICSharpCode.Decompiler/IL/ILReader.cs b/ICSharpCode.Decompiler/IL/ILReader.cs
index c089a6562..8ce77b8c2 100644
--- a/ICSharpCode.Decompiler/IL/ILReader.cs
+++ b/ICSharpCode.Decompiler/IL/ILReader.cs
@@ -632,7 +632,14 @@ namespace ICSharpCode.Decompiler.IL
case ILOpCode.Stsfld:
return new Void(new StsFld(Pop(), ReadAndDecodeFieldReference()));
case ILOpCode.Ldtoken:
- return new LdToken((MemberReference)ReadAndDecodeMetadataToken());
+ var memberReference = ReadAndDecodeMetadataToken() as MemberReference;
+ if (memberReference is TypeReference)
+ return new LdTypeToken(typeSystem.Resolve((TypeReference)memberReference));
+ if (memberReference is FieldReference)
+ return new LdMemberToken(typeSystem.Resolve((FieldReference)memberReference));
+ if (memberReference is MethodReference)
+ return new LdMemberToken(typeSystem.Resolve((MethodReference)memberReference));
+ throw new NotImplementedException();
case ILOpCode.Ldvirtftn:
return new LdVirtFtn(Pop(), ReadAndDecodeMethodReference());
case ILOpCode.Mkrefany:
diff --git a/ICSharpCode.Decompiler/IL/Instructions.cs b/ICSharpCode.Decompiler/IL/Instructions.cs
index 23a765234..8be76a7c1 100644
--- a/ICSharpCode.Decompiler/IL/Instructions.cs
+++ b/ICSharpCode.Decompiler/IL/Instructions.cs
@@ -119,7 +119,9 @@ namespace ICSharpCode.Decompiler.IL
/// Load method pointer
LdVirtFtn,
/// Loads runtime representation of metadata token
- LdToken,
+ LdTypeToken,
+ /// Loads runtime representation of metadata token
+ LdMemberToken,
/// Allocates space in the stack frame
LocAlloc,
/// Returns from the current method or lambda.
@@ -1074,15 +1076,38 @@ namespace ICSharpCode.Decompiler.IL
}
/// Loads runtime representation of metadata token
- public sealed partial class LdToken : SimpleInstruction
+ public sealed partial class LdTypeToken : SimpleInstruction
+ {
+ public LdTypeToken(IType type) : base(OpCode.LdTypeToken)
+ {
+ this.type = type;
+ }
+ readonly IType type;
+ /// Returns the type operand.
+ public IType Type { get { return type; } }
+ public override StackType ResultType { get { return StackType.O; } }
+ public override void WriteTo(ITextOutput output)
+ {
+ output.Write(OpCode);
+ output.Write(' ');
+ Disassembler.DisassemblerHelpers.WriteOperand(output, type);
+ }
+ public override T AcceptVisitor(ILVisitor visitor)
+ {
+ return visitor.VisitLdTypeToken(this);
+ }
+ }
+
+ /// Loads runtime representation of metadata token
+ public sealed partial class LdMemberToken : SimpleInstruction
{
- public LdToken(Mono.Cecil.MemberReference member) : base(OpCode.LdToken)
+ public LdMemberToken(IMember member) : base(OpCode.LdMemberToken)
{
this.member = member;
}
- readonly Mono.Cecil.MemberReference member;
+ readonly IMember member;
/// Returns the token operand.
- public Mono.Cecil.MemberReference Member { get { return member; } }
+ public IMember Member { get { return member; } }
public override StackType ResultType { get { return StackType.O; } }
public override void WriteTo(ITextOutput output)
{
@@ -1092,7 +1117,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override T AcceptVisitor(ILVisitor visitor)
{
- return visitor.VisitLdToken(this);
+ return visitor.VisitLdMemberToken(this);
}
}
@@ -2200,7 +2225,11 @@ namespace ICSharpCode.Decompiler.IL
{
return Default(inst);
}
- protected internal virtual T VisitLdToken(LdToken inst)
+ protected internal virtual T VisitLdTypeToken(LdTypeToken inst)
+ {
+ return Default(inst);
+ }
+ protected internal virtual T VisitLdMemberToken(LdMemberToken inst)
{
return Default(inst);
}
@@ -2406,7 +2435,8 @@ namespace ICSharpCode.Decompiler.IL
"ldnull",
"ldftn",
"ldvirtftn",
- "ldtoken",
+ "ldtypetoken",
+ "ldmembertoken",
"localloc",
"ret",
"shl",
diff --git a/ICSharpCode.Decompiler/IL/Instructions.tt b/ICSharpCode.Decompiler/IL/Instructions.tt
index f3e7b059f..e4c2dfdb8 100644
--- a/ICSharpCode.Decompiler/IL/Instructions.tt
+++ b/ICSharpCode.Decompiler/IL/Instructions.tt
@@ -122,8 +122,10 @@
CustomClassName("LdFtn"), NoArguments, HasMethodOperand, ResultType("I")),
new OpCode("ldvirtftn", "Load method pointer",
CustomClassName("LdVirtFtn"), Unary, HasMethodOperand, MayThrow, ResultType("I")),
- new OpCode("ldtoken", "Loads runtime representation of metadata token",
- CustomClassName("LdToken"), NoArguments, HasTokenOperand, ResultType("O")),
+ new OpCode("ldtypetoken", "Loads runtime representation of metadata token",
+ CustomClassName("LdTypeToken"), NoArguments, HasTypeOperand, ResultType("O")),
+ new OpCode("ldmembertoken", "Loads runtime representation of metadata token",
+ CustomClassName("LdMemberToken"), NoArguments, HasMemberOperand, ResultType("O")),
new OpCode("localloc", "Allocates space in the stack frame",
CustomClassName("LocAlloc"), Unary, ResultType("I"), MayThrow),
new OpCode("ret", "Returns from the current method or lambda.",
@@ -684,12 +686,12 @@ namespace ICSharpCode.Decompiler.IL
opCode.WriteOperand.Add("Disassembler.DisassemblerHelpers.WriteOperand(output, method);");
};
- static Action HasTokenOperand = opCode => {
- opCode.ConstructorParameters.Add("Mono.Cecil.MemberReference member");
- opCode.Members.Add("readonly Mono.Cecil.MemberReference member;");
+ static Action HasMemberOperand = opCode => {
+ opCode.ConstructorParameters.Add("IMember member");
+ opCode.Members.Add("readonly IMember member;");
opCode.ConstructorBody.Add("this.member = member;");
opCode.Members.Add("/// Returns the token operand." + Environment.NewLine
- + "public Mono.Cecil.MemberReference Member { get { return member; } }");
+ + "public IMember Member { get { return member; } }");
opCode.GenerateWriteTo = true;
opCode.WriteOperand.Add("output.Write(' ');");
opCode.WriteOperand.Add("Disassembler.DisassemblerHelpers.WriteOperand(output, member);");