public override Expression VisitAddressDereference(AddressDereference addr) { Expression result = base.VisitAddressDereference(addr); if (result is AddressDereference) { Expression expr = ((AddressDereference)result).Address; if (expr != null && expr.Type != null && expr.Type.IsPointerType && !this.typeSystem.insideUnsafeCode){ this.HandleError(addr, Error.UnsafeNeeded); return null; } if (addr.Explicit && expr != null && expr.Type is Reference) { this.HandleError(addr, Error.PtrExpected); return null; } } return result; }
private bool ParseStatement(Block/*!*/ block) { //parse instructions and put in expression tree until an assignment, void call, branch target, or branch is encountered StatementList statementList = block.Statements; Expression expr = null; Statement statement = null; bool transferStatement = false; int startingAddress = 0; #if !FxCop SourceContext sourceContext = new SourceContext(); sourceContext.StartPos = this.counter; #endif #if !ROTOR if (this.method.contextForOffset != null){ object sctx = this.method.contextForOffset[this.counter+1]; if (sctx != null) sourceContext = (SourceContext)sctx; } #endif while (true){ bool isStatement = false; startingAddress = this.counter+1; //Add one so that it is never zero (the latter means no entry to the TrivialHashtable) #if FxCop || ILOFFSETS this.ilOffset = this.counter; this.opCode = this.GetOpCode(); #else OpCode opCode = this.GetOpCode(); #endif #if FxCop if (this.handlerMap.TryGetValue(this.ilOffset, out expr)){ expr.sourceContext = sourceContext; expr.ILOffset = this.ilOffset; this.operandStack.Push(expr); } #endif switch (opCode){ case OpCode.Nop: statement = new Statement(NodeType.Nop); goto done; case OpCode.Break: statement = new Statement(NodeType.DebugBreak); goto done; case OpCode.Ldarg_0: expr = this.Parameters(0); break; case OpCode.Ldarg_1: expr = this.Parameters(1); break; case OpCode.Ldarg_2: expr = this.Parameters(2); break; case OpCode.Ldarg_3: expr = this.Parameters(3); break; case OpCode.Ldloc_0: expr = this.locals[0]; break; case OpCode.Ldloc_1: expr = this.locals[1]; break; case OpCode.Ldloc_2: expr = this.locals[2]; break; case OpCode.Ldloc_3: expr = this.locals[3]; break; case OpCode.Stloc_0: statement = new AssignmentStatement(this.locals[0], PopOperand()); goto done; case OpCode.Stloc_1: statement = new AssignmentStatement(this.locals[1], PopOperand()); goto done; case OpCode.Stloc_2: statement = new AssignmentStatement(this.locals[2], PopOperand()); goto done; case OpCode.Stloc_3: statement = new AssignmentStatement(this.locals[3], PopOperand()); goto done; case OpCode.Ldarg_S: expr = this.Parameters(this.GetByte()); break; case OpCode.Ldarga_S: expr = SetType(new UnaryExpression(this.Parameters(this.GetByte()), NodeType.AddressOf)); break; case OpCode.Starg_S: statement = new AssignmentStatement(this.Parameters(this.GetByte()), PopOperand()); goto done; case OpCode.Ldloc_S: expr = this.locals[this.GetByte()]; break; case OpCode.Ldloca_S: expr = SetType(new UnaryExpression(this.locals[this.GetByte()], NodeType.AddressOf)); break; case OpCode.Stloc_S: statement = new AssignmentStatement(this.locals[this.GetByte()], PopOperand()); goto done; case OpCode.Ldnull: expr = new Literal(null, CoreSystemTypes.Object); break; case OpCode.Ldc_I4_M1: expr = new Literal(-1, CoreSystemTypes.Int32); break; case OpCode.Ldc_I4_0: expr = new Literal(0, CoreSystemTypes.Int32); break; case OpCode.Ldc_I4_1: expr = new Literal(1, CoreSystemTypes.Int32); break; case OpCode.Ldc_I4_2: expr = new Literal(2, CoreSystemTypes.Int32); break; case OpCode.Ldc_I4_3: expr = new Literal(3, CoreSystemTypes.Int32); break; case OpCode.Ldc_I4_4: expr = new Literal(4, CoreSystemTypes.Int32); break; case OpCode.Ldc_I4_5: expr = new Literal(5, CoreSystemTypes.Int32); break; case OpCode.Ldc_I4_6: expr = new Literal(6, CoreSystemTypes.Int32); break; case OpCode.Ldc_I4_7: expr = new Literal(7, CoreSystemTypes.Int32); break; case OpCode.Ldc_I4_8: expr = new Literal(8, CoreSystemTypes.Int32); break; case OpCode.Ldc_I4_S: expr = new Literal((int)this.GetSByte(), CoreSystemTypes.Int32); break; case OpCode.Ldc_I4: expr = new Literal(this.GetInt32(), CoreSystemTypes.Int32); break; case OpCode.Ldc_I8: expr = new Literal(this.GetInt64(), CoreSystemTypes.Int64); break; case OpCode.Ldc_R4: expr = new Literal(this.GetSingle(), CoreSystemTypes.Single); break; case OpCode.Ldc_R8: expr = new Literal(this.GetDouble(), CoreSystemTypes.Double); break; case OpCode.Dup: statement = new ExpressionStatement(new Expression(NodeType.Dup)); goto done; case OpCode.Pop: statement = new ExpressionStatement(new UnaryExpression(PopOperand(), NodeType.Pop)); goto done; case OpCode.Jmp: expr = this.ParseCall(NodeType.Jmp, out isStatement); if (isStatement) goto done; break; case OpCode.Call: expr = this.ParseCall(NodeType.Call, out isStatement); if (isStatement) goto done; break; case OpCode.Calli: expr = this.ParseCalli(out isStatement); if (isStatement) goto done; break; case OpCode.Ret: Expression retVal = BodyParser.TypeIsVoid(this.method.ReturnType) ? null : PopOperand(); statement = new Return(retVal); transferStatement = true; goto done; case OpCode.Br_S: statement = this.ParseBranch(NodeType.Nop, 0, true, false); transferStatement = true; goto done; case OpCode.Brfalse_S: statement = this.ParseBranch(NodeType.LogicalNot, 1, true, false); transferStatement = true; goto done; case OpCode.Brtrue_S: statement = this.ParseBranch(NodeType.Nop, 1, true, false); transferStatement = true; goto done; case OpCode.Beq_S: statement = this.ParseBranch(NodeType.Eq, 2, true, false); transferStatement = true; goto done; case OpCode.Bge_S: statement = this.ParseBranch(NodeType.Ge, 2, true, false); transferStatement = true; goto done; case OpCode.Bgt_S: statement = this.ParseBranch(NodeType.Gt, 2, true, false); transferStatement = true; goto done; case OpCode.Ble_S: statement = this.ParseBranch(NodeType.Le, 2, true, false); transferStatement = true; goto done; case OpCode.Blt_S: statement = this.ParseBranch(NodeType.Lt, 2, true, false); transferStatement = true; goto done; case OpCode.Bne_Un_S: statement = this.ParseBranch(NodeType.Ne, 2, true, true); transferStatement = true; goto done; case OpCode.Bge_Un_S: statement = this.ParseBranch(NodeType.Ge, 2, true, true); transferStatement = true; goto done; case OpCode.Bgt_Un_S: statement = this.ParseBranch(NodeType.Gt, 2, true, true); transferStatement = true; goto done; case OpCode.Ble_Un_S: statement = this.ParseBranch(NodeType.Le, 2, true, true); transferStatement = true; goto done; case OpCode.Blt_Un_S: statement = this.ParseBranch(NodeType.Lt, 2, true, true); transferStatement = true; goto done; case OpCode.Br: statement = this.ParseBranch(NodeType.Nop, 0, false, false); transferStatement = true; goto done; case OpCode.Brfalse: statement = this.ParseBranch(NodeType.LogicalNot, 1, false, false); transferStatement = true; goto done; case OpCode.Brtrue: statement = this.ParseBranch(NodeType.Nop, 1, false, false); transferStatement = true; goto done; case OpCode.Beq: statement = this.ParseBranch(NodeType.Eq, 2, false, false); transferStatement = true; goto done; case OpCode.Bge: statement = this.ParseBranch(NodeType.Ge, 2, false, false); transferStatement = true; goto done; case OpCode.Bgt: statement = this.ParseBranch(NodeType.Gt, 2, false, false); transferStatement = true; goto done; case OpCode.Ble: statement = this.ParseBranch(NodeType.Le, 2, false, false); transferStatement = true; goto done; case OpCode.Blt: statement = this.ParseBranch(NodeType.Lt, 2, false, false); transferStatement = true; goto done; case OpCode.Bne_Un: statement = this.ParseBranch(NodeType.Ne, 2, false, true); transferStatement = true; goto done; case OpCode.Bge_Un: statement = this.ParseBranch(NodeType.Ge, 2, false, true); transferStatement = true; goto done; case OpCode.Bgt_Un: statement = this.ParseBranch(NodeType.Gt, 2, false, true); transferStatement = true; goto done; case OpCode.Ble_Un: statement = this.ParseBranch(NodeType.Le, 2, false, true); transferStatement = true; goto done; case OpCode.Blt_Un: statement = this.ParseBranch(NodeType.Lt, 2, false, true); transferStatement = true; goto done; case OpCode.Switch: statement = this.ParseSwitchInstruction(); transferStatement = true; goto done; case OpCode.Ldind_I1: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Int8, this.isVolatile, this.alignment); break; case OpCode.Ldind_U1: expr = new AddressDereference(PopOperand(), CoreSystemTypes.UInt8, this.isVolatile, this.alignment); break; case OpCode.Ldind_I2: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Int16, this.isVolatile, this.alignment); break; case OpCode.Ldind_U2: expr = new AddressDereference(PopOperand(), CoreSystemTypes.UInt16, this.isVolatile, this.alignment); break; case OpCode.Ldind_I4: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Int32, this.isVolatile, this.alignment); break; case OpCode.Ldind_U4: expr = new AddressDereference(PopOperand(), CoreSystemTypes.UInt32, this.isVolatile, this.alignment); break; case OpCode.Ldind_I8: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Int64, this.isVolatile, this.alignment); break; case OpCode.Ldind_I: expr = new AddressDereference(PopOperand(), CoreSystemTypes.IntPtr, this.isVolatile, this.alignment); break; case OpCode.Ldind_R4: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Single, this.isVolatile, this.alignment); break; case OpCode.Ldind_R8: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Double, this.isVolatile, this.alignment); break; case OpCode.Ldind_Ref: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Object, this.isVolatile, this.alignment); break; case OpCode.Stind_Ref: statement = this.ParseStoreIndirect(CoreSystemTypes.Object); goto done; case OpCode.Stind_I1: statement = this.ParseStoreIndirect(CoreSystemTypes.Int8); goto done; case OpCode.Stind_I2: statement = this.ParseStoreIndirect(CoreSystemTypes.Int16); goto done; case OpCode.Stind_I4: statement = this.ParseStoreIndirect(CoreSystemTypes.Int32); goto done; case OpCode.Stind_I8: statement = this.ParseStoreIndirect(CoreSystemTypes.Int64); goto done; case OpCode.Stind_R4: statement = this.ParseStoreIndirect(CoreSystemTypes.Single); goto done; case OpCode.Stind_R8: statement = this.ParseStoreIndirect(CoreSystemTypes.Double); goto done; case OpCode.Add: expr = this.ParseBinaryOperation(NodeType.Add); break; case OpCode.Sub: expr = this.ParseBinaryOperation(NodeType.Sub); break; case OpCode.Mul: expr = this.ParseBinaryOperation(NodeType.Mul); break; case OpCode.Div: expr = this.ParseBinaryOperation(NodeType.Div); break; case OpCode.Div_Un: expr = this.ParseBinaryOperation(NodeType.Div_Un); break; case OpCode.Rem: expr = this.ParseBinaryOperation(NodeType.Rem); break; case OpCode.Rem_Un: expr = this.ParseBinaryOperation(NodeType.Rem_Un); break; case OpCode.And: expr = this.ParseBinaryOperation(NodeType.And); break; case OpCode.Or: expr = this.ParseBinaryOperation(NodeType.Or); break; case OpCode.Xor: expr = this.ParseBinaryOperation(NodeType.Xor); break; case OpCode.Shl: expr = this.ParseBinaryOperation(NodeType.Shl); break; case OpCode.Shr: expr = this.ParseBinaryOperation(NodeType.Shr); break; case OpCode.Shr_Un: expr = this.ParseBinaryOperation(NodeType.Shr_Un); break; case OpCode.Neg: expr = this.ParseUnaryOperation(NodeType.Neg); break; case OpCode.Not: expr = this.ParseUnaryOperation(NodeType.Not); break; case OpCode.Conv_I1: expr = new UnaryExpression(PopOperand(), NodeType.Conv_I1, CoreSystemTypes.Int8); break; case OpCode.Conv_I2: expr = new UnaryExpression(PopOperand(), NodeType.Conv_I2, CoreSystemTypes.Int16); break; case OpCode.Conv_I4: expr = new UnaryExpression(PopOperand(), NodeType.Conv_I4, CoreSystemTypes.Int32); break; case OpCode.Conv_I8: expr = new UnaryExpression(PopOperand(), NodeType.Conv_I8, CoreSystemTypes.Int64); break; case OpCode.Conv_R4: expr = new UnaryExpression(PopOperand(), NodeType.Conv_R4, CoreSystemTypes.Single); break; case OpCode.Conv_R8: expr = new UnaryExpression(PopOperand(), NodeType.Conv_R8, CoreSystemTypes.Double); break; case OpCode.Conv_U4: expr = new UnaryExpression(PopOperand(), NodeType.Conv_U4, CoreSystemTypes.UInt32); break; case OpCode.Conv_U8: expr = new UnaryExpression(PopOperand(), NodeType.Conv_U8, CoreSystemTypes.UInt64); break; case OpCode.Callvirt: expr = this.ParseCall(NodeType.Callvirt, out isStatement); if (isStatement) goto done; break; case OpCode.Cpobj: statement = this.ParseCopyObject(); goto done; case OpCode.Ldobj: expr = new AddressDereference(PopOperand(), (TypeNode)this.GetMemberFromToken(), this.isVolatile, this.alignment); break; case OpCode.Ldstr: expr = new Literal(this.GetStringFromToken(), CoreSystemTypes.String); break; case OpCode.Newobj: expr = this.ParseConstruct(); break; case OpCode.Castclass: expr = ParseTypeCheck(PopOperand(), (TypeNode)this.GetMemberFromToken(), NodeType.Castclass); break; case OpCode.Isinst: expr = ParseTypeCheck(PopOperand(), (TypeNode)this.GetMemberFromToken(), NodeType.Isinst); break; case OpCode.Conv_R_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_R_Un, CoreSystemTypes.Double); break; case OpCode.Unbox: expr = ParseTypeCheck(PopOperand(), (TypeNode)this.GetMemberFromToken(), NodeType.Unbox); break; case OpCode.Throw: statement = new Throw(PopOperand()); transferStatement = true; goto done; case OpCode.Ldfld: expr = new MemberBinding(PopOperand(), this.GetMemberFromToken(), this.isVolatile, this.alignment); break; case OpCode.Ldflda: expr = SetType(new UnaryExpression(new MemberBinding(PopOperand(), this.GetMemberFromToken(), this.isVolatile, this.alignment), NodeType.AddressOf)); break; case OpCode.Stfld: statement = this.ParseStoreField(); goto done; case OpCode.Ldsfld: expr = new MemberBinding(null, this.GetMemberFromToken(), this.isVolatile, this.alignment); break; case OpCode.Ldsflda: expr = SetType(new UnaryExpression(new MemberBinding(null, this.GetMemberFromToken(), this.isVolatile, this.alignment), NodeType.AddressOf)); break; case OpCode.Stsfld: statement = new AssignmentStatement(new MemberBinding(null, this.GetMemberFromToken(), this.isVolatile, this.alignment), PopOperand()); goto done; case OpCode.Stobj: statement = this.ParseStoreIndirect((TypeNode)this.GetMemberFromToken()); goto done; case OpCode.Conv_Ovf_I1_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I1_Un, CoreSystemTypes.Int8); break; case OpCode.Conv_Ovf_I2_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I2_Un, CoreSystemTypes.Int16); break; case OpCode.Conv_Ovf_I4_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I4_Un, CoreSystemTypes.Int32); break; case OpCode.Conv_Ovf_I8_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I8_Un, CoreSystemTypes.Int64); break; case OpCode.Conv_Ovf_U1_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U1_Un, CoreSystemTypes.UInt8); break; case OpCode.Conv_Ovf_U2_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U2_Un, CoreSystemTypes.UInt16); break; case OpCode.Conv_Ovf_U4_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U4_Un, CoreSystemTypes.UInt32); break; case OpCode.Conv_Ovf_U8_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U8_Un, CoreSystemTypes.UInt64); break; case OpCode.Conv_Ovf_I_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I_Un, CoreSystemTypes.IntPtr); break; case OpCode.Conv_Ovf_U_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U_Un, CoreSystemTypes.UIntPtr); break; case OpCode.Box: TypeNode t = (TypeNode)this.GetMemberFromToken(); TypeNode bt = t is EnumNode ? CoreSystemTypes.Enum : CoreSystemTypes.ValueType; expr = new BinaryExpression(PopOperand(), new Literal(t, CoreSystemTypes.Type), NodeType.Box, bt); break; case OpCode.Newarr: expr = this.ParseNewArray(); break; case OpCode.Ldlen: expr = new UnaryExpression(PopOperand(), NodeType.Ldlen, CoreSystemTypes.UIntPtr); break; case OpCode.Ldelema: expr = this.ParseArrayElementLoadAddress(); break; case OpCode.Ldelem_I1: case OpCode.Ldelem_U1: case OpCode.Ldelem_I2: case OpCode.Ldelem_U2: case OpCode.Ldelem_I4: case OpCode.Ldelem_U4: case OpCode.Ldelem_I8: case OpCode.Ldelem_I: case OpCode.Ldelem_R4: case OpCode.Ldelem_R8: case OpCode.Ldelem_Ref: expr = this.ParseArrayElementLoad(opCode, null); break; case OpCode.Stelem_I: case OpCode.Stelem_I1: case OpCode.Stelem_I2: case OpCode.Stelem_I4: case OpCode.Stelem_I8: case OpCode.Stelem_R4: case OpCode.Stelem_R8: case OpCode.Stelem_Ref: statement = this.ParseArrayElementAssignment(opCode); goto done; case OpCode.Ldelem: expr = this.ParseArrayElementLoad(opCode, null); break; case OpCode.Stelem: statement = this.ParseArrayElementAssignment(opCode); goto done; case OpCode.Unbox_Any: expr = ParseTypeCheck(PopOperand(), (TypeNode)this.GetMemberFromToken(), NodeType.UnboxAny); break; case OpCode.Conv_Ovf_I1: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I1, CoreSystemTypes.Int8); break; case OpCode.Conv_Ovf_U1: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U1, CoreSystemTypes.UInt8); break; case OpCode.Conv_Ovf_I2: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I2, CoreSystemTypes.Int16); break; case OpCode.Conv_Ovf_U2: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U2, CoreSystemTypes.UInt16); break; case OpCode.Conv_Ovf_I4: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I4, CoreSystemTypes.Int32); break; case OpCode.Conv_Ovf_U4: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U4, CoreSystemTypes.UInt32); break; case OpCode.Conv_Ovf_I8: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I8, CoreSystemTypes.Int64); break; case OpCode.Conv_Ovf_U8: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U8, CoreSystemTypes.UInt64); break; case OpCode.Refanyval: expr = new BinaryExpression(PopOperand(), new Literal(this.GetMemberFromToken(), CoreSystemTypes.Type), NodeType.Refanyval, CoreSystemTypes.IntPtr); break; case OpCode.Ckfinite: expr = this.ParseUnaryOperation(NodeType.Ckfinite); break; case OpCode.Mkrefany: expr = new BinaryExpression(PopOperand(), new Literal(this.GetMemberFromToken(), CoreSystemTypes.Type), NodeType.Mkrefany, CoreSystemTypes.DynamicallyTypedReference); break; case OpCode.Ldtoken: expr = ParseLoadRuntimeMetadataToken(); break; case OpCode.Conv_U2: expr = new UnaryExpression(PopOperand(), NodeType.Conv_U2, CoreSystemTypes.UInt16); break; case OpCode.Conv_U1: expr = new UnaryExpression(PopOperand(), NodeType.Conv_U1, CoreSystemTypes.UInt8); break; case OpCode.Conv_I: expr = new UnaryExpression(PopOperand(), NodeType.Conv_I, CoreSystemTypes.IntPtr); break; case OpCode.Conv_Ovf_I: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I, CoreSystemTypes.IntPtr); break; case OpCode.Conv_Ovf_U: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U, CoreSystemTypes.UIntPtr); break; case OpCode.Add_Ovf: expr = this.ParseBinaryOperation(NodeType.Add_Ovf); break; case OpCode.Add_Ovf_Un: expr = this.ParseBinaryOperation(NodeType.Add_Ovf_Un); break; case OpCode.Mul_Ovf: expr = this.ParseBinaryOperation(NodeType.Mul_Ovf); break; case OpCode.Mul_Ovf_Un: expr = this.ParseBinaryOperation(NodeType.Mul_Ovf_Un); break; case OpCode.Sub_Ovf: expr = this.ParseBinaryOperation(NodeType.Sub_Ovf); break; case OpCode.Sub_Ovf_Un: expr = this.ParseBinaryOperation(NodeType.Sub_Ovf_Un); break; case OpCode.Endfinally: statement = new EndFinally(); transferStatement = true; goto done; case OpCode.Leave: statement = this.ParseBranch(NodeType.Nop, 0, false, false, true); transferStatement = true; goto done; case OpCode.Leave_S: statement = this.ParseBranch(NodeType.Nop, 0, true, false, true); transferStatement = true; goto done; case OpCode.Stind_I: statement = this.ParseStoreIndirect(CoreSystemTypes.IntPtr); goto done; case OpCode.Conv_U: expr = new UnaryExpression(PopOperand(), NodeType.Conv_U, CoreSystemTypes.UIntPtr); break; case OpCode.Arglist: expr = new Expression(NodeType.Arglist, CoreSystemTypes.ArgIterator); break; case OpCode.Ceq: expr = this.ParseBinaryComparison(NodeType.Ceq); break; case OpCode.Cgt: expr = this.ParseBinaryComparison(NodeType.Cgt); break; case OpCode.Cgt_Un: expr = this.ParseBinaryComparison(NodeType.Cgt_Un); break; case OpCode.Clt: expr = this.ParseBinaryComparison(NodeType.Clt); break; case OpCode.Clt_Un: expr = this.ParseBinaryComparison(NodeType.Clt_Un); break; case OpCode.Ldftn: expr = new UnaryExpression(new MemberBinding(null, this.GetMemberFromToken()), NodeType.Ldftn, CoreSystemTypes.IntPtr); break; case OpCode.Ldvirtftn: expr = new BinaryExpression(PopOperand(), new MemberBinding(null, this.GetMemberFromToken()), NodeType.Ldvirtftn, CoreSystemTypes.IntPtr); break; case OpCode.Ldarg: expr = this.Parameters((ushort)this.GetInt16()); break; case OpCode.Ldarga: expr = SetType(new UnaryExpression(this.Parameters((ushort)this.GetInt16()), NodeType.AddressOf)); break; case OpCode.Starg: statement = new AssignmentStatement(this.Parameters((ushort)this.GetInt16()), PopOperand()); goto done; case OpCode.Ldloc: expr = this.locals[(ushort)this.GetInt16()]; break; case OpCode.Ldloca: expr = SetType(new UnaryExpression(this.locals[(ushort)this.GetInt16()], NodeType.AddressOf)); break; case OpCode.Stloc: statement = new AssignmentStatement(this.locals[(ushort)this.GetInt16()], PopOperand()); goto done; case OpCode.Localloc: expr = new UnaryExpression(PopOperand(), NodeType.Localloc, CoreSystemTypes.Void); break; case OpCode.Endfilter: statement = new EndFilter(PopOperand()); transferStatement = true; goto done; case OpCode.Unaligned_: this.alignment = this.GetByte(); continue; case OpCode.Volatile_: this.isVolatile = true; continue; case OpCode.Tail_: this.isTailCall = true; continue; case OpCode.Initobj: statement = this.ParseInitObject(); goto done; case OpCode.Constrained_: this.constraint = this.GetMemberFromToken() as TypeNode; continue; case OpCode.Cpblk: expr = this.ParseTernaryOperation(NodeType.Cpblk); goto done; case OpCode.Initblk: expr = this.ParseTernaryOperation(NodeType.Initblk); goto done; case OpCode.Rethrow: statement = new Throw(null); statement.NodeType = NodeType.Rethrow; transferStatement = true; goto done; case OpCode.Sizeof: expr = new UnaryExpression(new Literal(this.GetMemberFromToken(), CoreSystemTypes.Type), NodeType.Sizeof, CoreSystemTypes.Int32); break; case OpCode.Refanytype: expr = new UnaryExpression(PopOperand(), NodeType.Refanytype, CoreSystemTypes.RuntimeTypeHandle); break; case OpCode.Readonly_: this.isReadOnly = true; continue; default: throw new InvalidMetadataException(ExceptionStrings.UnknownOpCode); } if (this.blockMap[this.counter+1] != null){ transferStatement = true; //Falls through to the next basic block, so implicitly a "transfer" statement goto done; } //^ assume expr != null; #if FxCop expr.sourceContext = sourceContext; #endif #if FxCop || ILOFFSETS expr.ILOffset = this.ilOffset; #endif this.operandStack.Push(expr); this.isReadOnly = false; this.isVolatile = false; this.isTailCall = false; this.alignment = -1; } done: for (int i = 0; i <= this.operandStack.top; i++){ Expression e = this.operandStack.elements[i]; //^ assume e != null; Statement s = new ExpressionStatement(e); #if FxCop s.SourceContext = this.sourceContext; #endif #if FxCop || ILOFFSETS s.ILOffset = this.ilOffset; #endif statementList.Add(s); } this.operandStack.top = -1; if (statement == null) { statement = new ExpressionStatement(expr); #if FxCop expr.sourceContext = this.sourceContext; #endif #if FxCop || ILOFFSETS expr.ILOffset = this.ilOffset; #endif } statement.SourceContext = sourceContext; #if FxCop || ILOFFSETS statement.ILOffset = this.ilOffset; #endif #if ILOFFSETS this.lastSourceContext = sourceContext; #endif statementList.Add(statement); if (transferStatement) return true; return this.blockMap[this.counter+1] != null; }
public virtual Expression VisitAddressDereference(AddressDereference addr) { if (addr == null) return null; addr.Address = this.VisitExpression(addr.Address); return addr; }
public override Expression VisitAddressDereference(AddressDereference addr) { if (addr == null) return null; return base.VisitAddressDereference((AddressDereference)addr.Clone()); }
private Expression ParseIndexerCallOrSelector(Expression expression, TokenSet followers){ TokenSet followersOrContinuers = followers|Token.LeftBracket|Token.LeftParenthesis|Token.Dot; for(;;){ switch (this.currentToken){ case Token.LeftBracket: SourceContext lbCtx = this.scanner.CurrentSourceContext; this.GetNextToken(); if (this.insideModifiesClause && this.currentToken == Token.Multiply){ // Handle code such as // // modifies myArray[*]; // // which means that the method may modify all elements of myArray. int savedStartPos = this.scanner.startPos; int savedEndPos = this.scanner.endPos; this.GetNextToken(); if (this.currentToken == Token.RightBracket){ SourceContext sctxt = this.scanner.CurrentSourceContext; sctxt.StartPos = lbCtx.StartPos; this.GetNextToken(); return new ModifiesArrayClause(expression, sctxt); } this.scanner.startPos = savedStartPos; this.scanner.endPos = savedEndPos; } int endCol; ExpressionList indices = this.ParseIndexList(followersOrContinuers, lbCtx, out endCol); Indexer indexer = new Indexer(expression, indices); indexer.SourceContext = expression.SourceContext; indexer.SourceContext.EndPos = endCol; indexer.ArgumentListIsIncomplete = this.scanner.GetChar(endCol-1) != ']'; expression = indexer; break; case Token.LessThan: SourceContext ltCtx = this.scanner.CurrentSourceContext; ScannerState ss = this.scanner.state; int arity; TypeNodeList typeArguments = this.ParseTypeArguments(true, false, followers|Token.LeftParenthesis, out endCol, out arity); if (typeArguments == null || (typeArguments.Count > 1 && Parser.TypeArgumentListNonFollower[this.currentToken])) { this.scanner.endPos = ltCtx.StartPos; this.scanner.state = ss; this.currentToken = Token.None; this.GetNextToken(); return expression; } TemplateInstance instance = new TemplateInstance(expression, typeArguments); instance.TypeArgumentExpressions = typeArguments == null ? null : typeArguments.Clone(); instance.SourceContext = expression.SourceContext; instance.SourceContext.EndPos = endCol; expression = instance; break; case Token.LeftParenthesis: SourceContext lpCtx = this.scanner.CurrentSourceContext; this.GetNextToken(); ExpressionList arguments = this.ParseArgumentList(followersOrContinuers, lpCtx, out endCol); if (expression == null) return null; if (expression is Identifier && arguments.Count == 1 && ((Identifier)expression).Name == "old" && InEnsuresContext){ OldExpression old = new OldExpression(arguments[0]); typeArguments = null; old.SourceContext = expression.SourceContext; old.SourceContext.EndPos = endCol; expression = old; break; } if (expression is TemplateInstance) ((TemplateInstance)expression).IsMethodTemplate = true; MethodCall mcall = new MethodCall(expression, arguments); typeArguments = null; mcall.GiveErrorIfSpecialNameMethod = true; mcall.SourceContext = expression.SourceContext; mcall.SourceContext.EndPos = endCol; mcall.ArgumentListIsIncomplete = this.scanner.GetChar(endCol-1) != ')'; expression = mcall; break; case Token.LeftBrace: if (this.compatibilityOn || this.scanner.TokenIsFirstAfterLineBreak) goto default; Expression quant = this.ParseComprehension(followers); if (quant == null) { break; } Block argBlock = new Block(new StatementList(new ExpressionStatement(quant)),quant.SourceContext, this.insideCheckedBlock, this.insideUncheckedBlock, this.inUnsafeCode); argBlock.IsUnsafe = this.inUnsafeCode; argBlock.SourceContext = quant.SourceContext; ExpressionList arguments2 = new ExpressionList(new AnonymousNestedFunction(new ParameterList(0), argBlock, quant.SourceContext)); MethodCall mcall2 = new MethodCall(expression, arguments2); typeArguments = null; mcall2.GiveErrorIfSpecialNameMethod = true; mcall2.SourceContext = expression.SourceContext; mcall2.SourceContext.EndPos = this.scanner.endPos; expression = mcall2; break; case Token.Dot: expression = this.ParseQualifiedIdentifier(expression, followersOrContinuers); break; case Token.RealLiteral: string tokStr = this.scanner.GetTokenSource(); if (this.insideModifiesClause && tokStr == ".0") { // this case is here only for parsing ".0" while parsing a modifies clause // e.g., "modifies this.0;" this.GetNextToken(); // eat the ".0" return new ModifiesNothingClause(expression, this.scanner.CurrentSourceContext); } else { return expression; } case Token.Arrow: if (!this.allowUnsafeCode){ this.HandleError(Error.IllegalUnsafe); this.allowUnsafeCode = true; } this.currentToken = Token.Dot; AddressDereference ad = new AddressDereference(); ad.Address = expression; ad.ExplicitOperator = AddressDereference.ExplicitOp.Arrow; ad.SourceContext = expression.SourceContext; expression = this.ParseQualifiedIdentifier(ad, followersOrContinuers); break; default: return expression; } } }
private Expression ParseUnaryExpression(TokenSet followers){ if (this.currentToken == Token.EndOfFile) { if (this.returnedEmptyIdentForEOF) return null; else { this.returnedEmptyIdentForEOF = true; return this.scanner.GetIdentifier(); } } Expression expression; switch(this.currentToken){ case Token.Plus: case Token.BitwiseNot: case Token.LogicalNot: case Token.Subtract: case Token.BitwiseAnd: UnaryExpression uexpr = new UnaryExpression(); uexpr.SourceContext = this.scanner.CurrentSourceContext; uexpr.NodeType = Parser.ConvertToUnaryNodeType(this.currentToken); this.GetNextToken(); uexpr.Operand = this.ParseUnaryExpression(followers); if (uexpr.Operand == null) return null; uexpr.SourceContext.EndPos = uexpr.Operand.SourceContext.EndPos; expression = uexpr; break; case Token.Multiply: AddressDereference adref = new AddressDereference(); adref.SourceContext = this.scanner.CurrentSourceContext; adref.ExplicitOperator = AddressDereference.ExplicitOp.Star; this.GetNextToken(); adref.Address = this.ParseUnaryExpression(followers); if (adref.Address == null) return null; adref.SourceContext.EndPos = adref.Address.SourceContext.EndPos; expression = adref; break; case Token.AddOne: case Token.SubtractOne: PrefixExpression prefixExpr = new PrefixExpression(); prefixExpr.SourceContext = this.scanner.CurrentSourceContext; prefixExpr.Operator = Parser.ConvertToBinaryNodeType(this.currentToken); this.GetNextToken(); prefixExpr.Expression = this.ParseUnaryExpression(followers); if (prefixExpr.Expression == null) return null; prefixExpr.SourceContext.EndPos = prefixExpr.Expression.SourceContext.EndPos; expression = prefixExpr; break; case Token.LeftParenthesis: expression = this.ParseCastExpression(followers); break; case Token.LeftBrace: expression = this.ParseBlockExpression(ScannerState.Code, this.scanner.CurrentSourceContext, followers); break; case Token.Exists: case Token.Forall: case Token.Count: case Token.Sum: case Token.Max: case Token.Min: case Token.Product: Quantifier q = new Quantifier(); q.SourceContext = this.scanner.CurrentSourceContext; ScannerState ss = this.scanner.state; Token quantType = this.currentToken; SourceContext sctx = this.scanner.CurrentSourceContext; this.GetNextToken(); if (this.currentToken == Token.Unique){ quantType = this.currentToken; this.GetNextToken(); } // not necessarily a quantifier unless there is an open curly!! // REVIEW: Is that enough of a test? Or do we need to try parsing the comprehension? if (this.currentToken != Token.LeftBrace) { //Restore prior state and reparse as expression this.scanner.endPos = q.SourceContext.StartPos; this.scanner.state = ss; this.currentToken = Token.None; this.GetNextToken(); goto default; } q.QuantifierType = Parser.ConvertToQuantifierType(quantType); this.Skip(Token.LeftBrace); Comprehension c = this.ParseComprehension(followers, sctx); if (c == null) { return null; } q.Comprehension = c; q.SourceContext.EndPos = c.SourceContext.EndPos; expression = q; break; default: expression = this.ParsePrimaryExpression(followers); break; } return expression; }
public override Expression VisitAddressDereference(AddressDereference addr) { // Replacing initobj !!0 to initobj !0 var newType = genericParametersMapping.GetClosureTypeParameterByEnclosingTypeParameter(addr.Type); if (newType != addr.Type) { return new AddressDereference(addr.Address, newType, addr.Volatile, addr.Alignment, addr.SourceContext); } return base.VisitAddressDereference(addr); }
public override Expression VisitAddressDereference(AddressDereference addr) { addr = (AddressDereference)addr.Clone(); addr.Address = simplify(addr.Address); return addr; }
public override Expression VisitAddressDereference(AddressDereference addr) { throw new NotImplementedException("Node type not yet supported"); }
public EventingVisitor(Action<AddressDereference> visitAddressDereference) { VisitedAddressDereference += visitAddressDereference; } public event Action<AddressDereference> VisitedAddressDereference; public override Expression VisitAddressDereference(AddressDereference addr) { if (VisitedAddressDereference != null) VisitedAddressDereference(addr); return base.VisitAddressDereference(addr); }