clang API Documentation

CFGStmtVisitor.h
Go to the documentation of this file.
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