]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGStmtVisitor.h
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / llvm / tools / clang / include / clang / Analysis / Visitors / CFGStmtVisitor.h
1 //===--- CFGStmtVisitor.h - Visitor for Stmts in a CFG ----------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file defines the CFGStmtVisitor interface, which extends
11 //  StmtVisitor.  This interface is useful for visiting statements in a CFG
12 //  where some statements have implicit control-flow and thus should
13 //  be treated specially.
14 //
15 //===----------------------------------------------------------------------===//
16
17 #ifndef LLVM_CLANG_ANALYSIS_CFGSTMTVISITOR_H
18 #define LLVM_CLANG_ANALYSIS_CFGSTMTVISITOR_H
19
20 #include "clang/AST/StmtVisitor.h"
21 #include "clang/Analysis/CFG.h"
22
23 namespace clang {
24
25 #define DISPATCH_CASE(CLASS) \
26 case Stmt::CLASS ## Class: return \
27 static_cast<ImplClass*>(this)->BlockStmt_Visit ## CLASS(static_cast<CLASS*>(S));
28
29 #define DEFAULT_BLOCKSTMT_VISIT(CLASS) RetTy BlockStmt_Visit ## CLASS(CLASS *S)\
30 { return\
31   static_cast<ImplClass*>(this)->BlockStmt_VisitImplicitControlFlowExpr(\
32   cast<Expr>(S)); }
33
34 template <typename ImplClass, typename RetTy=void>
35 class CFGStmtVisitor : public StmtVisitor<ImplClass,RetTy> {
36   Stmt *CurrentBlkStmt;
37
38   struct NullifyStmt {
39     Stmt*& S;
40
41     NullifyStmt(Stmt*& s) : S(s) {}
42     ~NullifyStmt() { S = NULL; }
43   };
44
45 public:
46   CFGStmtVisitor() : CurrentBlkStmt(NULL) {}
47
48   Stmt *getCurrentBlkStmt() const { return CurrentBlkStmt; }
49
50   RetTy Visit(Stmt *S) {
51     if (S == CurrentBlkStmt ||
52         !static_cast<ImplClass*>(this)->getCFG().isBlkExpr(S))
53       return StmtVisitor<ImplClass,RetTy>::Visit(S);
54     else
55       return RetTy();
56   }
57   
58   /// VisitConditionVariableInit - Handle the initialization of condition
59   ///  variables at branches.  Valid statements include IfStmt, ForStmt,
60   ///  WhileStmt, and SwitchStmt.
61   RetTy VisitConditionVariableInit(Stmt *S) {
62     return RetTy();
63   }
64
65   /// BlockVisit_XXX - Visitor methods for visiting the "root" statements in
66   /// CFGBlocks.  Root statements are the statements that appear explicitly in
67   /// the list of statements in a CFGBlock.  For substatements, or when there
68   /// is no implementation provided for a BlockStmt_XXX method, we default
69   /// to using StmtVisitor's Visit method.
70   RetTy BlockStmt_Visit(Stmt *S) {
71     CurrentBlkStmt = S;
72     NullifyStmt cleanup(CurrentBlkStmt);
73
74     switch (S->getStmtClass()) {
75       case Stmt::IfStmtClass:
76       case Stmt::ForStmtClass:
77       case Stmt::WhileStmtClass:
78       case Stmt::SwitchStmtClass:
79         return static_cast<ImplClass*>(this)->VisitConditionVariableInit(S);
80
81       DISPATCH_CASE(StmtExpr)
82       DISPATCH_CASE(ConditionalOperator)
83       DISPATCH_CASE(BinaryConditionalOperator)
84       DISPATCH_CASE(ObjCForCollectionStmt)
85       DISPATCH_CASE(CXXForRangeStmt)
86
87       case Stmt::BinaryOperatorClass: {
88         BinaryOperator* B = cast<BinaryOperator>(S);
89         if (B->isLogicalOp())
90           return static_cast<ImplClass*>(this)->BlockStmt_VisitLogicalOp(B);
91         else if (B->getOpcode() == BO_Comma)
92           return static_cast<ImplClass*>(this)->BlockStmt_VisitComma(B);
93         // Fall through.
94       }
95
96       default:
97         if (isa<Expr>(S))
98           return
99             static_cast<ImplClass*>(this)->BlockStmt_VisitExpr(cast<Expr>(S));
100         else
101           return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(S);
102     }
103   }
104
105   DEFAULT_BLOCKSTMT_VISIT(StmtExpr)
106   DEFAULT_BLOCKSTMT_VISIT(ConditionalOperator)
107   DEFAULT_BLOCKSTMT_VISIT(BinaryConditionalOperator)
108
109   RetTy BlockStmt_VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
110     return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(S);
111   }
112
113   RetTy BlockStmt_VisitCXXForRangeStmt(CXXForRangeStmt *S) {
114     return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(S);
115   }
116
117   RetTy BlockStmt_VisitImplicitControlFlowExpr(Expr *E) {
118     return static_cast<ImplClass*>(this)->BlockStmt_VisitExpr(E);
119   }
120
121   RetTy BlockStmt_VisitExpr(Expr *E) {
122     return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(E);
123   }
124
125   RetTy BlockStmt_VisitStmt(Stmt *S) {
126     return static_cast<ImplClass*>(this)->Visit(S);
127   }
128
129   RetTy BlockStmt_VisitLogicalOp(BinaryOperator* B) {
130     return
131      static_cast<ImplClass*>(this)->BlockStmt_VisitImplicitControlFlowExpr(B);
132   }
133
134   RetTy BlockStmt_VisitComma(BinaryOperator* B) {
135     return
136      static_cast<ImplClass*>(this)->BlockStmt_VisitImplicitControlFlowExpr(B);
137   }
138
139   //===--------------------------------------------------------------------===//
140   // Utility methods.  Not called by default (but subclasses may use them).
141   //===--------------------------------------------------------------------===//
142
143   /// VisitChildren: Call "Visit" on each child of S.
144   void VisitChildren(Stmt *S) {
145
146     switch (S->getStmtClass()) {
147       default:
148         break;
149
150       case Stmt::StmtExprClass: {
151         CompoundStmt *CS = cast<StmtExpr>(S)->getSubStmt();
152         if (CS->body_empty()) return;
153         static_cast<ImplClass*>(this)->Visit(CS->body_back());
154         return;
155       }
156
157       case Stmt::BinaryOperatorClass: {
158         BinaryOperator* B = cast<BinaryOperator>(S);
159         if (B->getOpcode() != BO_Comma) break;
160         static_cast<ImplClass*>(this)->Visit(B->getRHS());
161         return;
162       }
163     }
164
165     for (Stmt::child_range I = S->children(); I; ++I)
166       if (*I) static_cast<ImplClass*>(this)->Visit(*I);
167   }
168 };
169
170 #undef DEFAULT_BLOCKSTMT_VISIT
171 #undef DISPATCH_CASE
172
173 }  // end namespace clang
174
175 #endif