From: Ted Kremenek Date: Wed, 19 Sep 2007 17:59:28 +0000 (+0000) Subject: Added two new visitors that extend CFGStmtVisitor: CFGRecStmtVisitor and CFGRecStmtDe... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ba0c5d6305a6fd164d0e4f186a735aca799194c3;p=clang Added two new visitors that extend CFGStmtVisitor: CFGRecStmtVisitor and CFGRecStmtDeclVisitor. The extended functionality of these visitors is that they automatically visit all statements in an AST (no explicit recursion is required from subclasses), and the for the latter, decls are visited as well. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42144 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/CFGRecStmtDeclVisitor.h b/include/clang/Analysis/CFGRecStmtDeclVisitor.h new file mode 100644 index 0000000000..ef3c5857e3 --- /dev/null +++ b/include/clang/Analysis/CFGRecStmtDeclVisitor.h @@ -0,0 +1,88 @@ +//= CFGRecStmtDeclVisitor - Recursive visitor of CFG stmts/decls -*- C++ --*-=// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Ted Kremenek and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the template class CFGRecStmtDeclVisitor, which extends +// CFGRecStmtVisitor by implementing (typed) visitation of decls. +// +// FIXME: This may not be fully complete. We currently explore only subtypes +// of ScopedDecl. +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_CFG_REC_STMT_DECL_VISITOR_H +#define LLVM_CLANG_ANALYSIS_CFG_REC_STMT_DECL_VISITOR_H + +#include "clang/Analysis/CFGRecStmtVisitor.h" +#include "clang/AST/Decl.h" + +#define DISPATCH_CASE(CASE,CLASS) \ +case Decl::CASE: \ +static_cast(this)->Visit##CLASS(static_cast(D));\ +break; + +#define DEFAULT_DISPATCH(CLASS) void Visit##CLASS(CLASS* D) {} + +namespace clang { +template +class CFGRecStmtDeclVisitor : public CFGRecStmtVisitor { +public: + + void VisitDeclRefExpr(DeclRefExpr* DR) { + static_cast(this)->VisitDeclChain(DR->getDecl()); + } + + void VisitDeclStmt(DeclStmt* DS) { + static_cast(this)->VisitDeclChain(DS->getDecl()); + } + + void VisitDeclChain(ScopedDecl* D) { + for (; D != NULL; D = D->getNextDeclarator()) + static_cast(this)->VisitScopedDecl(D); + } + + void VisitScopedDecl(ScopedDecl* D) { + switch (D->getKind()) { + DISPATCH_CASE(Function,FunctionDecl) + DISPATCH_CASE(BlockVariable,BlockVarDecl) // FIXME:Refine. VisitVarDecl? + DISPATCH_CASE(FileVariable,FileVarDecl) // FIXME: (same) + DISPATCH_CASE(ParmVariable,ParmVarDecl) // FIXME: (same) + DISPATCH_CASE(EnumConstant,EnumConstantDecl) + DISPATCH_CASE(Typedef,TypedefDecl) + DISPATCH_CASE(Struct,RecordDecl) // FIXME: Refine. VisitStructDecl? + DISPATCH_CASE(Union,RecordDecl) // FIXME: Refine. + DISPATCH_CASE(Class,RecordDecl) // FIXME: Refine. + DISPATCH_CASE(Enum,EnumDecl) + DISPATCH_CASE(ObjcInterface,ObjcInterfaceDecl) + DISPATCH_CASE(ObjcClass,ObjcClassDecl) + DISPATCH_CASE(ObjcProtocol,ObjcProtocolDecl) + DISPATCH_CASE(ObjcCategory,ObjcCategoryDecl) + default: + assert(false && "Subtype of ScopedDecl not handled."); + } + } + + DEFAULT_DISPATCH(FunctionDecl) + DEFAULT_DISPATCH(BlockVarDecl) + DEFAULT_DISPATCH(FileVarDecl) + DEFAULT_DISPATCH(ParmVarDecl) + DEFAULT_DISPATCH(EnumConstantDecl) + DEFAULT_DISPATCH(TypedefDecl) + DEFAULT_DISPATCH(RecordDecl) + DEFAULT_DISPATCH(EnumDecl) + DEFAULT_DISPATCH(ObjcInterfaceDecl) + DEFAULT_DISPATCH(ObjcClassDecl) + DEFAULT_DISPATCH(ObjcMethodDecl) + DEFAULT_DISPATCH(ObjcProtocolDecl) + DEFAULT_DISPATCH(ObjcCategoryDecl) +}; + +} // end namespace clang + +#undef DISPATCH_CASE +#undef DEFAULT_DISPATCH +#endif diff --git a/include/clang/Analysis/CFGRecStmtVisitor.h b/include/clang/Analysis/CFGRecStmtVisitor.h new file mode 100644 index 0000000000..2a209a78e6 --- /dev/null +++ b/include/clang/Analysis/CFGRecStmtVisitor.h @@ -0,0 +1,41 @@ +//==- CFGRecStmtVisitor - Recursive visitor of CFG statements ---*- C++ --*-==// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Ted Kremenek and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the template class CFGRecStmtVisitor, which extends +// CFGStmtVisitor by implementing a default recursive visit of all statements. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_CFG_REC_STMT_VISITOR_H +#define LLVM_CLANG_ANALYSIS_CFG_REC_STMT_VISITOR_H + +#include "clang/Analysis/CFGStmtVisitor.h" + +namespace clang { +template +class CFGRecStmtVisitor : public CFGStmtVisitor { +public: + + void Visit(Stmt* S) { + static_cast< CFGStmtVisitor* >(this)->Visit(S); + static_cast< ImplClass* >(this)->VisitChildren(S); + } + + void BlockStmt_Visit(Stmt* S) { + static_cast< CFGStmtVisitor* >(this)->BlockStmt_Visit(S); + static_cast< ImplClass* >(this)->VisitChildren(S); + } + + // Defining operator() allows the visitor to be used as a C++ style functor. + void operator()(Stmt* S) { static_cast(this)->BlockStmt_Visit(S);} +}; + +} // end namespace clang + +#endif