// Override Statements which includes expressions and more bool HostProgramTuning::VisitStmt(Stmt *s) { if (isa<IfStmt>(s)) { // Cast s to IfStmt to access the then and else clauses IfStmt *If = cast<IfStmt>(s); Stmt *TH = If->getThen(); // Add braces if needed to then clause InstrumentStmt(TH); Stmt *EL = If->getElse(); if (EL) { // Add braces if needed to else clause InstrumentStmt(EL); } } else if (isa<WhileStmt>(s)) { WhileStmt *While = cast<WhileStmt>(s); Stmt *BODY = While->getBody(); InstrumentStmt(BODY); } else if (isa<ForStmt>(s)) { ForStmt *For = cast<ForStmt>(s); Stmt *BODY = For->getBody(); InstrumentStmt(BODY); } return true; // returning false aborts the traversal }
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; }
bool VisitFunctionDecl(FunctionDecl *f) { // Only function definitions (with bodies), not declarations. if (f->hasBody()) { Stmt *FuncBody = f->getBody(); // Type name as string QualType QT = f->getReturnType(); std::string TypeStr = QT.getAsString(); // Function name DeclarationName DeclName = f->getNameInfo().getName(); std::string FuncName = DeclName.getAsString(); // Add comment before std::stringstream SSBefore; SSBefore << "// Begin function " << FuncName << " returning " << TypeStr << "\n"; SourceLocation ST = f->getSourceRange().getBegin(); TheRewriter.InsertText(ST, SSBefore.str(), true, true); // And after std::stringstream SSAfter; SSAfter << "\n// End function " << FuncName; ST = FuncBody->getLocEnd().getLocWithOffset(1); TheRewriter.InsertText(ST, SSAfter.str(), true, true); int forCounter=0; Stmt::child_iterator CI, CE = FuncBody->child_end(); for (CI = FuncBody->child_begin(); CI != CE; ++CI) { if (*CI != 0) { if (isa<ForStmt>(*CI)) { forCounter++; std::stringstream MarkerBefore; std::stringstream MarkerAfter; MarkerBefore<<"\nMCPROF_ZONE_ENTER(" << forCounter << ");\n"; MarkerAfter<<"\nMCPROF_ZONE_EXIT(" << forCounter << ");\n"; ForStmt *For = cast<ForStmt>(*CI); SourceLocation ST = For->getLocStart(); TheRewriter.InsertText(ST, MarkerBefore.str(), true, false); Stmt *ForBody = For->getBody(); SourceLocation END = ForBody->getLocEnd(); int offset = Lexer::MeasureTokenLength(END, TheRewriter.getSourceMgr(), TheRewriter.getLangOpts()) + 1; SourceLocation END1 = END.getLocWithOffset(offset); TheRewriter.InsertText(END1, MarkerAfter.str(), true, false); // llvm::errs() << " Detected for loop number " << forCounter // << " in function " << FuncName << "\n"; // InstrumentStmt(ForBody); // Stmt *ForBody = CI->getBody(); // SourceLocation ST = CI->getLocStart(); // char *b = sourceManager->getCharacterData(_b) // llvm::errs() << ST << " is location \n"; } } } } return true; }