1 //===-- NonTrivialTypeVisitor.h - Visitor for non-trivial Types *- C++ --*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file defines the visitor classes that are used to traverse non-trivial
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_NON_TRIVIAL_TYPE_VISITOR_H
15 #define LLVM_CLANG_NON_TRIVIAL_TYPE_VISITOR_H
17 #include "clang/AST/Type.h"
21 template <class Derived, class RetTy = void> struct DestructedTypeVisitor {
22 template <class... Ts> RetTy visit(QualType FT, Ts &&... Args) {
23 return asDerived().visitWithKind(FT.isDestructedType(), FT,
24 std::forward<Ts>(Args)...);
27 template <class... Ts>
28 RetTy visitWithKind(QualType::DestructionKind DK, QualType FT,
31 case QualType::DK_objc_strong_lifetime:
32 return asDerived().visitARCStrong(FT, std::forward<Ts>(Args)...);
33 case QualType::DK_nontrivial_c_struct:
34 return asDerived().visitStruct(FT, std::forward<Ts>(Args)...);
35 case QualType::DK_none:
36 return asDerived().visitTrivial(FT, std::forward<Ts>(Args)...);
37 case QualType::DK_cxx_destructor:
38 return asDerived().visitCXXDestructor(FT, std::forward<Ts>(Args)...);
39 case QualType::DK_objc_weak_lifetime:
40 return asDerived().visitARCWeak(FT, std::forward<Ts>(Args)...);
43 llvm_unreachable("unknown destruction kind");
46 Derived &asDerived() { return static_cast<Derived &>(*this); }
49 template <class Derived, class RetTy = void>
50 struct DefaultInitializedTypeVisitor {
51 template <class... Ts> RetTy visit(QualType FT, Ts &&... Args) {
52 return asDerived().visitWithKind(
53 FT.isNonTrivialToPrimitiveDefaultInitialize(), FT,
54 std::forward<Ts>(Args)...);
57 template <class... Ts>
58 RetTy visitWithKind(QualType::PrimitiveDefaultInitializeKind PDIK,
59 QualType FT, Ts &&... Args) {
61 case QualType::PDIK_ARCStrong:
62 return asDerived().visitARCStrong(FT, std::forward<Ts>(Args)...);
63 case QualType::PDIK_ARCWeak:
64 return asDerived().visitARCWeak(FT, std::forward<Ts>(Args)...);
65 case QualType::PDIK_Struct:
66 return asDerived().visitStruct(FT, std::forward<Ts>(Args)...);
67 case QualType::PDIK_Trivial:
68 return asDerived().visitTrivial(FT, std::forward<Ts>(Args)...);
71 llvm_unreachable("unknown default-initialize kind");
74 Derived &asDerived() { return static_cast<Derived &>(*this); }
77 template <class Derived, bool IsMove, class RetTy = void>
78 struct CopiedTypeVisitor {
79 template <class... Ts> RetTy visit(QualType FT, Ts &&... Args) {
80 QualType::PrimitiveCopyKind PCK =
81 IsMove ? FT.isNonTrivialToPrimitiveDestructiveMove()
82 : FT.isNonTrivialToPrimitiveCopy();
83 return asDerived().visitWithKind(PCK, FT, std::forward<Ts>(Args)...);
86 template <class... Ts>
87 RetTy visitWithKind(QualType::PrimitiveCopyKind PCK, QualType FT,
89 asDerived().preVisit(PCK, FT, std::forward<Ts>(Args)...);
92 case QualType::PCK_ARCStrong:
93 return asDerived().visitARCStrong(FT, std::forward<Ts>(Args)...);
94 case QualType::PCK_ARCWeak:
95 return asDerived().visitARCWeak(FT, std::forward<Ts>(Args)...);
96 case QualType::PCK_Struct:
97 return asDerived().visitStruct(FT, std::forward<Ts>(Args)...);
98 case QualType::PCK_Trivial:
99 return asDerived().visitTrivial(FT, std::forward<Ts>(Args)...);
100 case QualType::PCK_VolatileTrivial:
101 return asDerived().visitVolatileTrivial(FT, std::forward<Ts>(Args)...);
104 llvm_unreachable("unknown primitive copy kind");
107 Derived &asDerived() { return static_cast<Derived &>(*this); }
110 } // end namespace clang