void CodeGenFunction::EmitForStmt(const ForStmt &S) { // FIXME: What do we do if the increment (f.e.) contains a stmt expression, // which contains a continue/break? // Evaluate the first part before the loop. if (S.getInit()) EmitStmt(S.getInit()); // Start the loop with a block that tests the condition. llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); llvm::BasicBlock *AfterFor = createBasicBlock("for.end"); EmitBlock(CondBlock); // Evaluate the condition if present. If not, treat it as a // non-zero-constant according to 6.8.5.3p2, aka, true. if (S.getCond()) { // As long as the condition is true, iterate the loop. llvm::BasicBlock *ForBody = createBasicBlock("for.body"); // C99 6.8.5p2/p4: The first substatement is executed if the expression // compares unequal to 0. The condition must be a scalar type. EmitBranchOnBoolExpr(S.getCond(), ForBody, AfterFor); EmitBlock(ForBody); } else { // Treat it as a non-zero constant. Don't even create a new block for the // body, just fall into it. } // If the for loop doesn't have an increment we can just use the // condition as the continue block. llvm::BasicBlock *ContinueBlock; if (S.getInc()) ContinueBlock = createBasicBlock("for.inc"); else ContinueBlock = CondBlock; // Store the blocks to use for break and continue. BreakContinueStack.push_back(BreakContinue(AfterFor, ContinueBlock)); // If the condition is true, execute the body of the for stmt. EmitStmt(S.getBody()); BreakContinueStack.pop_back(); // If there is an increment, emit it next. if (S.getInc()) { EmitBlock(ContinueBlock); EmitStmt(S.getInc()); } // Finally, branch back up to the condition for the next iteration. EmitBranch(CondBlock); // Emit the fall-through block. EmitBlock(AfterFor, true); }
bool VisitForStmt(ForStmt *parentStmt) { Stmt *bodyStmt = parentStmt->getBody(); ForStmt *forStmt = dyn_cast_or_null<ForStmt>(bodyStmt); CompoundStmt *compoundStmt = dyn_cast_or_null<CompoundStmt>(bodyStmt); if (!forStmt && compoundStmt && compoundStmt->size() == 1) { forStmt = dyn_cast_or_null<ForStmt>(compoundStmt->body_back()); } if (forStmt) { Stmt *initStmt = parentStmt->getInit(); Expr *incExpr = forStmt->getInc(); if (isInnerIncMatchingOuterInit(incExpr, initStmt)) { addViolation(incExpr, this); } } return true; }