]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/clang/include/clang/AST/NonTrivialTypeVisitor.h
MFC r355940:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / clang / include / clang / AST / NonTrivialTypeVisitor.h
1 //===-- NonTrivialTypeVisitor.h - Visitor for non-trivial Types *- C++ --*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //  This file defines the visitor classes that are used to traverse non-trivial
10 //  structs.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_CLANG_NON_TRIVIAL_TYPE_VISITOR_H
15 #define LLVM_CLANG_NON_TRIVIAL_TYPE_VISITOR_H
16
17 #include "clang/AST/Type.h"
18
19 namespace clang {
20
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)...);
25   }
26
27   template <class... Ts>
28   RetTy visitWithKind(QualType::DestructionKind DK, QualType FT,
29                       Ts &&... Args) {
30     switch (DK) {
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)...);
41     }
42
43     llvm_unreachable("unknown destruction kind");
44   }
45
46   Derived &asDerived() { return static_cast<Derived &>(*this); }
47 };
48
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)...);
55   }
56
57   template <class... Ts>
58   RetTy visitWithKind(QualType::PrimitiveDefaultInitializeKind PDIK,
59                       QualType FT, Ts &&... Args) {
60     switch (PDIK) {
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)...);
69     }
70
71     llvm_unreachable("unknown default-initialize kind");
72   }
73
74   Derived &asDerived() { return static_cast<Derived &>(*this); }
75 };
76
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)...);
84   }
85
86   template <class... Ts>
87   RetTy visitWithKind(QualType::PrimitiveCopyKind PCK, QualType FT,
88                       Ts &&... Args) {
89     asDerived().preVisit(PCK, FT, std::forward<Ts>(Args)...);
90
91     switch (PCK) {
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)...);
102     }
103
104     llvm_unreachable("unknown primitive copy kind");
105   }
106
107   Derived &asDerived() { return static_cast<Derived &>(*this); }
108 };
109
110 } // end namespace clang
111
112 #endif