clang API Documentation
00001 //===--- CFGStmtVisitor.h - Visitor for Stmts in a CFG ----------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the CFGStmtVisitor interface, which extends 00011 // StmtVisitor. This interface is useful for visiting statements in a CFG 00012 // where some statements have implicit control-flow and thus should 00013 // be treated specially. 00014 // 00015 //===----------------------------------------------------------------------===// 00016 00017 #ifndef LLVM_CLANG_ANALYSIS_CFGSTMTVISITOR_H 00018 #define LLVM_CLANG_ANALYSIS_CFGSTMTVISITOR_H 00019 00020 #include "clang/AST/StmtVisitor.h" 00021 #include "clang/Analysis/CFG.h" 00022 00023 namespace clang { 00024 00025 #define DISPATCH_CASE(CLASS) \ 00026 case Stmt::CLASS ## Class: return \ 00027 static_cast<ImplClass*>(this)->BlockStmt_Visit ## CLASS(static_cast<CLASS*>(S)); 00028 00029 #define DEFAULT_BLOCKSTMT_VISIT(CLASS) RetTy BlockStmt_Visit ## CLASS(CLASS *S)\ 00030 { return\ 00031 static_cast<ImplClass*>(this)->BlockStmt_VisitImplicitControlFlowExpr(\ 00032 cast<Expr>(S)); } 00033 00034 template <typename ImplClass, typename RetTy=void> 00035 class CFGStmtVisitor : public StmtVisitor<ImplClass,RetTy> { 00036 Stmt *CurrentBlkStmt; 00037 00038 struct NullifyStmt { 00039 Stmt*& S; 00040 00041 NullifyStmt(Stmt*& s) : S(s) {} 00042 ~NullifyStmt() { S = NULL; } 00043 }; 00044 00045 public: 00046 CFGStmtVisitor() : CurrentBlkStmt(NULL) {} 00047 00048 Stmt *getCurrentBlkStmt() const { return CurrentBlkStmt; } 00049 00050 RetTy Visit(Stmt *S) { 00051 if (S == CurrentBlkStmt || 00052 !static_cast<ImplClass*>(this)->getCFG().isBlkExpr(S)) 00053 return StmtVisitor<ImplClass,RetTy>::Visit(S); 00054 else 00055 return RetTy(); 00056 } 00057 00058 /// VisitConditionVariableInit - Handle the initialization of condition 00059 /// variables at branches. Valid statements include IfStmt, ForStmt, 00060 /// WhileStmt, and SwitchStmt. 00061 RetTy VisitConditionVariableInit(Stmt *S) { 00062 return RetTy(); 00063 } 00064 00065 /// BlockVisit_XXX - Visitor methods for visiting the "root" statements in 00066 /// CFGBlocks. Root statements are the statements that appear explicitly in 00067 /// the list of statements in a CFGBlock. For substatements, or when there 00068 /// is no implementation provided for a BlockStmt_XXX method, we default 00069 /// to using StmtVisitor's Visit method. 00070 RetTy BlockStmt_Visit(Stmt *S) { 00071 CurrentBlkStmt = S; 00072 NullifyStmt cleanup(CurrentBlkStmt); 00073 00074 switch (S->getStmtClass()) { 00075 case Stmt::IfStmtClass: 00076 case Stmt::ForStmtClass: 00077 case Stmt::WhileStmtClass: 00078 case Stmt::SwitchStmtClass: 00079 return static_cast<ImplClass*>(this)->VisitConditionVariableInit(S); 00080 00081 DISPATCH_CASE(StmtExpr) 00082 DISPATCH_CASE(ConditionalOperator) 00083 DISPATCH_CASE(BinaryConditionalOperator) 00084 DISPATCH_CASE(ObjCForCollectionStmt) 00085 DISPATCH_CASE(CXXForRangeStmt) 00086 00087 case Stmt::BinaryOperatorClass: { 00088 BinaryOperator* B = cast<BinaryOperator>(S); 00089 if (B->isLogicalOp()) 00090 return static_cast<ImplClass*>(this)->BlockStmt_VisitLogicalOp(B); 00091 else if (B->getOpcode() == BO_Comma) 00092 return static_cast<ImplClass*>(this)->BlockStmt_VisitComma(B); 00093 // Fall through. 00094 } 00095 00096 default: 00097 if (isa<Expr>(S)) 00098 return 00099 static_cast<ImplClass*>(this)->BlockStmt_VisitExpr(cast<Expr>(S)); 00100 else 00101 return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(S); 00102 } 00103 } 00104 00105 DEFAULT_BLOCKSTMT_VISIT(StmtExpr) 00106 DEFAULT_BLOCKSTMT_VISIT(ConditionalOperator) 00107 DEFAULT_BLOCKSTMT_VISIT(BinaryConditionalOperator) 00108 00109 RetTy BlockStmt_VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) { 00110 return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(S); 00111 } 00112 00113 RetTy BlockStmt_VisitCXXForRangeStmt(CXXForRangeStmt *S) { 00114 return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(S); 00115 } 00116 00117 RetTy BlockStmt_VisitImplicitControlFlowExpr(Expr *E) { 00118 return static_cast<ImplClass*>(this)->BlockStmt_VisitExpr(E); 00119 } 00120 00121 RetTy BlockStmt_VisitExpr(Expr *E) { 00122 return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(E); 00123 } 00124 00125 RetTy BlockStmt_VisitStmt(Stmt *S) { 00126 return static_cast<ImplClass*>(this)->Visit(S); 00127 } 00128 00129 RetTy BlockStmt_VisitLogicalOp(BinaryOperator* B) { 00130 return 00131 static_cast<ImplClass*>(this)->BlockStmt_VisitImplicitControlFlowExpr(B); 00132 } 00133 00134 RetTy BlockStmt_VisitComma(BinaryOperator* B) { 00135 return 00136 static_cast<ImplClass*>(this)->BlockStmt_VisitImplicitControlFlowExpr(B); 00137 } 00138 00139 //===--------------------------------------------------------------------===// 00140 // Utility methods. Not called by default (but subclasses may use them). 00141 //===--------------------------------------------------------------------===// 00142 00143 /// VisitChildren: Call "Visit" on each child of S. 00144 void VisitChildren(Stmt *S) { 00145 00146 switch (S->getStmtClass()) { 00147 default: 00148 break; 00149 00150 case Stmt::StmtExprClass: { 00151 CompoundStmt *CS = cast<StmtExpr>(S)->getSubStmt(); 00152 if (CS->body_empty()) return; 00153 static_cast<ImplClass*>(this)->Visit(CS->body_back()); 00154 return; 00155 } 00156 00157 case Stmt::BinaryOperatorClass: { 00158 BinaryOperator* B = cast<BinaryOperator>(S); 00159 if (B->getOpcode() != BO_Comma) break; 00160 static_cast<ImplClass*>(this)->Visit(B->getRHS()); 00161 return; 00162 } 00163 } 00164 00165 for (Stmt::child_range I = S->children(); I; ++I) 00166 if (*I) static_cast<ImplClass*>(this)->Visit(*I); 00167 } 00168 }; 00169 00170 #undef DEFAULT_BLOCKSTMT_VISIT 00171 #undef DISPATCH_CASE 00172 00173 } // end namespace clang 00174 00175 #endif