clang 23.0.0git
SubobjectVisitor.h
Go to the documentation of this file.
1//===---------- SubobjectVisitor.h - Subobject Visitor ----------*- 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 SubobjectVisitor interface, which recursively
10// traverses subobjects within a type.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_SUBOBJECTVISITOR_H
15#define LLVM_CLANG_AST_SUBOBJECTVISITOR_H
16
18
19namespace clang {
20
21/// Given a type, subobject visitors visit all subobjects of the type in depth
22/// first order. Both pre-order and post-order visitation are performed so that
23/// derived classes can maintain an access path to the visited elements.
24/// Subobjects include all base classes and non-static data members, including
25/// those that are not subobjects according to the C++ standard like data
26/// members with a reference type. Virtual base classes are visited each time
27/// they appear in a class hierarchy despite there being only one actual
28/// subobject present in an object of a most derived type. Array elements are
29/// not individually visited; only their containing array is.
30template <template <typename> class Ptr, typename Derived>
32 ASTContext &Ctx;
33 template <typename Class> using ptr_t = typename Ptr<Class>::type;
34
35public:
36 SubobjectVisitorBase(ASTContext &Ctx) : Ctx(Ctx) {}
37
38 /// Return a reference to the derived class.
39 Derived &getDerived() { return *static_cast<Derived *>(this); }
40
41 void visit(QualType QT) {
42 assert(!QT->isDependentType());
43 QT = QT.getDesugaredType(Ctx);
44
45 // FunctionType, FunctionProtoType, and FunctionNoProtoType are never
46 // the type of a subobject.
47
48 // ObjCObjectType and ObjCInterfaceType are never the type of a
49 // subobject due to the Objective-C object allocation model.
50
51 // PointerType, BlockPointerType, ReferenceType, LValueReferenceType,
52 // RValueReferenceType, MemberPointerType, and ObjCObjectPointerType
53 // may all be the type of a subobject, but they do not contain other
54 // subobjects; the pointee type should not be visited.
55
56 // ComplexType, VectorType, ExtVectorType, MatrixType, PipeType,
57 // EnumType, and OverflowBehaviorType all have an element or
58 // underlying type that could be visited. However, in each of these
59 // cases, the lower type is constrained to a fundamental type and
60 // therefore doesn't contain any fields or base classes.
61
62 if (auto *ResAtomicType = QT->getAs<AtomicType>()) {
63 getDerived().visit(ResAtomicType->getValueType());
64 return;
65 }
66
67 // If the type is an array, visit its element type. Separate traversal of
68 // arrays is not needed because the array will be encountered as a
69 // FieldDecl.
70 if (QT->isArrayType()) {
71 QualType ElTy = Ctx.getAsArrayType(QT)->getElementType();
72 getDerived().visit(ElTy);
73 return;
74 }
75
76 if (ptr_t<RecordDecl> RD = QT->getAsRecordDecl()) {
77 getDerived().traverseRecord(RD);
78 return;
79 }
80 }
81
82 void traverseRecord(ptr_t<RecordDecl> RD) {
83 if (ptr_t<CXXRecordDecl> CRD = dyn_cast<CXXRecordDecl>(RD)) {
84 for (auto &BS : CRD->bases()) {
86 getDerived().visit(BS.getType());
87 getDerived().visitBaseSpecifierPost(&BS);
88 }
89 }
90 for (ptr_t<FieldDecl> FD : RD->fields()) {
92 getDerived().visit(FD->getType());
93 getDerived().visitFieldDeclPost(FD);
94 }
95 }
96
97 // Default base class specifier pre-order visitor.
98 bool visitBaseSpecifierPre(ptr_t<CXXBaseSpecifier> BS) { return true; }
99
100 // Default base class specifier post-order visitor.
101 void visitBaseSpecifierPost(ptr_t<CXXBaseSpecifier> BS) {}
102
103 // Default field pre-order visitor.
104 bool visitFieldDeclPre(ptr_t<FieldDecl> FD) { return true; }
105
106 // Default field post-order visitor.
107 void visitFieldDeclPost(ptr_t<FieldDecl> FD) {}
108};
109
110template <typename Derived>
112 : public SubobjectVisitorBase<std::add_pointer, Derived> {
113public:
115 : SubobjectVisitorBase<std::add_pointer, Derived>(Ctx) {}
116};
117
118template <typename Derived>
120 : public SubobjectVisitorBase<llvm::make_const_ptr, Derived> {
121public:
123 : SubobjectVisitorBase<llvm::make_const_ptr, Derived>(Ctx) {}
124};
125
126} // end namespace clang
127
128#endif // LLVM_CLANG_AST_SUBOBJECTVISITOR
Defines the clang::ASTContext interface.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
ConstSubobjectVisitor(ASTContext &Ctx)
A (possibly-)qualified type.
Definition TypeBase.h:937
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
Definition TypeBase.h:1311
void visitFieldDeclPost(ptr_t< FieldDecl > FD)
SubobjectVisitorBase(ASTContext &Ctx)
bool visitFieldDeclPre(ptr_t< FieldDecl > FD)
void visitBaseSpecifierPost(ptr_t< CXXBaseSpecifier > BS)
bool visitBaseSpecifierPre(ptr_t< CXXBaseSpecifier > BS)
Derived & getDerived()
Return a reference to the derived class.
void traverseRecord(ptr_t< RecordDecl > RD)
SubobjectVisitor(ASTContext &Ctx)
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition Type.h:41
bool isArrayType() const
Definition TypeBase.h:8783
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition TypeBase.h:2846
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9277
The JSON file list parser is used to communicate input to InstallAPI.
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30