// 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::EmitWhileStmt(const WhileStmt &S) { // Emit the header for the loop, insert it, which will create an uncond br to // it. llvm::BasicBlock *LoopHeader = createBasicBlock("while.cond"); EmitBlock(LoopHeader); // Create an exit block for when the condition fails, create a block for the // body of the loop. llvm::BasicBlock *ExitBlock = createBasicBlock("while.end"); llvm::BasicBlock *LoopBody = createBasicBlock("while.body"); // Store the blocks to use for break and continue. BreakContinueStack.push_back(BreakContinue(ExitBlock, LoopHeader)); // Evaluate the conditional in the while header. C99 6.8.5.1: The // evaluation of the controlling expression takes place before each // execution of the loop body. llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); // while(1) is common, avoid extra exit blocks. Be sure // to correctly handle break/continue though. bool EmitBoolCondBranch = true; if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal)) if (C->isOne()) EmitBoolCondBranch = false; // As long as the condition is true, go to the loop body. if (EmitBoolCondBranch) Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock); // Emit the loop body. EmitBlock(LoopBody); EmitStmt(S.getBody()); BreakContinueStack.pop_back(); // Cycle to the condition. EmitBranch(LoopHeader); // Emit the exit block. EmitBlock(ExitBlock, true); // The LoopHeader typically is just a branch if we skipped emitting // a branch, try to erase it. if (!EmitBoolCondBranch) SimplifyForwardingBlocks(LoopHeader); }
void WhileStmt::copyShare(const WhileStmt& ref, SymbolMap* mapRef, bool internal) { SymbolMap localMap; SymbolMap* map = (mapRef != 0) ? mapRef : &localMap; Expr* condExpr = ref.condExprGet(); astloc = ref.astloc; blockTag = ref.blockTag; mBreakLabel = ref.mBreakLabel; mContinueLabel = ref.mContinueLabel; mOrderIndependent = ref.mOrderIndependent; if (condExpr != 0) mCondExpr = condExpr->copy(map, true); for_alist(expr, ref.body) insertAtTail(expr->copy(map, true)); if (internal == false) update_symbols(this, map); }
/** * @brief TreeBuilder::visitNode * @param node * * Looks for variable name and statement, checks syntax correctness */ void TreeBuilder::visitNode(WhileStmt &node) { Token token = m_scanner->scan(); if (token.getType() != Token::Type_LBRACKET) { std::string message = "Expected '(' in while condition, got " + token.classify(); notify(Error::ErrorInfo(message, token)); if (token.getType() != Token::Type_SEMICOLON) restoreScannerState(); return; } token = m_scanner->scan(); if (token.getType() != Token::Type_IDENTIFIER) { std::string message = "Expected variable name in while condition, got " + token.classify(); notify(Error::ErrorInfo(message, token)); if (token.getType() != Token::Type_SEMICOLON) restoreScannerState(); return; } if (!ASTInterpreter::isVariableSupported(token.getValue())) { notify(Error::ErrorInfo("Variable not supported", token)); restoreScannerState(); return; } node.setVarName(token.getValue()); token = m_scanner->scan(); if (token.getType() != Token::Type_RBRACKET) { std::string message = "Expected ')' in while condition, got " + token.classify(); notify(Error::ErrorInfo(message, token)); if (token.getType() != Token::Type_SEMICOLON) restoreScannerState(); return; } token = m_scanner->scan(); if (token.getType() != Token::Type_IDENTIFIER) { std::string message = "Expected statement after while, got " + token.classify(); notify(Error::ErrorInfo(message, token)); if (token.getType() != Token::Type_SEMICOLON) restoreScannerState(); return; } StmtPtr stmt = visitStatement(token); if (stmt && (stmt->isValid())) { node.statement() = stmt; } }