xref: /freebsd-src/contrib/llvm-project/clang/include/clang/AST/DeclVisitor.h (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===- DeclVisitor.h - Visitor for Decl subclasses --------------*- C++ -*-===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric //
9*0b57cec5SDimitry Andric //  This file defines the DeclVisitor interface.
10*0b57cec5SDimitry Andric //
11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12*0b57cec5SDimitry Andric 
13*0b57cec5SDimitry Andric #ifndef LLVM_CLANG_AST_DECLVISITOR_H
14*0b57cec5SDimitry Andric #define LLVM_CLANG_AST_DECLVISITOR_H
15*0b57cec5SDimitry Andric 
16*0b57cec5SDimitry Andric #include "clang/AST/Decl.h"
17*0b57cec5SDimitry Andric #include "clang/AST/DeclBase.h"
18*0b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h"
19*0b57cec5SDimitry Andric #include "clang/AST/DeclFriend.h"
20*0b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h"
21*0b57cec5SDimitry Andric #include "clang/AST/DeclOpenMP.h"
22*0b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h"
23*0b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
24*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
25*0b57cec5SDimitry Andric 
26*0b57cec5SDimitry Andric namespace clang {
27*0b57cec5SDimitry Andric 
28*0b57cec5SDimitry Andric namespace declvisitor {
29*0b57cec5SDimitry Andric /// A simple visitor class that helps create declaration visitors.
30*0b57cec5SDimitry Andric template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
31*0b57cec5SDimitry Andric class Base {
32*0b57cec5SDimitry Andric public:
33*0b57cec5SDimitry Andric #define PTR(CLASS) typename Ptr<CLASS>::type
34*0b57cec5SDimitry Andric #define DISPATCH(NAME, CLASS) \
35*0b57cec5SDimitry Andric   return static_cast<ImplClass*>(this)->Visit##NAME(static_cast<PTR(CLASS)>(D))
36*0b57cec5SDimitry Andric 
Visit(PTR (Decl)D)37*0b57cec5SDimitry Andric   RetTy Visit(PTR(Decl) D) {
38*0b57cec5SDimitry Andric     switch (D->getKind()) {
39*0b57cec5SDimitry Andric #define DECL(DERIVED, BASE) \
40*0b57cec5SDimitry Andric       case Decl::DERIVED: DISPATCH(DERIVED##Decl, DERIVED##Decl);
41*0b57cec5SDimitry Andric #define ABSTRACT_DECL(DECL)
42*0b57cec5SDimitry Andric #include "clang/AST/DeclNodes.inc"
43*0b57cec5SDimitry Andric     }
44*0b57cec5SDimitry Andric     llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
45*0b57cec5SDimitry Andric   }
46*0b57cec5SDimitry Andric 
47*0b57cec5SDimitry Andric   // If the implementation chooses not to implement a certain visit
48*0b57cec5SDimitry Andric   // method, fall back to the parent.
49*0b57cec5SDimitry Andric #define DECL(DERIVED, BASE) \
50*0b57cec5SDimitry Andric   RetTy Visit##DERIVED##Decl(PTR(DERIVED##Decl) D) { DISPATCH(BASE, BASE); }
51*0b57cec5SDimitry Andric #include "clang/AST/DeclNodes.inc"
52*0b57cec5SDimitry Andric 
VisitDecl(PTR (Decl)D)53*0b57cec5SDimitry Andric   RetTy VisitDecl(PTR(Decl) D) { return RetTy(); }
54*0b57cec5SDimitry Andric 
55*0b57cec5SDimitry Andric #undef PTR
56*0b57cec5SDimitry Andric #undef DISPATCH
57*0b57cec5SDimitry Andric };
58*0b57cec5SDimitry Andric 
59*0b57cec5SDimitry Andric } // namespace declvisitor
60*0b57cec5SDimitry Andric 
61*0b57cec5SDimitry Andric /// A simple visitor class that helps create declaration visitors.
62*0b57cec5SDimitry Andric ///
63*0b57cec5SDimitry Andric /// This class does not preserve constness of Decl pointers (see also
64*0b57cec5SDimitry Andric /// ConstDeclVisitor).
65*0b57cec5SDimitry Andric template <typename ImplClass, typename RetTy = void>
66*0b57cec5SDimitry Andric class DeclVisitor
67*0b57cec5SDimitry Andric     : public declvisitor::Base<std::add_pointer, ImplClass, RetTy> {};
68*0b57cec5SDimitry Andric 
69*0b57cec5SDimitry Andric /// A simple visitor class that helps create declaration visitors.
70*0b57cec5SDimitry Andric ///
71*0b57cec5SDimitry Andric /// This class preserves constness of Decl pointers (see also DeclVisitor).
72*0b57cec5SDimitry Andric template <typename ImplClass, typename RetTy = void>
73*0b57cec5SDimitry Andric class ConstDeclVisitor
74*0b57cec5SDimitry Andric     : public declvisitor::Base<llvm::make_const_ptr, ImplClass, RetTy> {};
75*0b57cec5SDimitry Andric 
76*0b57cec5SDimitry Andric } // namespace clang
77*0b57cec5SDimitry Andric 
78*0b57cec5SDimitry Andric #endif // LLVM_CLANG_AST_DECLVISITOR_H
79