10#include "clang/AST/ASTContext.h"
11#include "clang/AST/DeclCXX.h"
12#include "clang/AST/DeclTemplate.h"
18 auto *Record = Type->getAsCXXRecordDecl();
19 return Record && Record->hasDefinition() &&
20 !Record->hasNonTrivialCopyConstructor() &&
21 !Record->hasNonTrivialDestructor();
25 auto *Record = Type->getAsCXXRecordDecl();
26 if (!Record || !Record->hasDefinition())
28 return llvm::any_of(Record->ctors(), [](
const auto *Constructor) {
29 return Constructor->isCopyConstructor() && Constructor->isDeleted();
34 const ASTContext &Context) {
35 if (Type->isDependentType() || Type->isIncompleteType())
37 return !Type.isTriviallyCopyableType(Context) &&
43 const ASTContext &Context) {
44 const auto *ClassDecl = dyn_cast<CXXRecordDecl>(&RecordDecl);
50 if (RecordDecl.isInvalidDecl())
54 if (ClassDecl->hasUserProvidedDefaultConstructor())
57 if (ClassDecl->isPolymorphic())
60 if (ClassDecl->hasTrivialDefaultConstructor())
65 for (
const FieldDecl *Field : ClassDecl->fields()) {
66 if (Field->hasInClassInitializer())
72 return llvm::all_of(ClassDecl->bases(), [&](
const CXXBaseSpecifier &Base) {
73 return isTriviallyDefaultConstructible(Base.getType(), Context) &&
83 if (Type->isArrayType())
89 if (Type->isIncompleteType())
92 if (Context.getLangOpts().ObjCAutoRefCount) {
93 switch (Type.getObjCLifetime()) {
94 case Qualifiers::OCL_ExplicitNone:
97 case Qualifiers::OCL_Strong:
98 case Qualifiers::OCL_Weak:
99 case Qualifiers::OCL_Autoreleasing:
102 case Qualifiers::OCL_None:
103 if (Type->isObjCLifetimeType())
109 const QualType CanonicalType = Type.getCanonicalType();
110 if (CanonicalType->isDependentType())
114 if (CanonicalType->isScalarType() || CanonicalType->isVectorType())
117 if (
const auto *RD = CanonicalType->getAsRecordDecl())
129 if (Type->isIncompleteType())
132 if (Type.getCanonicalType()->isDependentType())
135 return Type.isDestructedType() == QualType::DK_none;
139 auto *Record = Type->getAsCXXRecordDecl();
140 return Record && Record->hasDefinition() &&
141 Record->hasNonTrivialMoveConstructor();
145 auto *Record = Type->getAsCXXRecordDecl();
146 return Record && Record->hasDefinition() &&
147 Record->hasNonTrivialMoveAssignment();
151 return D->isInStdNamespace() && D->getName() ==
"initializer_list";
155 Type = Type.getCanonicalType();
156 if (
const auto *TS = Type->getAs<TemplateSpecializationType>()) {
157 if (
const TemplateDecl *TD = TS->getTemplateName().getAsTemplateDecl())
160 if (
const auto *RT = Type->getAs<RecordType>()) {
161 if (
const auto *Specialization =
162 dyn_cast_if_present<ClassTemplateSpecializationDecl>(RT->getDecl()))
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.
static bool declIsStdInitializerList(const NamedDecl *D)
static bool classHasTrivialCopyAndDestroy(QualType Type)
bool hasNonTrivialMoveAssignment(QualType Type)
Return true if Type has a non-trivial move assignment operator.
bool isStdInitializerList(QualType Type)
Returns true if Type is a std::initializer_list<...> specialization.
static bool hasDeletedCopyConstructor(QualType Type)
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.