forked from OSchip/llvm-project
Removed "hasImplicitControlFlow" from class CFG, and moved it to class Stmt
as a member function. This function is no longer needed within the CFG class, and logically belongs to the Stmt class as a predicate for a Stmt instance. llvm-svn: 42489
This commit is contained in:
parent
28e19a48ce
commit
7f74e13535
|
@ -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<BinaryOperator>(S);
|
||||
if (B->isLogicalOp() || B->getOpcode() == BinaryOperator::Comma)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// CFG Graphviz Visualization
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -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<BinaryOperator>(this);
|
||||
if (B->isLogicalOp() || B->getOpcode() == BinaryOperator::Comma)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Child Iterators for iterating over subexpressions/substatements
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -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.
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
|
|
@ -85,6 +85,13 @@ public:
|
|||
// Implement isa<T> 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.
|
||||
|
|
Loading…
Reference in New Issue