diff --git a/clang/AST/CFG.cpp b/clang/AST/CFG.cpp index e1c1a7474c3d..acda71ef42ce 100644 --- a/clang/AST/CFG.cpp +++ b/clang/AST/CFG.cpp @@ -1237,30 +1237,6 @@ void CFGBlock::print(std::ostream& OS, const CFG* cfg) const { print_block(OS, cfg, *this, &Helper, true); } -/// hasImplicitControlFlow - Returns true if a given expression is -/// is represented within a CFG as having a designated "statement slot" -bool CFG::hasImplicitControlFlow(const Stmt* S) { - switch (S->getStmtClass()) { - default: - return false; - - case Stmt::CallExprClass: - case Stmt::ConditionalOperatorClass: - case Stmt::ChooseExprClass: - case Stmt::StmtExprClass: - case Stmt::DeclStmtClass: - return true; - - case Stmt::BinaryOperatorClass: { - const BinaryOperator* B = cast(S); - if (B->isLogicalOp() || B->getOpcode() == BinaryOperator::Comma) - return true; - else - return false; - } - } -} - //===----------------------------------------------------------------------===// // CFG Graphviz Visualization //===----------------------------------------------------------------------===// diff --git a/clang/AST/Stmt.cpp b/clang/AST/Stmt.cpp index 9b405f1e23e6..0f2bb70416c4 100644 --- a/clang/AST/Stmt.cpp +++ b/clang/AST/Stmt.cpp @@ -89,6 +89,28 @@ SourceRange ReturnStmt::getSourceRange() const { return SourceRange(RetLoc); } +bool Stmt::hasImplicitControlFlow() const { + switch (sClass) { + default: + return false; + + case CallExprClass: + case ConditionalOperatorClass: + case ChooseExprClass: + case StmtExprClass: + case DeclStmtClass: + return true; + + case Stmt::BinaryOperatorClass: { + const BinaryOperator* B = cast(this); + if (B->isLogicalOp() || B->getOpcode() == BinaryOperator::Comma) + return true; + else + return false; + } + } +} + //===----------------------------------------------------------------------===// // Child Iterators for iterating over subexpressions/substatements //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/AST/CFG.h b/clang/include/clang/AST/CFG.h index 5a3bbf21d06a..e50c3cc906a9 100644 --- a/clang/include/clang/AST/CFG.h +++ b/clang/include/clang/AST/CFG.h @@ -273,45 +273,6 @@ public: void print(std::ostream& OS) const; void dump() const; - //===--------------------------------------------------------------------===// - // Static Predicates pertaining to CFG-related properties. - //===--------------------------------------------------------------------===// - - /// hasImplicitControlFlow - Returns true if a given expression is - /// is represented within a CFG as having a designated "statement slot" - /// within a CFGBlock to represent the execution of that expression. This - /// is usefull for expressions that contain implicit control flow, such - /// as &&, ||, and ? operators, as well as commas and statement expressions. - /// - /// For example, considering a CFGBlock with the following statement: - /// - /// (1) x = ... ? ... ? ... - /// - /// When the CFG is built, this logically becomes: - /// - /// (1) ... ? ... : ... (a unique statement slot for the ternary ?) - /// (2) x = [E1] (where E1 is actually the ConditionalOperator*) - /// - /// A client of the CFG, when walking the statement at (2), will encounter - /// E1. In this case, hasImplicitControlFlow(E1) == true, and the client - /// will know that the expression E1 is explicitly placed into its own - /// statement slot to capture the implicit control-flow it has. - /// - /// Special cases: - /// - /// (1) Function calls. - /// Function calls are placed in their own statement slot so that - /// that we have a clear identification of "call-return" sites. If - /// you see a CallExpr nested as a subexpression of E, the CallExpr appears - /// in a statement slot in the CFG that dominates the location of E. - /// - /// (2) DeclStmts - /// We include DeclStmts because the initializer expressions for Decls - /// will be separated out into distinct statements in the CFG. These - /// statements will dominate the Decl. - /// - static bool hasImplicitControlFlow(const Stmt* S); - //===--------------------------------------------------------------------===// // Internal: constructors and data. //===--------------------------------------------------------------------===// diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index a346fdc33fbb..ff93d22296e5 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -85,6 +85,13 @@ public: // Implement isa support. static bool classof(const Stmt *) { return true; } + /// hasImplicitControlFlow - Some statements (e.g. short circuited operations) + /// contain implicit control-flow in the order their subexpressions + /// are evaluated. This predicate returns true if this statement has + /// such implicit control-flow. Such statements are also specially handled + /// within CFGs. + bool hasImplicitControlFlow() const; + /// Child Iterators: All subclasses must implement child_begin and child_end /// to permit easy iteration over the substatements/subexpessions of an /// AST node. This permits easy iteration over all nodes in the AST.