Clang Project

clang_source_code/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
19namespace clang {
20
21template <class Derived, class RetTy = voidstruct 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 DKQualType FT,
29                      Ts &&... Args) {
30    switch (DK) {
31    case QualType::DK_objc_strong_lifetime:
32      return asDerived().visitARCStrong(FTstd::forward<Ts>(Args)...);
33    case QualType::DK_nontrivial_c_struct:
34      return asDerived().visitStruct(FTstd::forward<Ts>(Args)...);
35    case QualType::DK_none:
36      return asDerived().visitTrivial(FTstd::forward<Ts>(Args)...);
37    case QualType::DK_cxx_destructor:
38      return asDerived().visitCXXDestructor(FTstd::forward<Ts>(Args)...);
39    case QualType::DK_objc_weak_lifetime:
40      return asDerived().visitARCWeak(FTstd::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(FTstd::forward<Ts>(Args)...);
63    case QualType::PDIK_ARCWeak:
64      return asDerived().visitARCWeak(FTstd::forward<Ts>(Args)...);
65    case QualType::PDIK_Struct:
66      return asDerived().visitStruct(FTstd::forward<Ts>(Args)...);
67    case QualType::PDIK_Trivial:
68      return asDerived().visitTrivial(FTstd::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(PCKFTstd::forward<Ts>(Args)...);
84  }
85
86  template <class... Ts>
87  RetTy visitWithKind(QualType::PrimitiveCopyKind PCKQualType FT,
88                      Ts &&... Args) {
89    asDerived().preVisit(PCKFTstd::forward<Ts>(Args)...);
90
91    switch (PCK) {
92    case QualType::PCK_ARCStrong:
93      return asDerived().visitARCStrong(FTstd::forward<Ts>(Args)...);
94    case QualType::PCK_ARCWeak:
95      return asDerived().visitARCWeak(FTstd::forward<Ts>(Args)...);
96    case QualType::PCK_Struct:
97      return asDerived().visitStruct(FTstd::forward<Ts>(Args)...);
98    case QualType::PCK_Trivial:
99      return asDerived().visitTrivial(FTstd::forward<Ts>(Args)...);
100    case QualType::PCK_VolatileTrivial:
101      return asDerived().visitVolatileTrivial(FTstd::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
clang::DestructedTypeVisitor::visit
clang::DestructedTypeVisitor::visitWithKind
clang::DestructedTypeVisitor::asDerived
clang::DefaultInitializedTypeVisitor::visit
clang::DefaultInitializedTypeVisitor::visitWithKind
clang::DefaultInitializedTypeVisitor::asDerived
clang::CopiedTypeVisitor::visit
clang::CopiedTypeVisitor::visitWithKind
clang::CopiedTypeVisitor::asDerived