diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-07-17 18:15:54 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-07-17 18:15:54 +0000 |
commit | f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11 (patch) | |
tree | 5dd288b969c082a1063cf6a9f887acf96d81cfc5 /lib | |
parent | 237a31bf663c8c3783bd71dc7cfbdd0425a8ba69 (diff) |
Move WalkAST logic for 'ConditionalOperator' into 'VisitConditionalOperator'.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76202 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Analysis/CFG.cpp | 119 |
1 files changed, 61 insertions, 58 deletions
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index b445acf70f..1698048bb7 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -102,6 +102,7 @@ public: CFGBlock* VisitBreakStmt(BreakStmt* B); CFGBlock* VisitCaseStmt(CaseStmt* Terminator); CFGBlock* VisitCompoundStmt(CompoundStmt* C); + CFGBlock* VisitConditionalOperator(ConditionalOperator *C); CFGBlock* VisitContinueStmt(ContinueStmt* C); CFGBlock* VisitDefaultStmt(DefaultStmt* D); CFGBlock* VisitDoStmt(DoStmt* D); @@ -145,7 +146,7 @@ public: private: CFGBlock* createBlock(bool add_successor = true); CFGBlock* addStmt(Stmt* Terminator); - CFGBlock* WalkAST(Stmt* Terminator, bool AlwaysAddStmt); + CFGBlock* WalkAST(Stmt* Terminator, bool AlwaysAddStmt = false); CFGBlock* WalkAST_VisitChildren(Stmt* Terminator); CFGBlock* WalkAST_VisitDeclSubExpr(Decl* D); CFGBlock* WalkAST_VisitStmtExpr(StmtExpr* Terminator); @@ -272,68 +273,17 @@ bool CFGBuilder::FinishBlock(CFGBlock* B) { /// called if no additional blocks are created. CFGBlock* CFGBuilder::addStmt(Stmt* Terminator) { if (!Block) Block = createBlock(); - return WalkAST(Terminator,true); + return WalkAST(Terminator, true); } -/// WalkAST - Used by addStmt to walk the subtree of a statement and add extra +/// WalkAST - 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) { +CFGBlock* CFGBuilder::WalkAST(Stmt* Terminator, bool AlwaysAddStmt) { switch (Terminator->getStmtClass()) { - 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 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()); - } - + case Stmt::ConditionalOperatorClass: + return VisitConditionalOperator(cast<ConditionalOperator>(Terminator)); + case Stmt::ChooseExprClass: { ChooseExpr* C = cast<ChooseExpr>(Terminator); @@ -568,6 +518,59 @@ CFGBlock* CFGBuilder::VisitNullStmt(NullStmt* Statement) { return Block; } + +CFGBlock *CFGBuilder::VisitConditionalOperator(ConditionalOperator *C) { + // 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 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()); +} + CFGBlock* CFGBuilder::VisitCompoundStmt(CompoundStmt* C) { CFGBlock* LastBlock = Block; |