static bool runOnBlock(const CFGBlock *block, const CFG &cfg, AnalysisDeclContext &ac, CFGBlockValues &vals, llvm::BitVector &wasAnalyzed, UninitVariablesHandler *handler = 0) { wasAnalyzed[block->getBlockID()] = true; if (const BinaryOperator *b = getLogicalOperatorInChain(block)) { CFGBlock::const_pred_iterator itr = block->pred_begin(); BVPair vA = vals.getValueVectors(*itr, false); ++itr; BVPair vB = vals.getValueVectors(*itr, false); BVPair valsAB; if (b->getOpcode() == BO_LAnd) { // Merge the 'F' bits from the first and second. vals.mergeIntoScratch(*(vA.second ? vA.second : vA.first), true); vals.mergeIntoScratch(*(vB.second ? vB.second : vB.first), false); valsAB.first = vA.first; valsAB.second = &vals.getScratch(); } else { // Merge the 'T' bits from the first and second. assert(b->getOpcode() == BO_LOr); vals.mergeIntoScratch(*vA.first, true); vals.mergeIntoScratch(*vB.first, false); valsAB.first = &vals.getScratch(); valsAB.second = vA.second ? vA.second : vA.first; } return vals.updateValueVectors(block, valsAB); } // Default behavior: merge in values of predecessor blocks. vals.resetScratch(); bool isFirst = true; for (CFGBlock::const_pred_iterator I = block->pred_begin(), E = block->pred_end(); I != E; ++I) { const CFGBlock *pred = *I; if (wasAnalyzed[pred->getBlockID()]) { vals.mergeIntoScratch(vals.getValueVector(pred, block), isFirst); isFirst = false; } } // Apply the transfer function. TransferFunctions tf(vals, cfg, ac, handler); for (CFGBlock::const_iterator I = block->begin(), E = block->end(); I != E; ++I) { if (const CFGStmt *cs = dyn_cast<CFGStmt>(&*I)) { tf.Visit(const_cast<Stmt*>(cs->getStmt())); } } tf.ProcessUses(); return vals.updateValueVectorWithScratch(block); }