/// EmitCompoundStmt - Emit a compound statement {..} node. If GetLast is true, /// this captures the expression result of the last sub-statement and returns it /// (for use by the statement expression extension). RValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast, llvm::Value *AggLoc, bool isAggVol) { PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),S.getLBracLoc(), "LLVM IR generation of compound statement ('{}')"); CGDebugInfo *DI = getDebugInfo(); if (DI) { EnsureInsertPoint(); DI->setLocation(S.getLBracLoc()); // FIXME: The llvm backend is currently not ready to deal with region_end // for block scoping. In the presence of always_inline functions it gets so // confused that it doesn't emit any debug info. Just disable this for now. //DI->EmitRegionStart(CurFn, Builder); } // Keep track of the current cleanup stack depth. size_t CleanupStackDepth = CleanupEntries.size(); bool OldDidCallStackSave = DidCallStackSave; DidCallStackSave = false; for (CompoundStmt::const_body_iterator I = S.body_begin(), E = S.body_end()-GetLast; I != E; ++I) EmitStmt(*I); if (DI) { EnsureInsertPoint(); DI->setLocation(S.getRBracLoc()); // FIXME: The llvm backend is currently not ready to deal with region_end // for block scoping. In the presence of always_inline functions it gets so // confused that it doesn't emit any debug info. Just disable this for now. //DI->EmitRegionEnd(CurFn, Builder); } RValue RV; if (!GetLast) RV = RValue::get(0); else { // We have to special case labels here. They are statements, but when put // at the end of a statement expression, they yield the value of their // subexpression. Handle this by walking through all labels we encounter, // emitting them before we evaluate the subexpr. const Stmt *LastStmt = S.body_back(); while (const LabelStmt *LS = dyn_cast<LabelStmt>(LastStmt)) { EmitLabel(*LS); LastStmt = LS->getSubStmt(); } EnsureInsertPoint(); RV = EmitAnyExpr(cast<Expr>(LastStmt), AggLoc); } DidCallStackSave = OldDidCallStackSave; EmitCleanupBlocks(CleanupStackDepth); return RV; }
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; }