1 //===-- NonTrivialTypeVisitor.h - Visitor for non-trivial Types *- C++ --*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the visitor classes that are used to traverse non-trivial
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_CLANG_NON_TRIVIAL_TYPE_VISITOR_H
16 #define LLVM_CLANG_NON_TRIVIAL_TYPE_VISITOR_H
18 #include "clang/AST/Type.h"
22 template <class Derived, class RetTy = void> struct DestructedTypeVisitor {
23 template <class... Ts> RetTy visit(QualType FT, Ts &&... Args) {
24 return asDerived().visitWithKind(FT.isDestructedType(), FT,
25 std::forward<Ts>(Args)...);
28 template <class... Ts>
29 RetTy visitWithKind(QualType::DestructionKind DK, QualType FT,
32 case QualType::DK_objc_strong_lifetime:
33 return asDerived().visitARCStrong(FT, std::forward<Ts>(Args)...);
34 case QualType::DK_nontrivial_c_struct:
35 return asDerived().visitStruct(FT, std::forward<Ts>(Args)...);
36 case QualType::DK_none:
37 return asDerived().visitTrivial(FT, std::forward<Ts>(Args)...);
38 case QualType::DK_cxx_destructor:
39 return asDerived().visitCXXDestructor(FT, std::forward<Ts>(Args)...);
40 case QualType::DK_objc_weak_lifetime:
41 return asDerived().visitARCWeak(FT, std::forward<Ts>(Args)...);
44 llvm_unreachable("unknown destruction kind");
47 Derived &asDerived() { return static_cast<Derived &>(*this); }
50 template <class Derived, class RetTy = void>
51 struct DefaultInitializedTypeVisitor {
52 template <class... Ts> RetTy visit(QualType FT, Ts &&... Args) {
53 return asDerived().visitWithKind(
54 FT.isNonTrivialToPrimitiveDefaultInitialize(), FT,
55 std::forward<Ts>(Args)...);
58 template <class... Ts>
59 RetTy visitWithKind(QualType::PrimitiveDefaultInitializeKind PDIK,
60 QualType FT, Ts &&... Args) {
62 case QualType::PDIK_ARCStrong:
63 return asDerived().visitARCStrong(FT, std::forward<Ts>(Args)...);
64 case QualType::PDIK_ARCWeak:
65 return asDerived().visitARCWeak(FT, std::forward<Ts>(Args)...);
66 case QualType::PDIK_Struct:
67 return asDerived().visitStruct(FT, std::forward<Ts>(Args)...);
68 case QualType::PDIK_Trivial:
69 return asDerived().visitTrivial(FT, std::forward<Ts>(Args)...);
72 llvm_unreachable("unknown default-initialize kind");
75 Derived &asDerived() { return static_cast<Derived &>(*this); }
78 template <class Derived, bool IsMove, class RetTy = void>
79 struct CopiedTypeVisitor {
80 template <class... Ts> RetTy visit(QualType FT, Ts &&... Args) {
81 QualType::PrimitiveCopyKind PCK =
82 IsMove ? FT.isNonTrivialToPrimitiveDestructiveMove()
83 : FT.isNonTrivialToPrimitiveCopy();
84 return asDerived().visitWithKind(PCK, FT, std::forward<Ts>(Args)...);
87 template <class... Ts>
88 RetTy visitWithKind(QualType::PrimitiveCopyKind PCK, QualType FT,
90 asDerived().preVisit(PCK, FT, std::forward<Ts>(Args)...);
93 case QualType::PCK_ARCStrong:
94 return asDerived().visitARCStrong(FT, std::forward<Ts>(Args)...);
95 case QualType::PCK_ARCWeak:
96 return asDerived().visitARCWeak(FT, std::forward<Ts>(Args)...);
97 case QualType::PCK_Struct:
98 return asDerived().visitStruct(FT, std::forward<Ts>(Args)...);
99 case QualType::PCK_Trivial:
100 return asDerived().visitTrivial(FT, std::forward<Ts>(Args)...);
101 case QualType::PCK_VolatileTrivial:
102 return asDerived().visitVolatileTrivial(FT, std::forward<Ts>(Args)...);
105 llvm_unreachable("unknown primitive copy kind");
108 Derived &asDerived() { return static_cast<Derived &>(*this); }
111 } // end namespace clang