1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | #ifndef LLVM_CLANG_AST_DECLVISITOR_H |
14 | #define LLVM_CLANG_AST_DECLVISITOR_H |
15 | |
16 | #include "clang/AST/Decl.h" |
17 | #include "clang/AST/DeclBase.h" |
18 | #include "clang/AST/DeclCXX.h" |
19 | #include "clang/AST/DeclFriend.h" |
20 | #include "clang/AST/DeclObjC.h" |
21 | #include "clang/AST/DeclOpenMP.h" |
22 | #include "clang/AST/DeclTemplate.h" |
23 | #include "llvm/ADT/STLExtras.h" |
24 | #include "llvm/Support/ErrorHandling.h" |
25 | |
26 | namespace clang { |
27 | |
28 | namespace declvisitor { |
29 | |
30 | template<template <typename> class Ptr, typename ImplClass, typename RetTy=void> |
31 | class Base { |
32 | public: |
33 | #define PTR(CLASS) typename Ptr<CLASS>::type |
34 | #define DISPATCH(NAME, CLASS) \ |
35 | return static_cast<ImplClass*>(this)->Visit##NAME(static_cast<PTR(CLASS)>(D)) |
36 | |
37 | RetTy Visit(PTR(Decl) D) { |
38 | switch (D->getKind()) { |
39 | #define DECL(DERIVED, BASE) \ |
40 | case Decl::DERIVED: DISPATCH(DERIVED##Decl, DERIVED##Decl); |
41 | #define ABSTRACT_DECL(DECL) |
42 | #include "clang/AST/DeclNodes.inc" |
43 | } |
44 | llvm_unreachable("Decl that isn't part of DeclNodes.inc!"); |
45 | } |
46 | |
47 | |
48 | |
49 | #define DECL(DERIVED, BASE) \ |
50 | RetTy Visit##DERIVED##Decl(PTR(DERIVED##Decl) D) { DISPATCH(BASE, BASE); } |
51 | #include "clang/AST/DeclNodes.inc" |
52 | |
53 | RetTy VisitDecl(PTR(Decl) D) { return RetTy(); } |
54 | |
55 | #undef PTR |
56 | #undef DISPATCH |
57 | }; |
58 | |
59 | } |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | template <typename ImplClass, typename RetTy = void> |
66 | class DeclVisitor |
67 | : public declvisitor::Base<std::add_pointer, ImplClass, RetTy> {}; |
68 | |
69 | |
70 | |
71 | |
72 | template <typename ImplClass, typename RetTy = void> |
73 | class ConstDeclVisitor |
74 | : public declvisitor::Base<llvm::make_const_ptr, ImplClass, RetTy> {}; |
75 | |
76 | } |
77 | |
78 | #endif |
79 | |