public void VisitFor(ForNode node) { // Don't insert unreachable code if (!_builder.InsertBlock.IsValid) { return; } Metadata oldLexicalScope = _lexicalScope; if (_genContext.DebugInfo) { _genContext.TryGetNodeSymbol(node.Declaration, out Symbol declRange); _lexicalScope = _genContext.DiBuilder.CreateLexicalBlock(_lexicalScope, _genContext.DiFile, declRange.LLVMLine, _genContext.ColumnInfo ? declRange.LLVMColumn : 0); } node.Declaration.AcceptStatementVisitor(this); BasicBlock condBasicBlock = _genContext.Context.AppendBasicBlock(_function.FunctionValue, "for.cond"); BasicBlock bodyBasicBlock = _genContext.Context.AppendBasicBlock(_function.FunctionValue, "for.body"); BasicBlock incBasicBlock = _genContext.Context.AppendBasicBlock(_function.FunctionValue, "for.inc"); BasicBlock endBasicBlock = _genContext.Context.AppendBasicBlock(_function.FunctionValue, "for.end"); SetCurrentDebugLocation(node); BuildBrIfNecessary(condBasicBlock); _builder.PositionAtEnd(condBasicBlock); node.Condition.AcceptExpressionVisitor(this); Value condVal = _visitedValue; if (!condVal.IsValid) { throw new InvalidOperationException("condition did not produce a usable rvalue"); } SetCurrentDebugLocation(node); condVal = ConvertToBool(condVal); _builder.BuildCondBr(condVal, bodyBasicBlock, endBasicBlock); _builder.PositionAtEnd(bodyBasicBlock); BreakContinue oldBreakContinueTop = _breakContinueTop; _breakContinueTop = new BreakContinue(endBasicBlock, incBasicBlock); VisitBody(node.Body); _breakContinueTop = oldBreakContinueTop; BuildBrIfNecessary(incBasicBlock); _builder.PositionAtEnd(incBasicBlock); node.Update.AcceptExpressionVisitor(this); BuildBrIfNecessary(condBasicBlock); _builder.PositionAtEnd(endBasicBlock); _lexicalScope = oldLexicalScope; }
private static int GetBreakOrContinueScopeLevel(XmlNode node) { int breakArgument; if (!BreakContinue.TryGetScopeNumber(node, out breakArgument) || breakArgument < BreakContinue.DefaultScopeNumber) { // POSSIBLY INVALID: If we can't parse the number, we assume it is 1 (the default). // POSSIBLY INVALID: This is not necessarily correct. Older versions of PHP (< 5.4) allowed the // POSSIBLY INVALID: continue/break argument to be dynamic. We currently do not support dynamic values. // POSSIBLY INVALID: We do support constants below 1 (since they default to 1) breakArgument = 1; } return(breakArgument); }