[cfe-commits] r41868 - in /cfe/trunk: AST/CFG.cpp include/clang/AST/CFG.h

Ted Kremenek kremenek at apple.com
Tue Sep 11 15:08:25 PDT 2007


Author: kremenek
Date: Tue Sep 11 17:08:24 2007
New Revision: 41868

URL: http://llvm.org/viewvc/llvm-project?rev=41868&view=rev
Log:
Added static method "CFG::hasImplicitControlFlow".

This method is used to determine if an expression contains implicit
control-flow, and thus appears in a distinct statement slot in the CFG.

For example:

  (1) x = ... ? ... ? ...

  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.

Modified:
    cfe/trunk/AST/CFG.cpp
    cfe/trunk/include/clang/AST/CFG.h

Modified: cfe/trunk/AST/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/CFG.cpp?rev=41868&r1=41867&r2=41868&view=diff

==============================================================================
--- cfe/trunk/AST/CFG.cpp (original)
+++ cfe/trunk/AST/CFG.cpp Tue Sep 11 17:08:24 2007
@@ -1240,6 +1240,30 @@
   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
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/include/clang/AST/CFG.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CFG.h?rev=41868&r1=41867&r2=41868&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/CFG.h (original)
+++ cfe/trunk/include/clang/AST/CFG.h Tue Sep 11 17:08:24 2007
@@ -222,7 +222,45 @@
   void print(std::ostream& OS) const;
   void dump() const;
   void setEntry(CFGBlock *B) { Entry = B; }
-  void setIndirectGotoBlock(CFGBlock* B) { IndirectGotoBlock = B; }   
+  void setIndirectGotoBlock(CFGBlock* B) { IndirectGotoBlock = B; }
+  
+  // Useful Predicates
+  
+  /// 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);  
+  
 };
 } // end namespace clang
 





More information about the cfe-commits mailing list