10#include "clang/AST/ASTContext.h"
11#include "clang/AST/DeclCXX.h"
12#include "clang/ASTMatchers/ASTMatchFinder.h"
19bool classHasTrivialCopyAndDestroy(QualType
Type) {
20 auto *Record =
Type->getAsCXXRecordDecl();
21 return Record && Record->hasDefinition() &&
22 !Record->hasNonTrivialCopyConstructor() &&
23 !Record->hasNonTrivialDestructor();
26bool hasDeletedCopyConstructor(QualType
Type) {
27 auto *Record =
Type->getAsCXXRecordDecl();
28 if (!Record || !Record->hasDefinition())
30 for (
const auto *Constructor : Record->ctors()) {
31 if (Constructor->isCopyConstructor() && Constructor->isDeleted())
40 const ASTContext &Context) {
41 if (
Type->isDependentType() ||
Type->isIncompleteType())
43 return !
Type.isTriviallyCopyableType(Context) &&
44 !classHasTrivialCopyAndDestroy(
Type) &&
45 !hasDeletedCopyConstructor(
Type) &&
46 !
Type->isObjCLifetimeType();
50 const ASTContext &Context) {
51 const auto *ClassDecl = dyn_cast<CXXRecordDecl>(&RecordDecl);
57 if (RecordDecl.isInvalidDecl())
61 if (ClassDecl->hasUserProvidedDefaultConstructor())
64 if (ClassDecl->isPolymorphic())
67 if (ClassDecl->hasTrivialDefaultConstructor())
72 for (
const FieldDecl *
Field : ClassDecl->fields()) {
73 if (
Field->hasInClassInitializer())
79 for (
const CXXBaseSpecifier &Base : ClassDecl->bases()) {
94 if (
Type->isArrayType())
100 if (
Type->isIncompleteType())
103 if (Context.getLangOpts().ObjCAutoRefCount) {
104 switch (
Type.getObjCLifetime()) {
105 case Qualifiers::OCL_ExplicitNone:
108 case Qualifiers::OCL_Strong:
109 case Qualifiers::OCL_Weak:
110 case Qualifiers::OCL_Autoreleasing:
113 case Qualifiers::OCL_None:
114 if (
Type->isObjCLifetimeType())
120 QualType CanonicalType =
Type.getCanonicalType();
121 if (CanonicalType->isDependentType())
125 if (CanonicalType->isScalarType() || CanonicalType->isVectorType())
128 if (
const auto *RT = CanonicalType->getAs<RecordType>()) {
141 if (
Type->isIncompleteType())
144 if (
Type.getCanonicalType()->isDependentType())
147 return Type.isDestructedType() == QualType::DK_none;
151 auto *Record =
Type->getAsCXXRecordDecl();
152 return Record && Record->hasDefinition() &&
153 Record->hasNonTrivialMoveConstructor();
157 auto *Record =
Type->getAsCXXRecordDecl();
158 return Record && Record->hasDefinition() &&
159 Record->hasNonTrivialMoveAssignment();
bool isTriviallyDefaultConstructible(QualType Type, const ASTContext &Context)
Returns true if Type is trivially default constructible.
bool recordIsTriviallyDefaultConstructible(const RecordDecl &RecordDecl, const ASTContext &Context)
Returns true if RecordDecl is trivially default constructible.
std::optional< bool > isExpensiveToCopy(QualType Type, const ASTContext &Context)
Returns true if Type is expensive to copy.
bool hasNonTrivialMoveAssignment(QualType Type)
Return true if Type has a non-trivial move assignment operator.
bool hasNonTrivialMoveConstructor(QualType Type)
Returns true if Type has a non-trivial move constructor.
bool isTriviallyDestructible(QualType Type)
Returns true if Type is trivially destructible.