From 81e84560c85c5d3727072f5b9e8bd2a963adf8e7 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Wed, 29 Jul 2009 23:40:39 +0000 Subject: [PATCH] Use helper class ASTVisitor to fully traverse an AST. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@77539 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Index/ASTVisitor.h | 109 +++++++++++++++++++++++++++++++++ lib/Index/DeclReferenceMap.cpp | 91 ++++----------------------- 2 files changed, 120 insertions(+), 80 deletions(-) create mode 100644 lib/Index/ASTVisitor.h diff --git a/lib/Index/ASTVisitor.h b/lib/Index/ASTVisitor.h new file mode 100644 index 0000000000..330bf016d3 --- /dev/null +++ b/lib/Index/ASTVisitor.h @@ -0,0 +1,109 @@ +//===--- ASTVisitor.h - Visitor for an ASTContext ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the ASTVisitor interface. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_INDEX_ASTVISITOR_H +#define LLVM_CLANG_INDEX_ASTVISITOR_H + +#include "clang/AST/DeclVisitor.h" +#include "clang/AST/StmtVisitor.h" + +namespace clang { + +namespace idx { + +/// \brief Traverses the full AST, both Decls and Stmts. +template +class ASTVisitor : public DeclVisitor, + public StmtVisitor { +public: + ASTVisitor() : CurrentDecl(0) { } + + Decl *CurrentDecl; + + typedef ASTVisitor Base; + typedef DeclVisitor BaseDeclVisitor; + typedef StmtVisitor BaseStmtVisitor; + + using BaseStmtVisitor::Visit; + + //===--------------------------------------------------------------------===// + // DeclVisitor + //===--------------------------------------------------------------------===// + + void Visit(Decl *D) { + Decl *PrevDecl = CurrentDecl; + CurrentDecl = D; + BaseDeclVisitor::Visit(D); + CurrentDecl = PrevDecl; + } + + void VisitFunctionDecl(FunctionDecl *D) { + BaseDeclVisitor::VisitValueDecl(D); + if (D->isThisDeclarationADefinition()) + Visit(D->getBody()); + } + + void VisitObjCMethodDecl(ObjCMethodDecl *D) { + BaseDeclVisitor::VisitNamedDecl(D); + if (D->getBody()) + Visit(D->getBody()); + } + + void VisitBlockDecl(BlockDecl *D) { + BaseDeclVisitor::VisitDecl(D); + Visit(D->getBody()); + } + + void VisitVarDecl(VarDecl *D) { + BaseDeclVisitor::VisitValueDecl(D); + if (Expr *Init = D->getInit()) + Visit(Init); + } + + void VisitDecl(Decl *D) { + if (isa(D) || isa(D) || isa(D)) + return; + + if (DeclContext *DC = dyn_cast(D)) + static_cast(this)->VisitDeclContext(DC); + } + + void VisitDeclContext(DeclContext *DC) { + for (DeclContext::decl_iterator + I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) + Visit(*I); + } + + //===--------------------------------------------------------------------===// + // StmtVisitor + //===--------------------------------------------------------------------===// + + void VisitDeclStmt(DeclStmt *Node) { + for (DeclStmt::decl_iterator + I = Node->decl_begin(), E = Node->decl_end(); I != E; ++I) + Visit(*I); + } + + void VisitStmt(Stmt *Node) { + for (Stmt::child_iterator + I = Node->child_begin(), E = Node->child_end(); I != E; ++I) + if (*I) + Visit(*I); + } +}; + +} // namespace idx + +} // namespace clang + +#endif diff --git a/lib/Index/DeclReferenceMap.cpp b/lib/Index/DeclReferenceMap.cpp index f99f4ae84d..1e6ae21a64 100644 --- a/lib/Index/DeclReferenceMap.cpp +++ b/lib/Index/DeclReferenceMap.cpp @@ -14,111 +14,42 @@ #include "clang/Index/DeclReferenceMap.h" #include "clang/Index/ASTLocation.h" -#include "clang/AST/Decl.h" -#include "clang/AST/Stmt.h" -#include "clang/AST/DeclVisitor.h" -#include "clang/AST/StmtVisitor.h" +#include "ASTVisitor.h" #include "llvm/Support/Compiler.h" using namespace clang; using namespace idx; namespace { -class VISIBILITY_HIDDEN StmtMapper : public StmtVisitor { +class VISIBILITY_HIDDEN RefMapper : public ASTVisitor { DeclReferenceMap::MapTy ⤅ - Decl *Parent; public: - StmtMapper(DeclReferenceMap::MapTy &map, Decl *parent) - : Map(map), Parent(parent) { } + RefMapper(DeclReferenceMap::MapTy &map) : Map(map) { } - void VisitDeclStmt(DeclStmt *Node); void VisitDeclRefExpr(DeclRefExpr *Node); void VisitMemberExpr(MemberExpr *Node); void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node); - void VisitStmt(Stmt *Node); -}; - -class VISIBILITY_HIDDEN DeclMapper : public DeclVisitor { - DeclReferenceMap::MapTy ⤅ - -public: - DeclMapper(DeclReferenceMap::MapTy &map) - : Map(map) { } - - void VisitDeclContext(DeclContext *DC); - void VisitVarDecl(VarDecl *D); - void VisitFunctionDecl(FunctionDecl *D); - void VisitObjCMethodDecl(ObjCMethodDecl *D); - void VisitBlockDecl(BlockDecl *D); - void VisitDecl(Decl *D); }; } // anonymous namespace //===----------------------------------------------------------------------===// -// StmtMapper Implementation +// RefMapper Implementation //===----------------------------------------------------------------------===// -void StmtMapper::VisitDeclStmt(DeclStmt *Node) { - DeclMapper Mapper(Map); - for (DeclStmt::decl_iterator - I = Node->decl_begin(), E = Node->decl_end(); I != E; ++I) - Mapper.Visit(*I); -} - -void StmtMapper::VisitDeclRefExpr(DeclRefExpr *Node) { +void RefMapper::VisitDeclRefExpr(DeclRefExpr *Node) { NamedDecl *PrimD = cast(Node->getDecl()->getCanonicalDecl()); - Map.insert(std::make_pair(PrimD, ASTLocation(Parent, Node))); + Map.insert(std::make_pair(PrimD, ASTLocation(CurrentDecl, Node))); } -void StmtMapper::VisitMemberExpr(MemberExpr *Node) { +void RefMapper::VisitMemberExpr(MemberExpr *Node) { NamedDecl *PrimD = cast(Node->getMemberDecl()->getCanonicalDecl()); - Map.insert(std::make_pair(PrimD, ASTLocation(Parent, Node))); -} - -void StmtMapper::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { - Map.insert(std::make_pair(Node->getDecl(), ASTLocation(Parent, Node))); -} - -void StmtMapper::VisitStmt(Stmt *Node) { - for (Stmt::child_iterator - I = Node->child_begin(), E = Node->child_end(); I != E; ++I) - Visit(*I); -} - -//===----------------------------------------------------------------------===// -// DeclMapper Implementation -//===----------------------------------------------------------------------===// - -void DeclMapper::VisitDeclContext(DeclContext *DC) { - for (DeclContext::decl_iterator - I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) - Visit(*I); -} - -void DeclMapper::VisitFunctionDecl(FunctionDecl *D) { - if (D->isThisDeclarationADefinition()) - StmtMapper(Map, D).Visit(D->getBody()); -} - -void DeclMapper::VisitObjCMethodDecl(ObjCMethodDecl *D) { - if (D->getBody()) - StmtMapper(Map, D).Visit(D->getBody()); -} - -void DeclMapper::VisitBlockDecl(BlockDecl *D) { - StmtMapper(Map, D).Visit(D->getBody()); -} - -void DeclMapper::VisitVarDecl(VarDecl *D) { - if (Expr *Init = D->getInit()) - StmtMapper(Map, D).Visit(Init); + Map.insert(std::make_pair(PrimD, ASTLocation(CurrentDecl, Node))); } -void DeclMapper::VisitDecl(Decl *D) { - if (DeclContext *DC = dyn_cast(D)) - VisitDeclContext(DC); +void RefMapper::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { + Map.insert(std::make_pair(Node->getDecl(), ASTLocation(CurrentDecl, Node))); } //===----------------------------------------------------------------------===// @@ -126,7 +57,7 @@ void DeclMapper::VisitDecl(Decl *D) { //===----------------------------------------------------------------------===// DeclReferenceMap::DeclReferenceMap(ASTContext &Ctx) { - DeclMapper(Map).Visit(Ctx.getTranslationUnitDecl()); + RefMapper(Map).Visit(Ctx.getTranslationUnitDecl()); } DeclReferenceMap::astlocation_iterator -- 2.40.0