diff options
| author | Mike Stump <mrs@apple.com> | 2009-07-17 01:31:16 +0000 | 
|---|---|---|
| committer | Mike Stump <mrs@apple.com> | 2009-07-17 01:31:16 +0000 | 
| commit | 31feda55853398ed4e5eac69a4c6c5ee5bcd5b94 (patch) | |
| tree | 94b4947458111c78943c359fe19cfa2e70ae143e /clang/lib/Analysis | |
| parent | b825c0ddc510d8aa0cce9b4065cb8e5dace6bc39 (diff) | |
| download | bcm5719-llvm-31feda55853398ed4e5eac69a4c6c5ee5bcd5b94.tar.gz bcm5719-llvm-31feda55853398ed4e5eac69a4c6c5ee5bcd5b94.zip  | |
Fixup indentation of rest of switch statement to match llvm coding
conventions.  Also reflowed comments and removed spaces at end of
lines and fixed up 80 col violations.
llvm-svn: 76140
Diffstat (limited to 'clang/lib/Analysis')
| -rw-r--r-- | clang/lib/Analysis/CFG.cpp | 1357 | 
1 files changed, 667 insertions, 690 deletions
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index c77f8cebda0..884bc177fdc 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -38,15 +38,15 @@ struct VISIBILITY_HIDDEN SaveAndRestore {    T& X;    T old_value;  }; -   +  static SourceLocation GetEndLoc(Decl* D) {    if (VarDecl* VD = dyn_cast<VarDecl>(D))      if (Expr* Ex = VD->getInit())        return Ex->getSourceRange().getEnd(); -   -  return D->getLocation();   + +  return D->getLocation();  } -   +  /// CFGBuilder - This class implements CFG construction from an AST.  ///   The builder is stateful: an instance of the builder should be used to only  ///   construct a single CFG. @@ -56,13 +56,12 @@ static SourceLocation GetEndLoc(Decl* D) {  ///     CFGBuilder builder;  ///     CFG* cfg = builder.BuildAST(stmt1);  /// -///  CFG construction is done via a recursive walk of an AST. -///  We actually parse the AST in reverse order so that the successor -///  of a basic block is constructed prior to its predecessor.  This -///  allows us to nicely capture implicit fall-throughs without extra -///  basic blocks. +///  CFG construction is done via a recursive walk of an AST.  We actually parse +///  the AST in reverse order so that the successor of a basic block is +///  constructed prior to its predecessor.  This allows us to nicely capture +///  implicit fall-throughs without extra basic blocks.  /// -class VISIBILITY_HIDDEN CFGBuilder : public StmtVisitor<CFGBuilder,CFGBlock*> {     +class VISIBILITY_HIDDEN CFGBuilder : public StmtVisitor<CFGBuilder,CFGBlock*> {    CFG* cfg;    CFGBlock* Block;    CFGBlock* Succ; @@ -70,36 +69,36 @@ class VISIBILITY_HIDDEN CFGBuilder : public StmtVisitor<CFGBuilder,CFGBlock*> {    CFGBlock* BreakTargetBlock;    CFGBlock* SwitchTerminatedBlock;    CFGBlock* DefaultCaseBlock; -   +    // LabelMap records the mapping from Label expressions to their blocks.    typedef llvm::DenseMap<LabelStmt*,CFGBlock*> LabelMapTy;    LabelMapTy LabelMap; -   -  // A list of blocks that end with a "goto" that must be backpatched to -  // their resolved targets upon completion of CFG construction. + +  // A list of blocks that end with a "goto" that must be backpatched to their +  // resolved targets upon completion of CFG construction.    typedef std::vector<CFGBlock*> BackpatchBlocksTy;    BackpatchBlocksTy BackpatchBlocks; -   +    // A list of labels whose address has been taken (for indirect gotos).    typedef llvm::SmallPtrSet<LabelStmt*,5> LabelSetTy;    LabelSetTy AddressTakenLabels; -   -public:   + +public:    explicit CFGBuilder() : cfg(NULL), Block(NULL), Succ(NULL),                            ContinueTargetBlock(NULL), BreakTargetBlock(NULL),                            SwitchTerminatedBlock(NULL), DefaultCaseBlock(NULL) {      // Create an empty CFG. -    cfg = new CFG();                         +    cfg = new CFG();    } -   +    ~CFGBuilder() { delete cfg; } -   +    // buildCFG - Used by external clients to construct the CFG.    CFG* buildCFG(Stmt* Statement); -   -  // Visitors to walk an AST and construct the CFG.  Called by -  // buildCFG.  Do not call directly! -   + +  // Visitors to walk an AST and construct the CFG.  Called by buildCFG.  Do not +  // call directly! +    CFGBlock* VisitBreakStmt(BreakStmt* B);    CFGBlock* VisitCaseStmt(CaseStmt* Terminator);    CFGBlock* VisitCompoundStmt(CompoundStmt* C); @@ -125,24 +124,24 @@ public:      badCFG = true;      return Block;    } -   +    CFGBlock* VisitObjCAtTryStmt(ObjCAtTryStmt* S); -  CFGBlock* VisitObjCAtCatchStmt(ObjCAtCatchStmt* S) {  -    // FIXME: For now we pretend that @catch and the code it contains -    //  does not exit. +  CFGBlock* VisitObjCAtCatchStmt(ObjCAtCatchStmt* S) { +    // FIXME: For now we pretend that @catch and the code it contains does not +    //  exit.      return Block;    } -  // FIXME: This is not completely supported.  We basically @throw like -  // a 'return'. +  // FIXME: This is not completely supported.  We basically @throw like a +  // 'return'.    CFGBlock* VisitObjCAtThrowStmt(ObjCAtThrowStmt* S);    CFGBlock* VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt* S); -   +    // Blocks.    CFGBlock* VisitBlockExpr(BlockExpr* E) { return NYS(); } -  CFGBlock* VisitBlockDeclRefExpr(BlockDeclRefExpr* E) { return NYS(); }   -   +  CFGBlock* VisitBlockDeclRefExpr(BlockDeclRefExpr* E) { return NYS(); } +  private:    CFGBlock* createBlock(bool add_successor = true);    CFGBlock* addStmt(Stmt* Terminator); @@ -151,10 +150,10 @@ private:    CFGBlock* WalkAST_VisitDeclSubExpr(Decl* D);    CFGBlock* WalkAST_VisitStmtExpr(StmtExpr* Terminator);    bool FinishBlock(CFGBlock* B); -   +    bool badCFG;  }; -   +  // FIXME: Add support for dependent-sized array types in C++?  // Does it even make sense to build a CFG for an uninstantiated template?  static VariableArrayType* FindVA(Type* t) { @@ -162,45 +161,45 @@ static VariableArrayType* FindVA(Type* t) {      if (VariableArrayType* vat = dyn_cast<VariableArrayType>(vt))        if (vat->getSizeExpr())          return vat; -     +      t = vt->getElementType().getTypePtr();    } -   +    return 0;  } -     -/// BuildCFG - Constructs a CFG from an AST (a Stmt*).  The AST can -///  represent an arbitrary statement.  Examples include a single expression -///  or a function body (compound statement).  The ownership of the returned -///  CFG is transferred to the caller.  If CFG construction fails, this method -///  returns NULL. + +/// BuildCFG - Constructs a CFG from an AST (a Stmt*).  The AST can represent an +///  arbitrary statement.  Examples include a single expression or a function +///  body (compound statement).  The ownership of the returned CFG is +///  transferred to the caller.  If CFG construction fails, this method returns +///  NULL.  CFG* CFGBuilder::buildCFG(Stmt* Statement) {    assert (cfg);    if (!Statement) return NULL;    badCFG = false; -   -  // Create an empty block that will serve as the exit block for the CFG. -  // Since this is the first block added to the CFG, it will be implicitly -  // registered as the exit block. + +  // Create an empty block that will serve as the exit block for the CFG.  Since +  // this is the first block added to the CFG, it will be implicitly registered +  // as the exit block.    Succ = createBlock();    assert (Succ == &cfg->getExit());    Block = NULL;  // the EXIT block is empty.  Create all other blocks lazily. -   +    // Visit the statements and create the CFG.    CFGBlock* B = Visit(Statement);    if (!B) B = Succ; -   +    if (B) { -    // Finalize the last constructed block.  This usually involves -    // reversing the order of the statements in the block. +    // Finalize the last constructed block.  This usually involves reversing the +    // order of the statements in the block.      if (Block) FinishBlock(B); -     -    // Backpatch the gotos whose label -> block mappings we didn't know -    // when we encountered them. -    for (BackpatchBlocksTy::iterator I = BackpatchBlocks.begin(),  + +    // Backpatch the gotos whose label -> block mappings we didn't know when we +    // encountered them. +    for (BackpatchBlocksTy::iterator I = BackpatchBlocks.begin(),           E = BackpatchBlocks.end(); I != E; ++I ) { -      +        CFGBlock* B = *I;        GotoStmt* G = cast<GotoStmt>(B->getTerminator());        LabelMapTy::iterator LI = LabelMap.find(G->getLabel()); @@ -208,10 +207,10 @@ CFG* CFGBuilder::buildCFG(Stmt* Statement) {        // If there is no target for the goto, then we are looking at an        // incomplete AST.  Handle this by not registering a successor.        if (LI == LabelMap.end()) continue; -       -      B->addSuccessor(LI->second);                    + +      B->addSuccessor(LI->second);      } -     +      // Add successors to the Indirect Goto Dispatch block (if we have one).      if (CFGBlock* B = cfg->getIndirectGotoBlock())        for (LabelSetTy::iterator I = AddressTakenLabels.begin(), @@ -223,40 +222,39 @@ CFG* CFGBuilder::buildCFG(Stmt* Statement) {          // If there is no target block that contains label, then we are looking          // at an incomplete AST.  Handle this by not registering a successor.          if (LI == LabelMap.end()) continue; -         -        B->addSuccessor(LI->second);            + +        B->addSuccessor(LI->second);        } -                                                           +      Succ = B;    } -   -  // Create an empty entry block that has no predecessors.     + +  // Create an empty entry block that has no predecessors.    cfg->setEntry(createBlock()); -     +    if (badCFG) {      delete cfg;      cfg = NULL;      return NULL;    } -     -  // NULL out cfg so that repeated calls to the builder will fail and that -  // the ownership of the constructed CFG is passed to the caller. + +  // NULL out cfg so that repeated calls to the builder will fail and that the +  // ownership of the constructed CFG is passed to the caller.    CFG* t = cfg;    cfg = NULL;    return t;  } -   +  /// createBlock - Used to lazily create blocks that are connected  ///  to the current (global) succcessor. -CFGBlock* CFGBuilder::createBlock(bool add_successor) {  +CFGBlock* CFGBuilder::createBlock(bool add_successor) {    CFGBlock* B = cfg->createBlock();    if (add_successor && Succ) B->addSuccessor(Succ);    return B;  } -   -/// FinishBlock - When the last statement has been added to the block, -///  we must reverse the statements because they have been inserted -///  in reverse order. + +/// FinishBlock - When the last statement has been added to the block, we must +///  reverse the statements because they have been inserted in reverse order.  bool CFGBuilder::FinishBlock(CFGBlock* B) {    if (badCFG)      return false; @@ -266,218 +264,214 @@ bool CFGBuilder::FinishBlock(CFGBlock* B) {    return true;  } -/// addStmt - Used to add statements/expressions to the current CFGBlock  +/// addStmt - Used to add statements/expressions to the current CFGBlock  ///  "Block".  This method calls WalkAST on the passed statement to see if it -///  contains any short-circuit expressions.  If so, it recursively creates -///  the necessary blocks for such expressions.  It returns the "topmost" block -///  of the created blocks, or the original value of "Block" when this method -///  was called if no additional blocks are created. +///  contains any short-circuit expressions.  If so, it recursively creates the +///  necessary blocks for such expressions.  It returns the "topmost" block of +///  the created blocks, or the original value of "Block" when this method was +///  called if no additional blocks are created.  CFGBlock* CFGBuilder::addStmt(Stmt* Terminator) {    if (!Block) Block = createBlock();    return WalkAST(Terminator,true);  } -/// WalkAST - Used by addStmt to walk the subtree of a statement and -///   add extra blocks for ternary operators, &&, and ||.  We also -///   process "," and DeclStmts (which may contain nested control-flow). +/// WalkAST - Used by addStmt to walk the subtree of a statement and add extra +///   blocks for ternary operators, &&, and ||.  We also process "," and +///   DeclStmts (which may contain nested control-flow).  CFGBlock* CFGBuilder::WalkAST(Stmt* Terminator, bool AlwaysAddStmt = false) {    switch (Terminator->getStmtClass()) { -    case Stmt::ConditionalOperatorClass: { -      ConditionalOperator* C = cast<ConditionalOperator>(Terminator); +  case Stmt::ConditionalOperatorClass: { +    ConditionalOperator* C = cast<ConditionalOperator>(Terminator); + +    // Create the confluence block that will "merge" the results of the ternary +    // expression. +    CFGBlock* ConfluenceBlock = (Block) ? Block : createBlock(); +    ConfluenceBlock->appendStmt(C); +    if (!FinishBlock(ConfluenceBlock)) +      return 0; -      // Create the confluence block that will "merge" the results -      // of the ternary expression. -      CFGBlock* ConfluenceBlock = (Block) ? Block : createBlock();   -      ConfluenceBlock->appendStmt(C); -      if (!FinishBlock(ConfluenceBlock)) +    // Create a block for the LHS expression if there is an LHS expression.  A +    // GCC extension allows LHS to be NULL, causing the condition to be the +    // value that is returned instead. +    //  e.g: x ?: y is shorthand for: x ? x : y; +    Succ = ConfluenceBlock; +    Block = NULL; +    CFGBlock* LHSBlock = NULL; +    if (C->getLHS()) { +      LHSBlock = Visit(C->getLHS()); +      if (!FinishBlock(LHSBlock))          return 0; - -      // Create a block for the LHS expression if there is an LHS expression. -      // A GCC extension allows LHS to be NULL, causing the condition to -      // be the value that is returned instead. -      //  e.g: x ?: y is shorthand for: x ? x : y; -      Succ = ConfluenceBlock;        Block = NULL; -      CFGBlock* LHSBlock = NULL; -      if (C->getLHS()) { -        LHSBlock = Visit(C->getLHS()); -        if (!FinishBlock(LHSBlock)) -          return 0; -        Block = NULL;         -      } -       -      // Create the block for the RHS expression. -      Succ = ConfluenceBlock; -      CFGBlock* RHSBlock = Visit(C->getRHS()); -      if (!FinishBlock(RHSBlock)) -        return 0; +    } -      // Create the block that will contain the condition. -      Block = createBlock(false); -       -      if (LHSBlock) -        Block->addSuccessor(LHSBlock); -      else { -        // If we have no LHS expression, add the ConfluenceBlock as a direct -        // successor for the block containing the condition.  Moreover, -        // we need to reverse the order of the predecessors in the -        // ConfluenceBlock because the RHSBlock will have been added to -        // the succcessors already, and we want the first predecessor to the -        // the block containing the expression for the case when the ternary -        // expression evaluates to true. -        Block->addSuccessor(ConfluenceBlock); -        assert (ConfluenceBlock->pred_size() == 2); -        std::reverse(ConfluenceBlock->pred_begin(),  -                     ConfluenceBlock->pred_end()); -      } -       -      Block->addSuccessor(RHSBlock); -       -      Block->setTerminator(C); -      return addStmt(C->getCond()); +    // Create the block for the RHS expression. +    Succ = ConfluenceBlock; +    CFGBlock* RHSBlock = Visit(C->getRHS()); +    if (!FinishBlock(RHSBlock)) +      return 0; + +    // Create the block that will contain the condition. +    Block = createBlock(false); + +    if (LHSBlock) +      Block->addSuccessor(LHSBlock); +    else { +      // If we have no LHS expression, add the ConfluenceBlock as a direct +      // successor for the block containing the condition.  Moreover, we need to +      // reverse the order of the predecessors in the ConfluenceBlock because +      // the RHSBlock will have been added to the succcessors already, and we +      // want the first predecessor to the the block containing the expression +      // for the case when the ternary expression evaluates to true. +      Block->addSuccessor(ConfluenceBlock); +      assert (ConfluenceBlock->pred_size() == 2); +      std::reverse(ConfluenceBlock->pred_begin(), +                   ConfluenceBlock->pred_end()); +    } + +    Block->addSuccessor(RHSBlock); + +    Block->setTerminator(C); +    return addStmt(C->getCond()); +  } + +  case Stmt::ChooseExprClass: { +    ChooseExpr* C = cast<ChooseExpr>(Terminator); + +    CFGBlock* ConfluenceBlock = Block ? Block : createBlock(); +    ConfluenceBlock->appendStmt(C); +    if (!FinishBlock(ConfluenceBlock)) +      return 0; + +    Succ = ConfluenceBlock; +    Block = NULL; +    CFGBlock* LHSBlock = Visit(C->getLHS()); +    if (!FinishBlock(LHSBlock)) +      return 0; + +    Succ = ConfluenceBlock; +    Block = NULL; +    CFGBlock* RHSBlock = Visit(C->getRHS()); +    if (!FinishBlock(RHSBlock)) +      return 0; + +    Block = createBlock(false); +    Block->addSuccessor(LHSBlock); +    Block->addSuccessor(RHSBlock); +    Block->setTerminator(C); +    return addStmt(C->getCond()); +  } + +  case Stmt::DeclStmtClass: { +    DeclStmt *DS = cast<DeclStmt>(Terminator); +    if (DS->isSingleDecl()) { +      Block->appendStmt(Terminator); +      return WalkAST_VisitDeclSubExpr(DS->getSingleDecl());      } -     -    case Stmt::ChooseExprClass: { -      ChooseExpr* C = cast<ChooseExpr>(Terminator);       -       -      CFGBlock* ConfluenceBlock = Block ? Block : createBlock();   -      ConfluenceBlock->appendStmt(C); + +    CFGBlock* B = 0; + +    // FIXME: Add a reverse iterator for DeclStmt to avoid this extra copy. +    typedef llvm::SmallVector<Decl*,10> BufTy; +    BufTy Buf(DS->decl_begin(), DS->decl_end()); + +    for (BufTy::reverse_iterator I=Buf.rbegin(), E=Buf.rend(); I!=E; ++I) { +      // Get the alignment of the new DeclStmt, padding out to >=8 bytes. +      unsigned A = llvm::AlignOf<DeclStmt>::Alignment < 8 +                   ? 8 : llvm::AlignOf<DeclStmt>::Alignment; + +      // Allocate the DeclStmt using the BumpPtrAllocator.  It will get +      // automatically freed with the CFG. +      DeclGroupRef DG(*I); +      Decl* D = *I; +      void* Mem = cfg->getAllocator().Allocate(sizeof(DeclStmt), A); + +      DeclStmt* DS = new (Mem) DeclStmt(DG, D->getLocation(), GetEndLoc(D)); + +      // Append the fake DeclStmt to block. +      Block->appendStmt(DS); +      B = WalkAST_VisitDeclSubExpr(D); +    } +    return B; +  } + +  case Stmt::AddrLabelExprClass: { +    AddrLabelExpr* A = cast<AddrLabelExpr>(Terminator); +    AddressTakenLabels.insert(A->getLabel()); + +    if (AlwaysAddStmt) Block->appendStmt(Terminator); +    return Block; +  } + +  case Stmt::StmtExprClass: +    return WalkAST_VisitStmtExpr(cast<StmtExpr>(Terminator)); + +  case Stmt::SizeOfAlignOfExprClass: { +    SizeOfAlignOfExpr* E = cast<SizeOfAlignOfExpr>(Terminator); + +    // VLA types have expressions that must be evaluated. +    if (E->isArgumentType()) { +      for (VariableArrayType* VA = FindVA(E->getArgumentType().getTypePtr()); +           VA != 0; VA = FindVA(VA->getElementType().getTypePtr())) +        addStmt(VA->getSizeExpr()); +    } +    // Expressions in sizeof/alignof are not evaluated and thus have no +    // control flow. +    else +      Block->appendStmt(Terminator); + +    return Block; +  } + +  case Stmt::BinaryOperatorClass: { +    BinaryOperator* B = cast<BinaryOperator>(Terminator); + +    if (B->isLogicalOp()) { // && or || +      CFGBlock* ConfluenceBlock = (Block) ? Block : createBlock(); +      ConfluenceBlock->appendStmt(B);        if (!FinishBlock(ConfluenceBlock))          return 0; -       -      Succ = ConfluenceBlock; -      Block = NULL; -      CFGBlock* LHSBlock = Visit(C->getLHS()); -      if (!FinishBlock(LHSBlock)) -        return 0; +      // create the block evaluating the LHS +      CFGBlock* LHSBlock = createBlock(false); +      LHSBlock->setTerminator(B); + +      // create the block evaluating the RHS        Succ = ConfluenceBlock;        Block = NULL; -      CFGBlock* RHSBlock = Visit(C->getRHS()); +      CFGBlock* RHSBlock = Visit(B->getRHS());        if (!FinishBlock(RHSBlock))          return 0; -       -      Block = createBlock(false); -      Block->addSuccessor(LHSBlock); -      Block->addSuccessor(RHSBlock); -      Block->setTerminator(C); -      return addStmt(C->getCond()); -    } -    case Stmt::DeclStmtClass: { -      DeclStmt *DS = cast<DeclStmt>(Terminator);       -      if (DS->isSingleDecl()) {       -        Block->appendStmt(Terminator); -        return WalkAST_VisitDeclSubExpr(DS->getSingleDecl()); +      // Now link the LHSBlock with RHSBlock. +      if (B->getOpcode() == BinaryOperator::LOr) { +        LHSBlock->addSuccessor(ConfluenceBlock); +        LHSBlock->addSuccessor(RHSBlock); +      } else { +        assert (B->getOpcode() == BinaryOperator::LAnd); +        LHSBlock->addSuccessor(RHSBlock); +        LHSBlock->addSuccessor(ConfluenceBlock);        } -       -      CFGBlock* B = 0; - -      // FIXME: Add a reverse iterator for DeclStmt to avoid this -      // extra copy. -      typedef llvm::SmallVector<Decl*,10> BufTy; -      BufTy Buf(DS->decl_begin(), DS->decl_end()); -       -      for (BufTy::reverse_iterator I=Buf.rbegin(), E=Buf.rend(); I!=E; ++I) { -        // Get the alignment of the new DeclStmt, padding out to >=8 bytes. -        unsigned A = llvm::AlignOf<DeclStmt>::Alignment < 8 -                     ? 8 : llvm::AlignOf<DeclStmt>::Alignment; -         -        // Allocate the DeclStmt using the BumpPtrAllocator.  It will -        // get automatically freed with the CFG.  -        DeclGroupRef DG(*I); -        Decl* D = *I; -        void* Mem = cfg->getAllocator().Allocate(sizeof(DeclStmt), A); -         -        DeclStmt* DS = new (Mem) DeclStmt(DG, D->getLocation(), GetEndLoc(D)); -         -        // Append the fake DeclStmt to block. -        Block->appendStmt(DS); -        B = WalkAST_VisitDeclSubExpr(D); -      } -      return B; -    } -    case Stmt::AddrLabelExprClass: { -      AddrLabelExpr* A = cast<AddrLabelExpr>(Terminator); -      AddressTakenLabels.insert(A->getLabel()); -       -      if (AlwaysAddStmt) Block->appendStmt(Terminator); -      return Block; +      // Generate the blocks for evaluating the LHS. +      Block = LHSBlock; +      return addStmt(B->getLHS()); +    } else if (B->getOpcode() == BinaryOperator::Comma) { // , +      Block->appendStmt(B); +      addStmt(B->getRHS()); +      return addStmt(B->getLHS());      } -     -    case Stmt::StmtExprClass: -      return WalkAST_VisitStmtExpr(cast<StmtExpr>(Terminator)); - -    case Stmt::SizeOfAlignOfExprClass: { -      SizeOfAlignOfExpr* E = cast<SizeOfAlignOfExpr>(Terminator); - -      // VLA types have expressions that must be evaluated. -      if (E->isArgumentType()) { -        for (VariableArrayType* VA = FindVA(E->getArgumentType().getTypePtr()); -             VA != 0; VA = FindVA(VA->getElementType().getTypePtr())) -          addStmt(VA->getSizeExpr()); -      } -      // Expressions in sizeof/alignof are not evaluated and thus have no -      // control flow. -      else -        Block->appendStmt(Terminator); -      return Block; -    } -       -    case Stmt::BinaryOperatorClass: { -      BinaryOperator* B = cast<BinaryOperator>(Terminator); - -      if (B->isLogicalOp()) { // && or || -        CFGBlock* ConfluenceBlock = (Block) ? Block : createBlock();   -        ConfluenceBlock->appendStmt(B); -        if (!FinishBlock(ConfluenceBlock)) -          return 0; - -        // create the block evaluating the LHS -        CFGBlock* LHSBlock = createBlock(false); -        LHSBlock->setTerminator(B); -         -        // create the block evaluating the RHS -        Succ = ConfluenceBlock; -        Block = NULL; -        CFGBlock* RHSBlock = Visit(B->getRHS()); -        if (!FinishBlock(RHSBlock)) -          return 0; - -        // Now link the LHSBlock with RHSBlock. -        if (B->getOpcode() == BinaryOperator::LOr) { -          LHSBlock->addSuccessor(ConfluenceBlock); -          LHSBlock->addSuccessor(RHSBlock); -        } -        else { -          assert (B->getOpcode() == BinaryOperator::LAnd); -          LHSBlock->addSuccessor(RHSBlock); -          LHSBlock->addSuccessor(ConfluenceBlock); -        } -         -        // Generate the blocks for evaluating the LHS. -        Block = LHSBlock; -        return addStmt(B->getLHS());                                     -      } -      else if (B->getOpcode() == BinaryOperator::Comma) { // , -        Block->appendStmt(B); -        addStmt(B->getRHS()); -        return addStmt(B->getLHS()); -      } -       -      break; -    } -     +    break; +  } +      // Blocks: No support for blocks ... yet -    case Stmt::BlockExprClass: -    case Stmt::BlockDeclRefExprClass: -      return NYS(); -       -    case Stmt::ParenExprClass: -      return WalkAST(cast<ParenExpr>(Terminator)->getSubExpr(), AlwaysAddStmt); -     +  case Stmt::BlockExprClass: +  case Stmt::BlockDeclRefExprClass: +    return NYS(); + +  case Stmt::ParenExprClass: +    return WalkAST(cast<ParenExpr>(Terminator)->getSubExpr(), AlwaysAddStmt); +    case Stmt::CallExprClass: {      bool NoReturn = false;      CallExpr *C = cast<CallExpr>(Terminator); @@ -508,24 +502,24 @@ CFGBlock* CFGBuilder::WalkAST(Stmt* Terminator, bool AlwaysAddStmt = false) {      return WalkAST_VisitChildren(Terminator);    } -    default: -      break; +  default: +    break;    }; -       +    if (AlwaysAddStmt) Block->appendStmt(Terminator);    return WalkAST_VisitChildren(Terminator);  } -   -/// WalkAST_VisitDeclSubExpr - Utility method to add block-level expressions -///  for initializers in Decls. + +/// WalkAST_VisitDeclSubExpr - Utility method to add block-level expressions for +///  initializers in Decls.  CFGBlock* CFGBuilder::WalkAST_VisitDeclSubExpr(Decl* D) {    VarDecl* VD = dyn_cast<VarDecl>(D);    if (!VD)      return Block; -   +    Expr* Init = VD->getInit(); -   +    if (Init) {      // Optimization: Don't create separate block-level statements for literals.      switch (Init->getStmtClass()) { @@ -537,24 +531,24 @@ CFGBlock* CFGBuilder::WalkAST_VisitDeclSubExpr(Decl* D) {          Block = addStmt(Init);      }    } -     +    // If the type of VD is a VLA, then we must process its size expressions.    for (VariableArrayType* VA = FindVA(VD->getType().getTypePtr()); VA != 0;         VA = FindVA(VA->getElementType().getTypePtr())) -    Block = addStmt(VA->getSizeExpr());   -   +    Block = addStmt(VA->getSizeExpr()); +    return Block;  } -/// WalkAST_VisitChildren - Utility method to call WalkAST on the -///  children of a Stmt. +/// WalkAST_VisitChildren - Utility method to call WalkAST on the children of a +///  Stmt.  CFGBlock* CFGBuilder::WalkAST_VisitChildren(Stmt* Terminator) {    CFGBlock* B = Block;    for (Stmt::child_iterator I = Terminator->child_begin(),           E = Terminator->child_end();         I != E; ++I)      if (*I) B = WalkAST(*I); -   +    return B;  } @@ -562,19 +556,19 @@ CFGBlock* CFGBuilder::WalkAST_VisitChildren(Stmt* Terminator) {  ///  expressions (a GCC extension).  CFGBlock* CFGBuilder::WalkAST_VisitStmtExpr(StmtExpr* Terminator) {    Block->appendStmt(Terminator); -  return VisitCompoundStmt(Terminator->getSubStmt());   +  return VisitCompoundStmt(Terminator->getSubStmt());  }  /// VisitStmt - Handle statements with no branching control flow.  CFGBlock* CFGBuilder::VisitStmt(Stmt* Statement) { -  // We cannot assume that we are in the middle of a basic block, since -  // the CFG might only be constructed for this single statement.  If -  // we have no current basic block, just create one lazily. +  // We cannot assume that we are in the middle of a basic block, since the CFG +  // might only be constructed for this single statement.  If we have no current +  // basic block, just create one lazily.    if (!Block) Block = createBlock(); -   -  // Simply add the statement to the current block.  We actually -  // insert statements in reverse order; this order is reversed later -  // when processing the containing element in the AST. + +  // Simply add the statement to the current block.  We actually insert +  // statements in reverse order; this order is reversed later when processing +  // the containing element in the AST.    addStmt(Statement);    return Block; @@ -585,7 +579,7 @@ CFGBlock* CFGBuilder::VisitNullStmt(NullStmt* Statement) {  }  CFGBlock* CFGBuilder::VisitCompoundStmt(CompoundStmt* C) { -   +    CFGBlock* LastBlock = Block;    for (CompoundStmt::reverse_body_iterator I=C->body_rbegin(), E=C->body_rend(); @@ -597,35 +591,35 @@ CFGBlock* CFGBuilder::VisitCompoundStmt(CompoundStmt* C) {  }  CFGBlock* CFGBuilder::VisitIfStmt(IfStmt* I) { -  // We may see an if statement in the middle of a basic block, or -  // it may be the first statement we are processing.  In either case, -  // we create a new basic block.  First, we create the blocks for -  // the then...else statements, and then we create the block containing -  // the if statement.  If we were in the middle of a block, we -  // stop processing that block and reverse its statements.  That block -  // is then the implicit successor for the "then" and "else" clauses. -   -  // The block we were proccessing is now finished.  Make it the -  // successor block. -  if (Block) {  +  // We may see an if statement in the middle of a basic block, or it may be the +  // first statement we are processing.  In either case, we create a new basic +  // block.  First, we create the blocks for the then...else statements, and +  // then we create the block containing the if statement.  If we were in the +  // middle of a block, we stop processing that block and reverse its +  // statements.  That block is then the implicit successor for the "then" and +  // "else" clauses. + +  // The block we were proccessing is now finished.  Make it the successor +  // block. +  if (Block) {      Succ = Block;      if (!FinishBlock(Block))        return 0;    } -   -  // Process the false branch.  NULL out Block so that the recursive -  // call to Visit will create a new basic block. + +  // Process the false branch.  NULL out Block so that the recursive call to +  // Visit will create a new basic block.    // Null out Block so that all successor    CFGBlock* ElseBlock = Succ; -   +    if (Stmt* Else = I->getElse()) {      SaveAndRestore<CFGBlock*> sv(Succ); -     +      // NULL out Block so that the recursive call to Visit will -    // create a new basic block.           +    // create a new basic block.      Block = NULL;      ElseBlock = Visit(Else); -               +      if (!ElseBlock) // Can occur when the Else body has all NullStmts.        ElseBlock = sv.get();      else if (Block) { @@ -633,67 +627,65 @@ CFGBlock* CFGBuilder::VisitIfStmt(IfStmt* I) {          return 0;      }    } -   -  // Process the true branch.  NULL out Block so that the recursive -  // call to Visit will create a new basic block. + +  // Process the true branch.  NULL out Block so that the recursive call to +  // Visit will create a new basic block.    // Null out Block so that all successor    CFGBlock* ThenBlock;    {      Stmt* Then = I->getThen();      assert (Then);      SaveAndRestore<CFGBlock*> sv(Succ); -    Block = NULL;         +    Block = NULL;      ThenBlock = Visit(Then); -     +      if (!ThenBlock) {        // We can reach here if the "then" body has all NullStmts.        // Create an empty block so we can distinguish between true and false        // branches in path-sensitive analyses.        ThenBlock = createBlock(false);        ThenBlock->addSuccessor(sv.get()); -    } -    else if (Block) { +    } else if (Block) {        if (!FinishBlock(ThenBlock))          return 0; -    }         +    }    } -  // Now create a new block containing the if statement.         +  // Now create a new block containing the if statement.    Block = createBlock(false); -   +    // Set the terminator of the new block to the If statement.    Block->setTerminator(I); -   +    // Now add the successors.    Block->addSuccessor(ThenBlock);    Block->addSuccessor(ElseBlock); -   -  // Add the condition as the last statement in the new block.  This -  // may create new blocks as the condition may contain control-flow.  Any -  // newly created blocks will be pointed to be "Block". + +  // Add the condition as the last statement in the new block.  This may create +  // new blocks as the condition may contain control-flow.  Any newly created +  // blocks will be pointed to be "Block".    return addStmt(I->getCond()->IgnoreParens());  } -   -     + +  CFGBlock* CFGBuilder::VisitReturnStmt(ReturnStmt* R) { -  // If we were in the middle of a block we stop processing that block -  // and reverse its statements. +  // If we were in the middle of a block we stop processing that block and +  // reverse its statements.    // -  // NOTE: If a "return" appears in the middle of a block, this means -  //       that the code afterwards is DEAD (unreachable).  We still -  //       keep a basic block for that code; a simple "mark-and-sweep" -  //       from the entry block will be able to report such dead -  //       blocks. +  // NOTE: If a "return" appears in the middle of a block, this means that the +  //       code afterwards is DEAD (unreachable).  We still keep a basic block +  //       for that code; a simple "mark-and-sweep" from the entry block will be +  //       able to report such dead blocks.    if (Block) FinishBlock(Block);    // Create the new block.    Block = createBlock(false); -   +    // The Exit block is the only successor.    Block->addSuccessor(&cfg->getExit()); -     -  // Add the return statement to the block.  This may create new blocks -  // if R contains control-flow (short-circuit operations). + +  // Add the return statement to the block.  This may create new blocks if R +  // contains control-flow (short-circuit operations).    return addStmt(R);  } @@ -701,75 +693,72 @@ CFGBlock* CFGBuilder::VisitLabelStmt(LabelStmt* L) {    // Get the block of the labeled statement.  Add it to our map.    Visit(L->getSubStmt());    CFGBlock* LabelBlock = Block; -   +    if (!LabelBlock)            // This can happen when the body is empty, i.e.      LabelBlock=createBlock(); // scopes that only contains NullStmts. -   +    assert (LabelMap.find(L) == LabelMap.end() && "label already in map");    LabelMap[ L ] = LabelBlock; -   -  // Labels partition blocks, so this is the end of the basic block -  // we were processing (L is the block's label).  Because this is -  // label (and we have already processed the substatement) there is no -  // extra control-flow to worry about. + +  // Labels partition blocks, so this is the end of the basic block we were +  // processing (L is the block's label).  Because this is label (and we have +  // already processed the substatement) there is no extra control-flow to worry +  // about.    LabelBlock->setLabel(L);    if (!FinishBlock(LabelBlock))      return 0; -   -  // We set Block to NULL to allow lazy creation of a new block -  // (if necessary); + +  // We set Block to NULL to allow lazy creation of a new block (if necessary);    Block = NULL; -   +    // This block is now the implicit successor of other blocks.    Succ = LabelBlock; -   +    return LabelBlock;  }  CFGBlock* CFGBuilder::VisitGotoStmt(GotoStmt* G) { -  // Goto is a control-flow statement.  Thus we stop processing the -  // current block and create a new one. +  // Goto is a control-flow statement.  Thus we stop processing the current +  // block and create a new one.    if (Block) FinishBlock(Block);    Block = createBlock(false);    Block->setTerminator(G); -   -  // If we already know the mapping to the label block add the -  // successor now. + +  // If we already know the mapping to the label block add the successor now.    LabelMapTy::iterator I = LabelMap.find(G->getLabel()); -   +    if (I == LabelMap.end())      // We will need to backpatch this block later.      BackpatchBlocks.push_back(Block);    else      Block->addSuccessor(I->second); -  return Block;             +  return Block;  }  CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) { -  // "for" is a control-flow statement.  Thus we stop processing the -  // current block. -   +  // "for" is a control-flow statement.  Thus we stop processing the current +  // block. +    CFGBlock* LoopSuccessor = NULL; -   +    if (Block) {      if (!FinishBlock(Block))        return 0;      LoopSuccessor = Block; -  } -  else LoopSuccessor = Succ; -   -  // Because of short-circuit evaluation, the condition of the loop -  // can span multiple basic blocks.  Thus we need the "Entry" and "Exit" -  // blocks that evaluate the condition. +  } else LoopSuccessor = Succ; + +  // Because of short-circuit evaluation, the condition of the loop can span +  // multiple basic blocks.  Thus we need the "Entry" and "Exit" blocks that +  // evaluate the condition.    CFGBlock* ExitConditionBlock = createBlock(false);    CFGBlock* EntryConditionBlock = ExitConditionBlock; -   +    // Set the terminator for the "exit" condition block. -  ExitConditionBlock->setTerminator(F);   -   -  // Now add the actual condition to the condition block.  Because the -  // condition itself may contain control-flow, new blocks may be created. +  ExitConditionBlock->setTerminator(F); + +  // Now add the actual condition to the condition block.  Because the condition +  // itself may contain control-flow, new blocks may be created.    if (Stmt* C = F->getCond()) {      Block = ExitConditionBlock;      EntryConditionBlock = addStmt(C); @@ -779,34 +768,33 @@ CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) {      }    } -  // The condition block is the implicit successor for the loop body as -  // well as any code above the loop. +  // The condition block is the implicit successor for the loop body as well as +  // any code above the loop.    Succ = EntryConditionBlock; -   +    // Now create the loop body.    {      assert (F->getBody()); -     +      // Save the current values for Block, Succ, and continue and break targets      SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ),      save_continue(ContinueTargetBlock), -    save_break(BreakTargetBlock);       -  +    save_break(BreakTargetBlock); +      // Create a new block to contain the (bottom) of the loop body.      Block = NULL; -     +      if (Stmt* I = F->getInc()) { -      // Generate increment code in its own basic block.  This is the target -      // of continue statements. +      // Generate increment code in its own basic block.  This is the target of +      // continue statements.        Succ = Visit(I); -    } -    else { -      // No increment code.  Create a special, empty, block that is used as -      // the target block for "looping back" to the start of the loop. +    } else { +      // No increment code.  Create a special, empty, block that is used as the +      // target block for "looping back" to the start of the loop.        assert(Succ == EntryConditionBlock);        Succ = createBlock();      } -     +      // Finish up the increment (or empty) block if it hasn't been already.      if (Block) {        assert(Block == Succ); @@ -814,45 +802,43 @@ CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) {          return 0;        Block = 0;      } -     +      ContinueTargetBlock = Succ; -     +      // The starting block for the loop increment is the block that should      // represent the 'loop target' for looping back to the start of the loop.      ContinueTargetBlock->setLoopTarget(F);      // All breaks should go to the code following the loop. -    BreakTargetBlock = LoopSuccessor;     -     -    // Now populate the body block, and in the process create new blocks -    // as we walk the body of the loop. -    CFGBlock* BodyBlock = Visit(F->getBody());       +    BreakTargetBlock = LoopSuccessor; + +    // Now populate the body block, and in the process create new blocks as we +    // walk the body of the loop. +    CFGBlock* BodyBlock = Visit(F->getBody());      if (!BodyBlock)        BodyBlock = EntryConditionBlock; // can happen for "for (...;...; ) ;"      else if (Block) {        if (!FinishBlock(BodyBlock))          return 0; -    }       -     +    } +      // This new body block is a successor to our "exit" condition block.      ExitConditionBlock->addSuccessor(BodyBlock);    } -   -  // Link up the condition block with the code that follows the loop. -  // (the false branch). + +  // Link up the condition block with the code that follows the loop.  (the +  // false branch).    ExitConditionBlock->addSuccessor(LoopSuccessor); -   +    // If the loop contains initialization, create a new block for those -  // statements.  This block can also contain statements that precede -  // the loop. +  // statements.  This block can also contain statements that precede the loop.    if (Stmt* I = F->getInit()) {      Block = createBlock();      return addStmt(I); -  } -  else { -    // There is no loop initialization.   We are thus basically a while  -    // loop.  NULL out Block to force lazy block construction. +  } else { +    // There is no loop initialization.  We are thus basically a while loop. +    // NULL out Block to force lazy block construction.      Block = NULL;      Succ = EntryConditionBlock;      return EntryConditionBlock; @@ -887,70 +873,69 @@ CFGBlock* CFGBuilder::VisitObjCForCollectionStmt(ObjCForCollectionStmt* S) {    //    //  becomes:    // -  //   the same with newVariable replaced with existingItem; the binding -  //   works the same except that for one ObjCForCollectionStmt::getElement() -  //   returns a DeclStmt and the other returns a DeclRefExpr. +  //   the same with newVariable replaced with existingItem; the binding works +  //   the same except that for one ObjCForCollectionStmt::getElement() returns +  //   a DeclStmt and the other returns a DeclRefExpr.    // -   +    CFGBlock* LoopSuccessor = 0; -   +    if (Block) {      if (!FinishBlock(Block))        return 0;      LoopSuccessor = Block;      Block = 0; -  } -  else LoopSuccessor = Succ; -   +  } else LoopSuccessor = Succ; +    // Build the condition blocks.    CFGBlock* ExitConditionBlock = createBlock(false);    CFGBlock* EntryConditionBlock = ExitConditionBlock; -   +    // Set the terminator for the "exit" condition block. -  ExitConditionBlock->setTerminator(S);   -   -  // The last statement in the block should be the ObjCForCollectionStmt, -  // which performs the actual binding to 'element' and determines if there -  // are any more items in the collection. +  ExitConditionBlock->setTerminator(S); + +  // The last statement in the block should be the ObjCForCollectionStmt, which +  // performs the actual binding to 'element' and determines if there are any +  // more items in the collection.    ExitConditionBlock->appendStmt(S);    Block = ExitConditionBlock; -   +    // Walk the 'element' expression to see if there are any side-effects.  We -  // generate new blocks as necesary.  We DON'T add the statement by default -  // to the CFG unless it contains control-flow. +  // generate new blocks as necesary.  We DON'T add the statement by default to +  // the CFG unless it contains control-flow.    EntryConditionBlock = WalkAST(S->getElement(), false); -  if (Block) {  +  if (Block) {      if (!FinishBlock(EntryConditionBlock))        return 0;      Block = 0;    } -   -  // The condition block is the implicit successor for the loop body as -  // well as any code above the loop. + +  // The condition block is the implicit successor for the loop body as well as +  // any code above the loop.    Succ = EntryConditionBlock; -   +    // Now create the true branch. -  {  +  {      // Save the current values for Succ, continue and break targets.      SaveAndRestore<CFGBlock*> save_Succ(Succ), -      save_continue(ContinueTargetBlock), save_break(BreakTargetBlock);  -     +      save_continue(ContinueTargetBlock), save_break(BreakTargetBlock); +      BreakTargetBlock = LoopSuccessor; -    ContinueTargetBlock = EntryConditionBlock;   -     +    ContinueTargetBlock = EntryConditionBlock; +      CFGBlock* BodyBlock = Visit(S->getBody()); -     +      if (!BodyBlock)        BodyBlock = EntryConditionBlock; // can happen for "for (X in Y) ;"      else if (Block) {        if (!FinishBlock(BodyBlock))          return 0;      } -                   +      // This new body block is a successor to our "exit" condition block.      ExitConditionBlock->addSuccessor(BodyBlock);    } -   +    // Link up the condition block with the code that follows the loop.    // (the false branch).    ExitConditionBlock->addSuccessor(LoopSuccessor); @@ -958,58 +943,57 @@ CFGBlock* CFGBuilder::VisitObjCForCollectionStmt(ObjCForCollectionStmt* S) {    // Now create a prologue block to contain the collection expression.    Block = createBlock();    return addStmt(S->getCollection()); -}     -   +} +  CFGBlock* CFGBuilder::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt* S) {    // FIXME: Add locking 'primitives' to CFG for @synchronized. -   +    // Inline the body.    CFGBlock *SyncBlock = Visit(S->getSynchBody()); -   +    // The sync body starts its own basic block.  This makes it a little easier    // for diagnostic clients.    if (SyncBlock) {      if (!FinishBlock(SyncBlock))        return 0; -     +      Block = 0;    } -     +    Succ = SyncBlock; -   +    // Inline the sync expression.    return Visit(S->getSynchExpr());  } -   +  CFGBlock* CFGBuilder::VisitObjCAtTryStmt(ObjCAtTryStmt* S) {    return NYS();  }  CFGBlock* CFGBuilder::VisitWhileStmt(WhileStmt* W) { -  // "while" is a control-flow statement.  Thus we stop processing the -  // current block. -   +  // "while" is a control-flow statement.  Thus we stop processing the current +  // block. +    CFGBlock* LoopSuccessor = NULL; -   +    if (Block) {      if (!FinishBlock(Block))        return 0;      LoopSuccessor = Block; -  } -  else LoopSuccessor = Succ; -             -  // Because of short-circuit evaluation, the condition of the loop -  // can span multiple basic blocks.  Thus we need the "Entry" and "Exit" -  // blocks that evaluate the condition. +  } else LoopSuccessor = Succ; + +  // Because of short-circuit evaluation, the condition of the loop can span +  // multiple basic blocks.  Thus we need the "Entry" and "Exit" blocks that +  // evaluate the condition.    CFGBlock* ExitConditionBlock = createBlock(false);    CFGBlock* EntryConditionBlock = ExitConditionBlock; -   +    // Set the terminator for the "exit" condition block.    ExitConditionBlock->setTerminator(W); -   -  // Now add the actual condition to the condition block.  Because the -  // condition itself may contain control-flow, new blocks may be created. -  // Thus we update "Succ" after adding the condition. + +  // Now add the actual condition to the condition block.  Because the condition +  // itself may contain control-flow, new blocks may be created.  Thus we update +  // "Succ" after adding the condition.    if (Stmt* C = W->getCond()) {      Block = ExitConditionBlock;      EntryConditionBlock = addStmt(C); @@ -1019,11 +1003,11 @@ CFGBlock* CFGBuilder::VisitWhileStmt(WhileStmt* W) {          return 0;      }    } -   -  // The condition block is the implicit successor for the loop body as -  // well as any code above the loop. + +  // The condition block is the implicit successor for the loop body as well as +  // any code above the loop.    Succ = EntryConditionBlock; -   +    // Process the loop body.    {      assert(W->getBody()); @@ -1033,94 +1017,92 @@ CFGBlock* CFGBuilder::VisitWhileStmt(WhileStmt* W) {                                save_continue(ContinueTargetBlock),                                save_break(BreakTargetBlock); -    // Create an empty block to represent the transition block for looping -    // back to the head of the loop. +    // Create an empty block to represent the transition block for looping back +    // to the head of the loop.      Block = 0;      assert(Succ == EntryConditionBlock);      Succ = createBlock();      Succ->setLoopTarget(W); -    ContinueTargetBlock = Succ;     -     +    ContinueTargetBlock = Succ; +      // All breaks should go to the code following the loop.      BreakTargetBlock = LoopSuccessor; -     +      // NULL out Block to force lazy instantiation of blocks for the body.      Block = NULL; -     +      // Create the body.  The returned block is the entry to the loop body.      CFGBlock* BodyBlock = Visit(W->getBody()); -     +      if (!BodyBlock)        BodyBlock = EntryConditionBlock; // can happen for "while(...) ;"      else if (Block) {        if (!FinishBlock(BodyBlock))          return 0;      } -     +      // Add the loop body entry as a successor to the condition.      ExitConditionBlock->addSuccessor(BodyBlock);    } -   -  // Link up the condition block with the code that follows the loop. -  // (the false branch). + +  // Link up the condition block with the code that follows the loop.  (the +  // false branch).    ExitConditionBlock->addSuccessor(LoopSuccessor); -   -  // There can be no more statements in the condition block -  // since we loop back to this block.  NULL out Block to force -  // lazy creation of another block. + +  // There can be no more statements in the condition block since we loop back +  // to this block.  NULL out Block to force lazy creation of another block.    Block = NULL; -   +    // Return the condition block, which is the dominating block for the loop.    Succ = EntryConditionBlock;    return EntryConditionBlock;  } -   +  CFGBlock* CFGBuilder::VisitObjCAtThrowStmt(ObjCAtThrowStmt* S) {    // FIXME: This isn't complete.  We basically treat @throw like a return    //  statement. -   -  // If we were in the middle of a block we stop processing that block -  // and reverse its statements. + +  // If we were in the middle of a block we stop processing that block and +  // reverse its statements.    if (Block) {      if (!FinishBlock(Block))        return 0;    } -   +    // Create the new block.    Block = createBlock(false); -   +    // The Exit block is the only successor.    Block->addSuccessor(&cfg->getExit()); -   -  // Add the statement to the block.  This may create new blocks -  // if S contains control-flow (short-circuit operations). + +  // Add the statement to the block.  This may create new blocks if S contains +  // control-flow (short-circuit operations).    return addStmt(S);  }  CFGBlock* CFGBuilder::VisitDoStmt(DoStmt* D) {    // "do...while" is a control-flow statement.  Thus we stop processing the    // current block. -   +    CFGBlock* LoopSuccessor = NULL; -   +    if (Block) {      if (!FinishBlock(Block))        return 0;      LoopSuccessor = Block; -  } -  else LoopSuccessor = Succ; -   -  // Because of short-circuit evaluation, the condition of the loop -  // can span multiple basic blocks.  Thus we need the "Entry" and "Exit" -  // blocks that evaluate the condition. +  } else LoopSuccessor = Succ; + +  // Because of short-circuit evaluation, the condition of the loop can span +  // multiple basic blocks.  Thus we need the "Entry" and "Exit" blocks that +  // evaluate the condition.    CFGBlock* ExitConditionBlock = createBlock(false);    CFGBlock* EntryConditionBlock = ExitConditionBlock; -         +    // Set the terminator for the "exit" condition block. -  ExitConditionBlock->setTerminator(D);   -   -  // Now add the actual condition to the condition block.  Because the -  // condition itself may contain control-flow, new blocks may be created. +  ExitConditionBlock->setTerminator(D); + +  // Now add the actual condition to the condition block.  Because the condition +  // itself may contain control-flow, new blocks may be created.    if (Stmt* C = D->getCond()) {      Block = ExitConditionBlock;      EntryConditionBlock = addStmt(C); @@ -1129,7 +1111,7 @@ CFGBlock* CFGBuilder::VisitDoStmt(DoStmt* D) {          return 0;      }    } -   +    // The condition block is the implicit successor for the loop body.    Succ = EntryConditionBlock; @@ -1137,54 +1119,53 @@ CFGBlock* CFGBuilder::VisitDoStmt(DoStmt* D) {    CFGBlock* BodyBlock = NULL;    {      assert (D->getBody()); -     +      // Save the current values for Block, Succ, and continue and break targets      SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ),      save_continue(ContinueTargetBlock),      save_break(BreakTargetBlock); -     +      // All continues within this loop should go to the condition block      ContinueTargetBlock = EntryConditionBlock; -     +      // All breaks should go to the code following the loop.      BreakTargetBlock = LoopSuccessor; -     +      // NULL out Block to force lazy instantiation of blocks for the body.      Block = NULL; -     +      // Create the body.  The returned block is the entry to the loop body.      BodyBlock = Visit(D->getBody()); -     +      if (!BodyBlock)        BodyBlock = EntryConditionBlock; // can happen for "do ; while(...)"      else if (Block) {        if (!FinishBlock(BodyBlock))          return 0;      } -         +      // Add an intermediate block between the BodyBlock and the -    // ExitConditionBlock to represent the "loop back" transition. -    // Create an empty block to represent the transition block for looping -    // back to the head of the loop. +    // ExitConditionBlock to represent the "loop back" transition.  Create an +    // empty block to represent the transition block for looping back to the +    // head of the loop.      // FIXME: Can we do this more efficiently without adding another block?      Block = NULL;      Succ = BodyBlock;      CFGBlock *LoopBackBlock = createBlock();      LoopBackBlock->setLoopTarget(D); -     +      // Add the loop body entry as a successor to the condition.      ExitConditionBlock->addSuccessor(LoopBackBlock);    } -   +    // Link up the condition block with the code that follows the loop.    // (the false branch).    ExitConditionBlock->addSuccessor(LoopSuccessor); -   -  // There can be no more statements in the body block(s) -  // since we loop back to the body.  NULL out Block to force -  // lazy creation of another block. + +  // There can be no more statements in the body block(s) since we loop back to +  // the body.  NULL out Block to force lazy creation of another block.    Block = NULL; -   +    // Return the loop body, which is the dominating block for the loop.    Succ = BodyBlock;    return BodyBlock; @@ -1197,77 +1178,76 @@ CFGBlock* CFGBuilder::VisitContinueStmt(ContinueStmt* C) {      if (!FinishBlock(Block))        return 0;    } -   +    // Now create a new block that ends with the continue statement.    Block = createBlock(false);    Block->setTerminator(C); -   +    // If there is no target for the continue, then we are looking at an    // incomplete AST.  This means the CFG cannot be constructed.    if (ContinueTargetBlock)      Block->addSuccessor(ContinueTargetBlock);    else      badCFG = true; -   +    return Block;  }  CFGBlock* CFGBuilder::VisitBreakStmt(BreakStmt* B) { -  // "break" is a control-flow statement.  Thus we stop processing the -  // current block. +  // "break" is a control-flow statement.  Thus we stop processing the current +  // block.    if (Block) {      if (!FinishBlock(Block))        return 0;    } -   +    // Now create a new block that ends with the break statement.    Block = createBlock(false);    Block->setTerminator(B); -   -  // If there is no target for the break, then we are looking at an -  // incomplete AST.  This means that the CFG cannot be constructed. + +  // If there is no target for the break, then we are looking at an incomplete +  // AST.  This means that the CFG cannot be constructed.    if (BreakTargetBlock)      Block->addSuccessor(BreakTargetBlock); -  else  +  else      badCFG = true; -  return Block;   +  return Block;  }  CFGBlock* CFGBuilder::VisitSwitchStmt(SwitchStmt* Terminator) { -  // "switch" is a control-flow statement.  Thus we stop processing the -  // current block.     +  // "switch" is a control-flow statement.  Thus we stop processing the current +  // block.    CFGBlock* SwitchSuccessor = NULL; -   +    if (Block) {      if (!FinishBlock(Block))        return 0;      SwitchSuccessor = Block; -  } -  else SwitchSuccessor = Succ; +  } else SwitchSuccessor = Succ;    // Save the current "switch" context.    SaveAndRestore<CFGBlock*> save_switch(SwitchTerminatedBlock),                              save_break(BreakTargetBlock),                              save_default(DefaultCaseBlock); -  // Set the "default" case to be the block after the switch statement. -  // If the switch statement contains a "default:", this value will -  // be overwritten with the block for that code. +  // Set the "default" case to be the block after the switch statement.  If the +  // switch statement contains a "default:", this value will be overwritten with +  // the block for that code.    DefaultCaseBlock = SwitchSuccessor; -   +    // Create a new block that will contain the switch statement.    SwitchTerminatedBlock = createBlock(false); -   +    // Now process the switch body.  The code after the switch is the implicit    // successor.    Succ = SwitchSuccessor;    BreakTargetBlock = SwitchSuccessor; -   -  // When visiting the body, the case statements should automatically get -  // linked up to the switch.  We also don't keep a pointer to the body, -  // since all control-flow from the switch goes to case/default statements. + +  // When visiting the body, the case statements should automatically get linked +  // up to the switch.  We also don't keep a pointer to the body, since all +  // control-flow from the switch goes to case/default statements.    assert (Terminator->getBody() && "switch must contain a non-NULL body");    Block = NULL;    CFGBlock *BodyBlock = Visit(Terminator->getBody()); @@ -1276,83 +1256,81 @@ CFGBlock* CFGBuilder::VisitSwitchStmt(SwitchStmt* Terminator) {        return 0;    } -  // If we have no "default:" case, the default transition is to the -  // code following the switch body. +  // If we have no "default:" case, the default transition is to the code +  // following the switch body.    SwitchTerminatedBlock->addSuccessor(DefaultCaseBlock); -   +    // Add the terminator and condition in the switch block.    SwitchTerminatedBlock->setTerminator(Terminator);    assert (Terminator->getCond() && "switch condition must be non-NULL");    Block = SwitchTerminatedBlock; -   +    return addStmt(Terminator->getCond());  }  CFGBlock* CFGBuilder::VisitCaseStmt(CaseStmt* Terminator) { -  // CaseStmts are essentially labels, so they are the -  // first statement in a block.       +  // CaseStmts are essentially labels, so they are the first statement in a +  // block.    if (Terminator->getSubStmt()) Visit(Terminator->getSubStmt());    CFGBlock* CaseBlock = Block; -  if (!CaseBlock) CaseBlock = createBlock();   -     -  // Cases statements partition blocks, so this is the top of -  // the basic block we were processing (the "case XXX:" is the label). +  if (!CaseBlock) CaseBlock = createBlock(); + +  // Cases statements partition blocks, so this is the top of the basic block we +  // were processing (the "case XXX:" is the label).    CaseBlock->setLabel(Terminator);    if (!FinishBlock(CaseBlock))      return 0; -   -  // Add this block to the list of successors for the block with the -  // switch statement. + +  // Add this block to the list of successors for the block with the switch +  // statement.    assert (SwitchTerminatedBlock);    SwitchTerminatedBlock->addSuccessor(CaseBlock); -   +    // We set Block to NULL to allow lazy creation of a new block (if necessary)    Block = NULL; -   +    // This block is now the implicit successor of other blocks.    Succ = CaseBlock; -   +    return CaseBlock;  } -   +  CFGBlock* CFGBuilder::VisitDefaultStmt(DefaultStmt* Terminator) {    if (Terminator->getSubStmt()) Visit(Terminator->getSubStmt());    DefaultCaseBlock = Block; -  if (!DefaultCaseBlock) DefaultCaseBlock = createBlock();   -   -  // Default statements partition blocks, so this is the top of -  // the basic block we were processing (the "default:" is the label). +  if (!DefaultCaseBlock) DefaultCaseBlock = createBlock(); + +  // Default statements partition blocks, so this is the top of the basic block +  // we were processing (the "default:" is the label).    DefaultCaseBlock->setLabel(Terminator);    if (!FinishBlock(DefaultCaseBlock))      return 0; -  // Unlike case statements, we don't add the default block to the -  // successors for the switch statement immediately.  This is done -  // when we finish processing the switch statement.  This allows for -  // the default case (including a fall-through to the code after the -  // switch statement) to always be the last successor of a switch-terminated -  // block. -   +  // Unlike case statements, we don't add the default block to the successors +  // for the switch statement immediately.  This is done when we finish +  // processing the switch statement.  This allows for the default case +  // (including a fall-through to the code after the switch statement) to always +  // be the last successor of a switch-terminated block. +    // We set Block to NULL to allow lazy creation of a new block (if necessary)    Block = NULL; -   +    // This block is now the implicit successor of other blocks.    Succ = DefaultCaseBlock; -   -  return DefaultCaseBlock;   + +  return DefaultCaseBlock;  }  CFGBlock* CFGBuilder::VisitIndirectGotoStmt(IndirectGotoStmt* I) { -  // Lazily create the indirect-goto dispatch block if there isn't one -  // already. +  // Lazily create the indirect-goto dispatch block if there isn't one already.    CFGBlock* IBlock = cfg->getIndirectGotoBlock(); -   +    if (!IBlock) {      IBlock = createBlock(false);      cfg->setIndirectGotoBlock(IBlock);    } -   +    // IndirectGoto is a control-flow statement.  Thus we stop processing the    // current block and create a new one.    if (Block) { @@ -1368,10 +1346,9 @@ CFGBlock* CFGBuilder::VisitIndirectGotoStmt(IndirectGotoStmt* I) {  } // end anonymous namespace -/// createBlock - Constructs and adds a new CFGBlock to the CFG.  The -///  block has no successors or predecessors.  If this is the first block -///  created in the CFG, it is automatically set to be the Entry and Exit -///  of the CFG. +/// createBlock - Constructs and adds a new CFGBlock to the CFG.  The block has +///  no successors or predecessors.  If this is the first block created in the +///  CFG, it is automatically set to be the Entry and Exit of the CFG.  CFGBlock* CFG::createBlock() {    bool first_block = begin() == end(); @@ -1406,48 +1383,47 @@ namespace {  static void FindSubExprAssignments(Stmt* Terminator, llvm::SmallPtrSet<Expr*,50>& Set) {    if (!Terminator)      return; -   +    for (Stmt::child_iterator I=Terminator->child_begin(), E=Terminator->child_end(); I!=E; ++I) {      if (!*I) continue; -     +      if (BinaryOperator* B = dyn_cast<BinaryOperator>(*I))        if (B->isAssignmentOp()) Set.insert(B); -     +      FindSubExprAssignments(*I, Set);    }  }  static BlkExprMapTy* PopulateBlkExprMap(CFG& cfg) {    BlkExprMapTy* M = new BlkExprMapTy(); -   -  // Look for assignments that are used as subexpressions.  These are the -  // only assignments that we want to *possibly* register as a block-level -  // expression.  Basically, if an assignment occurs both in a subexpression -  // and at the block-level, it is a block-level expression. + +  // Look for assignments that are used as subexpressions.  These are the only +  // assignments that we want to *possibly* register as a block-level +  // expression.  Basically, if an assignment occurs both in a subexpression and +  // at the block-level, it is a block-level expression.    llvm::SmallPtrSet<Expr*,50> SubExprAssignments; -   +    for (CFG::iterator I=cfg.begin(), E=cfg.end(); I != E; ++I)      for (CFGBlock::iterator BI=I->begin(), EI=I->end(); BI != EI; ++BI)        FindSubExprAssignments(*BI, SubExprAssignments);    for (CFG::iterator I=cfg.begin(), E=cfg.end(); I != E; ++I) { -     -    // Iterate over the statements again on identify the Expr* and Stmt* at -    // the block-level that are block-level expressions. + +    // Iterate over the statements again on identify the Expr* and Stmt* at the +    // block-level that are block-level expressions.      for (CFGBlock::iterator BI=I->begin(), EI=I->end(); BI != EI; ++BI)        if (Expr* Exp = dyn_cast<Expr>(*BI)) { -         +          if (BinaryOperator* B = dyn_cast<BinaryOperator>(Exp)) {            // Assignment expressions that are not nested within another -          // expression are really "statements" whose value is never -          // used by another expression. +          // expression are really "statements" whose value is never used by +          // another expression.            if (B->isAssignmentOp() && !SubExprAssignments.count(Exp))              continue; -        } -        else if (const StmtExpr* Terminator = dyn_cast<StmtExpr>(Exp)) { -          // Special handling for statement expressions.  The last statement -          // in the statement expression is also a block-level expr. +        } else if (const StmtExpr* Terminator = dyn_cast<StmtExpr>(Exp)) { +          // Special handling for statement expressions.  The last statement in +          // the statement expression is also a block-level expr.            const CompoundStmt* C = Terminator->getSubStmt();            if (!C->body_empty()) {              unsigned x = M->size(); @@ -1458,27 +1434,27 @@ static BlkExprMapTy* PopulateBlkExprMap(CFG& cfg) {          unsigned x = M->size();          (*M)[Exp] = x;        } -     +      // Look at terminators.  The condition is a block-level expression. -     +      Stmt* S = I->getTerminatorCondition(); -     +      if (S && M->find(S) == M->end()) {          unsigned x = M->size();          (*M)[S] = x;      }    } -     +    return M;  }  CFG::BlkExprNumTy CFG::getBlkExprNum(const Stmt* S) {    assert(S != NULL);    if (!BlkExprMap) { BlkExprMap = (void*) PopulateBlkExprMap(*this); } -   +    BlkExprMapTy* M = reinterpret_cast<BlkExprMapTy*>(BlkExprMap);    BlkExprMapTy::iterator I = M->find(S); -   +    if (I == M->end()) return CFG::BlkExprNumTy();    else return CFG::BlkExprNumTy(I->second);  } @@ -1501,7 +1477,7 @@ unsigned CFG::getNumBlkExprs() {  CFG::~CFG() {    delete reinterpret_cast<const BlkExprMapTy*>(BlkExprMap);  } -   +  //===----------------------------------------------------------------------===//  // CFG pretty printing  //===----------------------------------------------------------------------===// @@ -1509,7 +1485,7 @@ CFG::~CFG() {  namespace {  class VISIBILITY_HIDDEN StmtPrinterHelper : public PrinterHelper  { -                           +    typedef llvm::DenseMap<Stmt*,std::pair<unsigned,unsigned> > StmtMapTy;    StmtMapTy StmtMap;    signed CurrentBlock; @@ -1526,24 +1502,24 @@ public:          StmtMap[*BI] = std::make_pair(I->getBlockID(),j);        }    } -             +    virtual ~StmtPrinterHelper() {} -   +    const LangOptions &getLangOpts() const { return LangOpts; }    void setBlockID(signed i) { CurrentBlock = i; }    void setStmtID(unsigned i) { CurrentStmt = i; } -   +    virtual bool handledStmt(Stmt* Terminator, llvm::raw_ostream& OS) { -     +      StmtMapTy::iterator I = StmtMap.find(Terminator);      if (I == StmtMap.end())        return false; -     -    if (CurrentBlock >= 0 && I->second.first == (unsigned) CurrentBlock  + +    if (CurrentBlock >= 0 && I->second.first == (unsigned) CurrentBlock                            && I->second.second == CurrentStmt)        return false; -       +        OS << "[B" << I->second.first << "." << I->second.second << "]";      return true;    } @@ -1554,7 +1530,7 @@ public:  namespace {  class VISIBILITY_HIDDEN CFGBlockTerminatorPrint    : public StmtVisitor<CFGBlockTerminatorPrint,void> { -   +    llvm::raw_ostream& OS;    StmtPrinterHelper* Helper;    PrintingPolicy Policy; @@ -1563,15 +1539,17 @@ public:    CFGBlockTerminatorPrint(llvm::raw_ostream& os, StmtPrinterHelper* helper,                            const PrintingPolicy &Policy)      : OS(os), Helper(helper), Policy(Policy) {} -   +    void VisitIfStmt(IfStmt* I) {      OS << "if ";      I->getCond()->printPretty(OS,Helper,Policy);    } -   +    // Default case. -  void VisitStmt(Stmt* Terminator) { Terminator->printPretty(OS, Helper, Policy); } -   +  void VisitStmt(Stmt* Terminator) { +    Terminator->printPretty(OS, Helper, Policy); +  } +    void VisitForStmt(ForStmt* F) {      OS << "for (" ;      if (F->getInit()) OS << "..."; @@ -1581,46 +1559,46 @@ public:      if (F->getInc()) OS << "...";      OS << ")";    } -   +    void VisitWhileStmt(WhileStmt* W) {      OS << "while " ;      if (Stmt* C = W->getCond()) C->printPretty(OS, Helper, Policy);    } -   +    void VisitDoStmt(DoStmt* D) {      OS << "do ... while ";      if (Stmt* C = D->getCond()) C->printPretty(OS, Helper, Policy);    } -   +    void VisitSwitchStmt(SwitchStmt* Terminator) {      OS << "switch ";      Terminator->getCond()->printPretty(OS, Helper, Policy);    } -   +    void VisitConditionalOperator(ConditionalOperator* C) {      C->getCond()->printPretty(OS, Helper, Policy); -    OS << " ? ... : ...";   +    OS << " ? ... : ...";    } -   +    void VisitChooseExpr(ChooseExpr* C) {      OS << "__builtin_choose_expr( ";      C->getCond()->printPretty(OS, Helper, Policy);      OS << " )";    } -   +    void VisitIndirectGotoStmt(IndirectGotoStmt* I) {      OS << "goto *";      I->getTarget()->printPretty(OS, Helper, Policy);    } -   +    void VisitBinaryOperator(BinaryOperator* B) {      if (!B->isLogicalOp()) {        VisitExpr(B);        return;      } -     +      B->getLHS()->printPretty(OS, Helper, Policy); -     +      switch (B->getOpcode()) {        case BinaryOperator::LOr:          OS << " || ..."; @@ -1630,23 +1608,23 @@ public:          return;        default:          assert(false && "Invalid logical operator."); -    }   +    }    } -   +    void VisitExpr(Expr* E) {      E->printPretty(OS, Helper, Policy); -  }                                                        +  }  };  } // end anonymous namespace -   +  static void print_stmt(llvm::raw_ostream &OS, StmtPrinterHelper* Helper,                         Stmt* Terminator) {    if (Helper) {      // special printing for statement-expressions.      if (StmtExpr* SE = dyn_cast<StmtExpr>(Terminator)) {        CompoundStmt* Sub = SE->getSubStmt(); -       +        if (Sub->child_begin() != Sub->child_end()) {          OS << "({ ... ; ";          Helper->handledStmt(*SE->getSubStmt()->body_rbegin(),OS); @@ -1654,7 +1632,7 @@ static void print_stmt(llvm::raw_ostream &OS, StmtPrinterHelper* Helper,          return;        }      } -     +      // special printing for comma expressions.      if (BinaryOperator* B = dyn_cast<BinaryOperator>(Terminator)) {        if (B->getOpcode() == BinaryOperator::Comma) { @@ -1662,25 +1640,25 @@ static void print_stmt(llvm::raw_ostream &OS, StmtPrinterHelper* Helper,          Helper->handledStmt(B->getRHS(),OS);          OS << '\n';          return; -      }           -    }   +      } +    }    } -   +    Terminator->printPretty(OS, Helper, PrintingPolicy(Helper->getLangOpts())); -   +    // Expressions need a newline.    if (isa<Expr>(Terminator)) OS << '\n';  } -   +  static void print_block(llvm::raw_ostream& OS, const CFG* cfg,                          const CFGBlock& B,                          StmtPrinterHelper* Helper, bool print_edges) { -  +    if (Helper) Helper->setBlockID(B.getBlockID()); -   +    // Print the header. -  OS << "\n [ B" << B.getBlockID();   -     +  OS << "\n [ B" << B.getBlockID(); +    if (&B == &cfg->getEntry())      OS << " (ENTRY) ]\n";    else if (&B == &cfg->getExit()) @@ -1689,13 +1667,13 @@ static void print_block(llvm::raw_ostream& OS, const CFG* cfg,      OS << " (INDIRECT GOTO DISPATCH) ]\n";    else      OS << " ]\n"; -  +    // Print the label of this block.    if (Stmt* Terminator = const_cast<Stmt*>(B.getLabel())) {      if (print_edges)        OS << "    "; -   +      if (LabelStmt* L = dyn_cast<LabelStmt>(Terminator))        OS << L->getName();      else if (CaseStmt* C = dyn_cast<CaseStmt>(Terminator)) { @@ -1707,48 +1685,47 @@ static void print_block(llvm::raw_ostream& OS, const CFG* cfg,          C->getRHS()->printPretty(OS, Helper,                                   PrintingPolicy(Helper->getLangOpts()));        } -    }   -    else if (isa<DefaultStmt>(Terminator)) +    } else if (isa<DefaultStmt>(Terminator))        OS << "default";      else        assert(false && "Invalid label statement in CFGBlock."); -  +      OS << ":\n";    } -  +    // Iterate through the statements in the block and print them.    unsigned j = 1; -   +    for (CFGBlock::const_iterator I = B.begin(), E = B.end() ;         I != E ; ++I, ++j ) { -        +      // Print the statement # in the basic block and the statement itself.      if (print_edges)        OS << "    "; -       +      OS << llvm::format("%3d", j) << ": "; -     +      if (Helper)        Helper->setStmtID(j); -      +      print_stmt(OS,Helper,*I);    } -  +    // Print the terminator of this block.    if (B.getTerminator()) {      if (print_edges)        OS << "    "; -       +      OS << "  T: "; -     +      if (Helper) Helper->setBlockID(-1); -     +      CFGBlockTerminatorPrint TPrinter(OS, Helper,                                       PrintingPolicy(Helper->getLangOpts()));      TPrinter.Visit(const_cast<Stmt*>(B.getTerminator()));      OS << '\n';    } -  +    if (print_edges) {      // Print the predecessors of this block.      OS << "    Predecessors (" << B.pred_size() << "):"; @@ -1756,31 +1733,31 @@ static void print_block(llvm::raw_ostream& OS, const CFG* cfg,      for (CFGBlock::const_pred_iterator I = B.pred_begin(), E = B.pred_end();           I != E; ++I, ++i) { -                   +        if (i == 8 || (i-8) == 0)          OS << "\n     "; -       +        OS << " B" << (*I)->getBlockID();      } -     +      OS << '\n'; -  +      // Print the successors of this block.      OS << "    Successors (" << B.succ_size() << "):";      i = 0;      for (CFGBlock::const_succ_iterator I = B.succ_begin(), E = B.succ_end();           I != E; ++I, ++i) { -          +        if (i == 8 || (i-8) % 10 == 0)          OS << "\n    ";        OS << " B" << (*I)->getBlockID();      } -     +      OS << '\n';    } -}                    +}  /// dump - A simple pretty printer of a CFG that outputs to stderr. @@ -1789,23 +1766,23 @@ void CFG::dump(const LangOptions &LO) const { print(llvm::errs(), LO); }  /// print - A simple pretty printer of a CFG that outputs to an ostream.  void CFG::print(llvm::raw_ostream &OS, const LangOptions &LO) const {    StmtPrinterHelper Helper(this, LO); -   +    // Print the entry block.    print_block(OS, this, getEntry(), &Helper, true); -                     +    // Iterate through the CFGBlocks and print them one by one.    for (const_iterator I = Blocks.begin(), E = Blocks.end() ; I != E ; ++I) {      // Skip the entry block, because we already printed it.      if (&(*I) == &getEntry() || &(*I) == &getExit())        continue; -       +      print_block(OS, this, *I, &Helper, true);    } -   +    // Print the exit block.    print_block(OS, this, getExit(), &Helper, true);    OS.flush(); -}   +}  /// dump - A simply pretty printer of a CFGBlock that outputs to stderr.  void CFGBlock::dump(const CFG* cfg, const LangOptions &LO) const { @@ -1822,86 +1799,86 @@ void CFGBlock::print(llvm::raw_ostream& OS, const CFG* cfg,  /// printTerminator - A simple pretty printer of the terminator of a CFGBlock.  void CFGBlock::printTerminator(llvm::raw_ostream &OS, -                               const LangOptions &LO) const {   +                               const LangOptions &LO) const {    CFGBlockTerminatorPrint TPrinter(OS, NULL, PrintingPolicy(LO));    TPrinter.Visit(const_cast<Stmt*>(getTerminator()));  }  Stmt* CFGBlock::getTerminatorCondition() { -   +    if (!Terminator)      return NULL; -   +    Expr* E = NULL; -   +    switch (Terminator->getStmtClass()) {      default:        break; -       +      case Stmt::ForStmtClass:        E = cast<ForStmt>(Terminator)->getCond();        break; -       +      case Stmt::WhileStmtClass:        E = cast<WhileStmt>(Terminator)->getCond();        break; -       +      case Stmt::DoStmtClass:        E = cast<DoStmt>(Terminator)->getCond();        break; -       +      case Stmt::IfStmtClass:        E = cast<IfStmt>(Terminator)->getCond();        break; -       +      case Stmt::ChooseExprClass:        E = cast<ChooseExpr>(Terminator)->getCond();        break; -       +      case Stmt::IndirectGotoStmtClass:        E = cast<IndirectGotoStmt>(Terminator)->getTarget();        break; -       +      case Stmt::SwitchStmtClass:        E = cast<SwitchStmt>(Terminator)->getCond();        break; -       +      case Stmt::ConditionalOperatorClass:        E = cast<ConditionalOperator>(Terminator)->getCond();        break; -       +      case Stmt::BinaryOperatorClass: // '&&' and '||'        E = cast<BinaryOperator>(Terminator)->getLHS();        break; -       +      case Stmt::ObjCForCollectionStmtClass: -      return Terminator;       +      return Terminator;    } -   +    return E ? E->IgnoreParens() : NULL;  }  bool CFGBlock::hasBinaryBranchTerminator() const { -   +    if (!Terminator)      return false; -   +    Expr* E = NULL; -   +    switch (Terminator->getStmtClass()) {      default:        return false; -       -    case Stmt::ForStmtClass:       + +    case Stmt::ForStmtClass:      case Stmt::WhileStmtClass:      case Stmt::DoStmtClass:      case Stmt::IfStmtClass:      case Stmt::ChooseExprClass:      case Stmt::ConditionalOperatorClass:      case Stmt::BinaryOperatorClass: -      return true;       +      return true;    } -   +    return E ? E->IgnoreParens() : NULL;  } @@ -1912,7 +1889,7 @@ bool CFGBlock::hasBinaryBranchTerminator() const {  #ifndef NDEBUG -static StmtPrinterHelper* GraphHelper;   +static StmtPrinterHelper* GraphHelper;  #endif  void CFG::viewCFG(const LangOptions &LO) const { @@ -1944,7 +1921,7 @@ struct DOTGraphTraits<const CFG*> : public DefaultDOTGraphTraits {          OutStr[i] = '\\';          OutStr.insert(OutStr.begin()+i+1, 'l');        } -       +      return OutStr;  #else      return "";  | 

