Home | History | Annotate | Download | only in Visitors
      1 //= CFGRecStmtDeclVisitor - Recursive visitor of CFG stmts/decls -*- 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 implements the template class CFGRecStmtDeclVisitor, which extends
     11 // CFGRecStmtVisitor by implementing (typed) visitation of decls.
     12 //
     13 // FIXME: This may not be fully complete.  We currently explore only subtypes
     14 //        of ScopedDecl.
     15 //===----------------------------------------------------------------------===//
     16 
     17 #ifndef LLVM_CLANG_ANALYSIS_CFG_REC_STMT_DECL_VISITOR_H
     18 #define LLVM_CLANG_ANALYSIS_CFG_REC_STMT_DECL_VISITOR_H
     19 
     20 #include "clang/AST/Decl.h"
     21 #include "clang/AST/DeclCXX.h"
     22 #include "clang/AST/DeclObjC.h"
     23 #include "clang/Analysis/Visitors/CFGRecStmtVisitor.h"
     24 
     25 #define DISPATCH_CASE(CLASS)                                  \
     26 case Decl::CLASS:                                             \
     27 static_cast<ImplClass*>(this)->Visit##CLASS##Decl(            \
     28                                static_cast<CLASS##Decl*>(D)); \
     29 break;
     30 
     31 #define DEFAULT_DISPATCH(CLASS) void Visit##CLASS##Decl(CLASS##Decl *D) {}
     32 #define DEFAULT_DISPATCH_VARDECL(CLASS) void Visit##CLASS##Decl(CLASS##Decl *D)\
     33   { static_cast<ImplClass*>(this)->VisitVarDecl(D); }
     34 
     35 
     36 namespace clang {
     37 template <typename ImplClass>
     38 class CFGRecStmtDeclVisitor : public CFGRecStmtVisitor<ImplClass> {
     39 public:
     40 
     41   void VisitDeclRefExpr(DeclRefExpr *DR) {
     42     static_cast<ImplClass*>(this)->VisitDecl(DR->getDecl());
     43   }
     44 
     45   void VisitDeclStmt(DeclStmt *DS) {
     46     for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end();
     47         DI != DE; ++DI) {
     48       Decl *D = *DI;
     49       static_cast<ImplClass*>(this)->VisitDecl(D);
     50       // Visit the initializer.
     51       if (VarDecl *VD = dyn_cast<VarDecl>(D))
     52         if (Expr *I = VD->getInit())
     53           static_cast<ImplClass*>(this)->Visit(I);
     54     }
     55   }
     56 
     57   void VisitDecl(Decl *D) {
     58     switch (D->getKind()) {
     59         DISPATCH_CASE(Function)
     60         DISPATCH_CASE(CXXMethod)
     61         DISPATCH_CASE(Var)
     62         DISPATCH_CASE(ParmVar)       // FIXME: (same)
     63         DISPATCH_CASE(ImplicitParam)
     64         DISPATCH_CASE(EnumConstant)
     65         DISPATCH_CASE(Typedef)
     66         DISPATCH_CASE(TypeAlias)
     67         DISPATCH_CASE(Record)    // FIXME: Refine.  VisitStructDecl?
     68         DISPATCH_CASE(CXXRecord)
     69         DISPATCH_CASE(Enum)
     70         DISPATCH_CASE(Field)
     71         DISPATCH_CASE(UsingDirective)
     72         DISPATCH_CASE(Using)
     73         DISPATCH_CASE(NamespaceAlias)
     74       default:
     75         llvm_unreachable("Subtype of ScopedDecl not handled.");
     76     }
     77   }
     78 
     79   DEFAULT_DISPATCH(Var)
     80   DEFAULT_DISPATCH(Function)
     81   DEFAULT_DISPATCH(CXXMethod)
     82   DEFAULT_DISPATCH_VARDECL(ParmVar)
     83   DEFAULT_DISPATCH(ImplicitParam)
     84   DEFAULT_DISPATCH(EnumConstant)
     85   DEFAULT_DISPATCH(Typedef)
     86   DEFAULT_DISPATCH(TypeAlias)
     87   DEFAULT_DISPATCH(Record)
     88   DEFAULT_DISPATCH(Enum)
     89   DEFAULT_DISPATCH(Field)
     90   DEFAULT_DISPATCH(ObjCInterface)
     91   DEFAULT_DISPATCH(ObjCMethod)
     92   DEFAULT_DISPATCH(ObjCProtocol)
     93   DEFAULT_DISPATCH(ObjCCategory)
     94   DEFAULT_DISPATCH(UsingDirective)
     95   DEFAULT_DISPATCH(Using)
     96   DEFAULT_DISPATCH(NamespaceAlias)
     97 
     98   void VisitCXXRecordDecl(CXXRecordDecl *D) {
     99     static_cast<ImplClass*>(this)->VisitRecordDecl(D);
    100   }
    101 };
    102 
    103 } // end namespace clang
    104 
    105 #undef DISPATCH_CASE
    106 #undef DEFAULT_DISPATCH
    107 #endif
    108