clang API Documentation

CFGRecStmtDeclVisitor.h
Go to the documentation of this file.
00001 //= CFGRecStmtDeclVisitor - Recursive visitor of CFG stmts/decls -*- 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 implements the template class CFGRecStmtDeclVisitor, which extends
00011 // CFGRecStmtVisitor by implementing (typed) visitation of decls.
00012 //
00013 // FIXME: This may not be fully complete.  We currently explore only subtypes
00014 //        of ScopedDecl.
00015 //===----------------------------------------------------------------------===//
00016 
00017 #ifndef LLVM_CLANG_ANALYSIS_CFG_REC_STMT_DECL_VISITOR_H
00018 #define LLVM_CLANG_ANALYSIS_CFG_REC_STMT_DECL_VISITOR_H
00019 
00020 #include "clang/Analysis/Visitors/CFGRecStmtVisitor.h"
00021 #include "clang/AST/Decl.h"
00022 #include "clang/AST/DeclObjC.h"
00023 #include "clang/AST/DeclCXX.h"
00024 
00025 #define DISPATCH_CASE(CLASS)                                  \
00026 case Decl::CLASS:                                             \
00027 static_cast<ImplClass*>(this)->Visit##CLASS##Decl(            \
00028                                static_cast<CLASS##Decl*>(D)); \
00029 break;
00030 
00031 #define DEFAULT_DISPATCH(CLASS) void Visit##CLASS##Decl(CLASS##Decl *D) {}
00032 #define DEFAULT_DISPATCH_VARDECL(CLASS) void Visit##CLASS##Decl(CLASS##Decl *D)\
00033   { static_cast<ImplClass*>(this)->VisitVarDecl(D); }
00034 
00035 
00036 namespace clang {
00037 template <typename ImplClass>
00038 class CFGRecStmtDeclVisitor : public CFGRecStmtVisitor<ImplClass> {
00039 public:
00040 
00041   void VisitDeclRefExpr(DeclRefExpr *DR) {
00042     static_cast<ImplClass*>(this)->VisitDecl(DR->getDecl());
00043   }
00044 
00045   void VisitDeclStmt(DeclStmt *DS) {
00046     for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end();
00047         DI != DE; ++DI) {
00048       Decl *D = *DI;
00049       static_cast<ImplClass*>(this)->VisitDecl(D);
00050       // Visit the initializer.
00051       if (VarDecl *VD = dyn_cast<VarDecl>(D))
00052         if (Expr *I = VD->getInit())
00053           static_cast<ImplClass*>(this)->Visit(I);
00054     }
00055   }
00056 
00057   void VisitDecl(Decl *D) {
00058     switch (D->getKind()) {
00059         DISPATCH_CASE(Function)
00060         DISPATCH_CASE(CXXMethod)
00061         DISPATCH_CASE(Var)
00062         DISPATCH_CASE(ParmVar)       // FIXME: (same)
00063         DISPATCH_CASE(ImplicitParam)
00064         DISPATCH_CASE(EnumConstant)
00065         DISPATCH_CASE(Typedef)
00066         DISPATCH_CASE(Record)    // FIXME: Refine.  VisitStructDecl?
00067         DISPATCH_CASE(CXXRecord)
00068         DISPATCH_CASE(Enum)
00069         DISPATCH_CASE(Field)
00070         DISPATCH_CASE(UsingDirective)
00071         DISPATCH_CASE(Using)
00072       default:
00073         llvm_unreachable("Subtype of ScopedDecl not handled.");
00074     }
00075   }
00076 
00077   DEFAULT_DISPATCH(Var)
00078   DEFAULT_DISPATCH(Function)
00079   DEFAULT_DISPATCH(CXXMethod)
00080   DEFAULT_DISPATCH_VARDECL(ParmVar)
00081   DEFAULT_DISPATCH(ImplicitParam)
00082   DEFAULT_DISPATCH(EnumConstant)
00083   DEFAULT_DISPATCH(Typedef)
00084   DEFAULT_DISPATCH(Record)
00085   DEFAULT_DISPATCH(Enum)
00086   DEFAULT_DISPATCH(Field)
00087   DEFAULT_DISPATCH(ObjCInterface)
00088   DEFAULT_DISPATCH(ObjCMethod)
00089   DEFAULT_DISPATCH(ObjCProtocol)
00090   DEFAULT_DISPATCH(ObjCCategory)
00091   DEFAULT_DISPATCH(UsingDirective)
00092   DEFAULT_DISPATCH(Using)
00093 
00094   void VisitCXXRecordDecl(CXXRecordDecl *D) {
00095     static_cast<ImplClass*>(this)->VisitRecordDecl(D);
00096   }
00097 };
00098 
00099 } // end namespace clang
00100 
00101 #undef DISPATCH_CASE
00102 #undef DEFAULT_DISPATCH
00103 #endif