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_AST_NONTRIVIALTYPEVISITOR_H
15#define LLVM_CLANG_AST_NONTRIVIALTYPEVISITOR_H
16
17#include "clang/AST/Type.h"
18
19namespace clang {
20
21template <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
49template <class Derived, class RetTy = void>
50struct 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
77template <class Derived, bool IsMove, class RetTy = void>
78struct 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
113

source code of clang/include/clang/AST/NonTrivialTypeVisitor.h