trivial.
We previously took a shortcut by assuming that if a subobject had a
trivial copy assignment operator (with a few side-conditions), we would
always invoke it, and could avoid going through overload resolution.
That turns out to not be correct in the presenve of ref-qualifiers (and
also won't be the case for copy-assignments with requires-clauses
either). Use the same logic for lazy declaration of copy-assignments
that we use for all other special member functions.
/// @{
FIELD(NeedOverloadResolutionForCopyConstructor, 1, NO_MERGE)
FIELD(NeedOverloadResolutionForMoveConstructor, 1, NO_MERGE)
+FIELD(NeedOverloadResolutionForCopyAssignment, 1, NO_MERGE)
FIELD(NeedOverloadResolutionForMoveAssignment, 1, NO_MERGE)
FIELD(NeedOverloadResolutionForDestructor, 1, NO_MERGE)
/// @}
/// @{
FIELD(DefaultedCopyConstructorIsDeleted, 1, NO_MERGE)
FIELD(DefaultedMoveConstructorIsDeleted, 1, NO_MERGE)
+FIELD(DefaultedCopyAssignmentIsDeleted, 1, NO_MERGE)
FIELD(DefaultedMoveAssignmentIsDeleted, 1, NO_MERGE)
FIELD(DefaultedDestructorIsDeleted, 1, NO_MERGE)
/// @}
}
/// \c true if we know for sure that this class has a single,
+ /// accessible, unambiguous copy assignment operator that is not deleted.
+ bool hasSimpleCopyAssignment() const {
+ return !hasUserDeclaredCopyAssignment() &&
+ !data().DefaultedCopyAssignmentIsDeleted;
+ }
+
+ /// \c true if we know for sure that this class has a single,
/// accessible, unambiguous move assignment operator that is not deleted.
bool hasSimpleMoveAssignment() const {
return !hasUserDeclaredMoveAssignment() && hasMoveAssignment() &&
return data().UserDeclaredSpecialMembers & SMF_CopyAssignment;
}
+ /// Set that we attempted to declare an implicit copy assignment
+ /// operator, but overload resolution failed so we deleted it.
+ void setImplicitCopyAssignmentIsDeleted() {
+ assert((data().DefaultedCopyAssignmentIsDeleted ||
+ needsOverloadResolutionForCopyAssignment()) &&
+ "copy assignment should not be deleted");
+ data().DefaultedCopyAssignmentIsDeleted = true;
+ }
+
/// Determine whether this class needs an implicit copy
/// assignment operator to be lazily declared.
bool needsImplicitCopyAssignment() const {
/// Determine whether we need to eagerly declare a defaulted copy
/// assignment operator for this class.
bool needsOverloadResolutionForCopyAssignment() const {
- return data().HasMutableFields;
+ // C++20 [class.copy.assign]p2:
+ // If the class definition declares a move constructor or move assignment
+ // operator, the implicitly declared copy assignment operator is defined
+ // as deleted.
+ // In MSVC mode, sometimes a declared move constructor does not delete an
+ // implicit copy assignment, so defer this choice to Sema.
+ if (data().UserDeclaredSpecialMembers &
+ (SMF_MoveConstructor | SMF_MoveAssignment))
+ return true;
+ return data().NeedOverloadResolutionForCopyAssignment;
}
/// Determine whether an implicit copy assignment operator for this
return CDeclOrErr.takeError();
D2CXX->setLambdaMangling(DCXX->getLambdaManglingNumber(), *CDeclOrErr,
DCXX->hasKnownLambdaInternalLinkage());
- } else if (DCXX->isInjectedClassName()) {
+ } else if (DCXX->isInjectedClassName()) {
// We have to be careful to do a similar dance to the one in
// Sema::ActOnStartCXXMemberDeclarations
const bool DelayTypeCreation = true;
HasInheritedConstructor(false), HasInheritedAssignment(false),
NeedOverloadResolutionForCopyConstructor(false),
NeedOverloadResolutionForMoveConstructor(false),
+ NeedOverloadResolutionForCopyAssignment(false),
NeedOverloadResolutionForMoveAssignment(false),
NeedOverloadResolutionForDestructor(false),
DefaultedCopyConstructorIsDeleted(false),
DefaultedMoveConstructorIsDeleted(false),
+ DefaultedCopyAssignmentIsDeleted(false),
DefaultedMoveAssignmentIsDeleted(false),
DefaultedDestructorIsDeleted(false), HasTrivialSpecialMembers(SMF_All),
HasTrivialSpecialMembersForCall(SMF_All),
setArgPassingRestrictions(RecordDecl::APK_CanNeverPassInRegs);
// Keep track of the presence of mutable fields.
- if (BaseClassDecl->hasMutableFields()) {
+ if (BaseClassDecl->hasMutableFields())
data().HasMutableFields = true;
- data().NeedOverloadResolutionForCopyConstructor = true;
- }
if (BaseClassDecl->hasUninitializedReferenceMember())
data().HasUninitializedReferenceMember = true;
// -- a direct or virtual base class B that cannot be copied/moved [...]
// -- a non-static data member of class type M (or array thereof)
// that cannot be copied or moved [...]
+ if (!Subobj->hasSimpleCopyAssignment())
+ data().NeedOverloadResolutionForCopyAssignment = true;
if (!Subobj->hasSimpleMoveAssignment())
data().NeedOverloadResolutionForMoveAssignment = true;
}
// Keep track of the presence of mutable fields.
- if (Field->isMutable()) {
+ if (Field->isMutable())
data().HasMutableFields = true;
- data().NeedOverloadResolutionForCopyConstructor = true;
- }
// C++11 [class.union]p8, DR1460:
// If X is a union, a non-static data member of X that is not an anonymous
if (isUnion()) {
data().DefaultedCopyConstructorIsDeleted = true;
data().DefaultedMoveConstructorIsDeleted = true;
+ data().DefaultedCopyAssignmentIsDeleted = true;
data().DefaultedMoveAssignmentIsDeleted = true;
data().DefaultedDestructorIsDeleted = true;
data().NeedOverloadResolutionForCopyConstructor = true;
data().NeedOverloadResolutionForMoveConstructor = true;
+ data().NeedOverloadResolutionForCopyAssignment = true;
data().NeedOverloadResolutionForMoveAssignment = true;
data().NeedOverloadResolutionForDestructor = true;
}
// A defaulted copy/move assignment operator for a class X is defined
// as deleted if X has:
// -- a non-static data member of reference type
- if (T->isReferenceType())
+ if (T->isReferenceType()) {
+ data().DefaultedCopyAssignmentIsDeleted = true;
data().DefaultedMoveAssignmentIsDeleted = true;
+ }
// Bitfields of length 0 are also zero-sized, but we already bailed out for
// those because they are always unnamed.
// parameter.
data().NeedOverloadResolutionForCopyConstructor = true;
data().NeedOverloadResolutionForMoveConstructor = true;
+ data().NeedOverloadResolutionForCopyAssignment = true;
data().NeedOverloadResolutionForMoveAssignment = true;
}
data().DefaultedCopyConstructorIsDeleted = true;
if (FieldRec->hasNonTrivialMoveConstructor())
data().DefaultedMoveConstructorIsDeleted = true;
+ if (FieldRec->hasNonTrivialCopyAssignment())
+ data().DefaultedCopyAssignmentIsDeleted = true;
if (FieldRec->hasNonTrivialMoveAssignment())
data().DefaultedMoveAssignmentIsDeleted = true;
if (FieldRec->hasNonTrivialDestructor())
FieldRec->data().NeedOverloadResolutionForCopyConstructor;
data().NeedOverloadResolutionForMoveConstructor |=
FieldRec->data().NeedOverloadResolutionForMoveConstructor;
+ data().NeedOverloadResolutionForCopyAssignment |=
+ FieldRec->data().NeedOverloadResolutionForCopyAssignment;
data().NeedOverloadResolutionForMoveAssignment |=
FieldRec->data().NeedOverloadResolutionForMoveAssignment;
data().NeedOverloadResolutionForDestructor |=
}
// Keep track of the presence of mutable fields.
- if (FieldRec->hasMutableFields()) {
+ if (FieldRec->hasMutableFields())
data().HasMutableFields = true;
+
+ if (Field->isMutable()) {
+ // Our copy constructor/assignment might call something other than
+ // the subobject's copy constructor/assignment if it's mutable and of
+ // class type.
data().NeedOverloadResolutionForCopyConstructor = true;
+ data().NeedOverloadResolutionForCopyAssignment = true;
}
// C++11 [class.copy]p13:
// as deleted if X has:
// -- a non-static data member of const non-class type (or array
// thereof)
- if (T.isConstQualified())
+ if (T.isConstQualified()) {
+ data().DefaultedCopyAssignmentIsDeleted = true;
data().DefaultedMoveAssignmentIsDeleted = true;
+ }
}
// C++14 [meta.unary.prop]p4:
*ToCapture++ = Captures[I];
}
+
+ if (!lambdaIsDefaultConstructibleAndAssignable())
+ Data.DefaultedCopyAssignmentIsDeleted = true;
}
void CXXRecordDecl::setTrivialForCallFlags(CXXMethodDecl *D) {
createCopyAssignmentDefinitionData(const CXXRecordDecl *RD) {
llvm::json::Object Ret;
+ FIELD2("simple", hasSimpleCopyAssignment);
FIELD2("trivial", hasTrivialCopyAssignment);
FIELD2("nonTrivial", hasNonTrivialCopyAssignment);
FIELD2("hasConstParam", hasCopyAssignmentWithConstParam);
ColorScope Color(OS, ShowColors, DeclKindNameColor);
OS << "CopyAssignment";
}
+ FLAG(hasSimpleCopyAssignment, simple);
FLAG(hasTrivialCopyAssignment, trivial);
FLAG(hasNonTrivialCopyAssignment, non_trivial);
FLAG(hasCopyAssignmentWithConstParam, has_const_param);
Scope *S = getScopeForContext(ClassDecl);
CheckImplicitSpecialMemberDeclaration(S, CopyAssignment);
- if (ShouldDeleteSpecialMember(CopyAssignment, CXXCopyAssignment))
+ if (ShouldDeleteSpecialMember(CopyAssignment, CXXCopyAssignment)) {
+ ClassDecl->setImplicitCopyAssignmentIsDeleted();
SetDeclDeleted(CopyAssignment, ClassLoc);
+ }
if (S)
PushOnScopeChains(CopyAssignment, S, false);
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: DefaultConstructor exists trivial constexpr\r
// CHECK-NEXT: CopyConstructor simple trivial has_const_param\r
// CHECK-NEXT: MoveConstructor exists simple trivial\r
-// CHECK-NEXT: CopyAssignment trivial has_const_param\r
+// CHECK-NEXT: CopyAssignment simple trivial has_const_param\r
// CHECK-NEXT: MoveAssignment exists simple trivial\r
// CHECK-NEXT: Destructor simple irrelevant trivial\r
\r
// CHECK-NEXT: DefaultConstructor exists non_trivial\r
// CHECK-NEXT: CopyConstructor simple non_trivial has_const_param\r
// CHECK-NEXT: MoveConstructor exists simple non_trivial\r
-// CHECK-NEXT: CopyAssignment non_trivial has_const_param\r
+// CHECK-NEXT: CopyAssignment simple non_trivial has_const_param\r
// CHECK-NEXT: MoveAssignment exists simple non_trivial\r
// CHECK-NEXT: Destructor simple irrelevant trivial\r
// CHECK-NEXT: virtual private 'testCXXRecordDecl::A'\r
// CHECK-NEXT: | | |-DefaultConstructor exists non_trivial user_provided\r
// CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param\r
// CHECK-NEXT: | | |-MoveConstructor\r
-// CHECK-NEXT: | | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param\r
+// CHECK-NEXT: | | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param\r
// CHECK-NEXT: | | |-MoveAssignment\r
// CHECK-NEXT: | | `-Destructor non_trivial user_declared\r
// CHECK-NEXT: | |-CXXRecordDecl 0x{{.+}} <col:24, col:30> col:30 implicit referenced class TestClassTemplate\r
// CHECK-NEXT: | | |-DefaultConstructor exists non_trivial user_provided\r
// CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param implicit_has_const_param\r
// CHECK-NEXT: | | |-MoveConstructor\r
-// CHECK-NEXT: | | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param\r
+// CHECK-NEXT: | | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param\r
// CHECK-NEXT: | | |-MoveAssignment\r
// CHECK-NEXT: | | `-Destructor non_trivial user_declared\r
// CHECK-NEXT: | |-TemplateArgument type 'testClassTemplateDecl::A'\r
// CHECK-NEXT: | |-DefaultConstructor exists trivial needs_implicit\r
// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param\r
// CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit\r
-// CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param\r
+// CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param\r
// CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit\r
// CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit\r
// CHECK-NEXT: |-TemplateArgument type 'testClassTemplateDecl::B'\r
// CHECK-NEXT: | |-DefaultConstructor exists non_trivial user_provided\r
// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param\r
// CHECK-NEXT: | |-MoveConstructor\r
-// CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param\r
+// CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param\r
// CHECK-NEXT: | |-MoveAssignment\r
// CHECK-NEXT: | `-Destructor non_trivial user_declared\r
// CHECK-NEXT: |-TemplateArgument type 'testClassTemplateDecl::C'\r
// CHECK-NEXT: | |-DefaultConstructor exists non_trivial user_provided\r
// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param\r
// CHECK-NEXT: | |-MoveConstructor\r
-// CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param\r
+// CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param\r
// CHECK-NEXT: | |-MoveAssignment\r
// CHECK-NEXT: | `-Destructor non_trivial user_declared\r
// CHECK-NEXT: |-TemplateArgument type 'testClassTemplateDecl::D'\r
// CHECK-NEXT: | |-DefaultConstructor exists trivial needs_implicit\r
// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param\r
// CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit\r
-// CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param\r
+// CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param\r
// CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit\r
// CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit\r
// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} <col:38, col:44> col:44 implicit class TestClassTemplatePartial\r
// CHECK-NEXT: | |-DefaultConstructor exists trivial needs_implicit\r
// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param\r
// CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit\r
-// CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param\r
+// CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param\r
// CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit\r
// CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit\r
// CHECK-NEXT: |-TemplateArgument type 'type-parameter-0-0'\r
// CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr\r
// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param\r
// CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit\r
-// CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param\r
+// CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param\r
// CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit\r
// CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit\r
// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} <col:24, col:31> col:31 implicit struct TestTemplateDefaultType\r
// CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr\r
// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param\r
// CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit\r
-// CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param\r
+// CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param\r
// CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit\r
// CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit\r
// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} <col:41, col:48> col:48 implicit struct TestTemplateTemplateDefaultType\r
// CHECK-NEXT: | | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr\r
// CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param\r
// CHECK-NEXT: | | |-MoveConstructor exists simple trivial needs_implicit\r
- // CHECK-NEXT: | | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param\r
+ // CHECK-NEXT: | | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param\r
// CHECK-NEXT: | | |-MoveAssignment exists simple trivial needs_implicit\r
// CHECK-NEXT: | | `-Destructor simple irrelevant trivial needs_implicit\r
// CHECK-NEXT: | |-CXXRecordDecl 0x{{.+}} <col:25, col:31> col:31 implicit class TestClassTemplate\r
// CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr defaulted_is_constexpr\r
// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param implicit_has_const_param\r
// CHECK-NEXT: | |-MoveConstructor exists simple trivial\r
- // CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param\r
+ // CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param\r
// CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit\r
// CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit\r
// CHECK-NEXT: |-TemplateArgument type 'testCanonicalTemplate::A'\r
// CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr defaulted_is_constexpr\r
// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param implicit_has_const_param\r
// CHECK-NEXT: | |-MoveConstructor exists simple trivial\r
- // CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param\r
+ // CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param\r
// CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit\r
// CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit\r
// CHECK-NEXT: |-TemplateArgument type 'testCanonicalTemplate::A'\r
// CHECK-NEXT: | | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr\r
// CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param\r
// CHECK-NEXT: | | |-MoveConstructor exists simple trivial needs_implicit\r
- // CHECK-NEXT: | | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param\r
+ // CHECK-NEXT: | | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param\r
// CHECK-NEXT: | | |-MoveAssignment exists simple trivial needs_implicit\r
// CHECK-NEXT: | | `-Destructor simple irrelevant trivial needs_implicit\r
// CHECK-NEXT: | `-CXXRecordDecl 0x{{.+}} <col:25, col:31> col:31 implicit class TestClassTemplate2\r
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "id": "0x{{.*}}",
// CHECK-NEXT: "kind": "TemplateTypeParmDecl",
// CHECK-NEXT: "loc": {
+// CHECK-NEXT: "offset": 197,
+// CHECK-NEXT: "col": 33,
+// CHECK-NEXT: "tokLen": 1
+// CHECK-NEXT: },
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "begin": {
+// CHECK-NEXT: "offset": 193,
+// CHECK-NEXT: "col": 29,
+// CHECK-NEXT: "tokLen": 4
+// CHECK-NEXT: },
+// CHECK-NEXT: "end": {
// CHECK-NEXT: "offset": 197,
// CHECK-NEXT: "col": 33,
// CHECK-NEXT: "tokLen": 1
-// CHECK-NEXT: },
-// CHECK-NEXT: "range": {
-// CHECK-NEXT: "begin": {
-// CHECK-NEXT: "offset": 193,
-// CHECK-NEXT: "col": 29,
-// CHECK-NEXT: "tokLen": 4
-// CHECK-NEXT: },
-// CHECK-NEXT: "end": {
-// CHECK-NEXT: "offset": 197,
-// CHECK-NEXT: "col": 33,
-// CHECK-NEXT: "tokLen": 1
-// CHECK-NEXT: }
+// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "isImplicit": true,
// CHECK-NEXT: "name": "auto:1",
// CHECK-NEXT: "id": "0x{{.*}}",
// CHECK-NEXT: "kind": "TemplateTypeParmDecl",
// CHECK-NEXT: "loc": {
+// CHECK-NEXT: "offset": 197,
+// CHECK-NEXT: "col": 33,
+// CHECK-NEXT: "tokLen": 1
+// CHECK-NEXT: },
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "begin": {
+// CHECK-NEXT: "offset": 193,
+// CHECK-NEXT: "col": 29,
+// CHECK-NEXT: "tokLen": 4
+// CHECK-NEXT: },
+// CHECK-NEXT: "end": {
// CHECK-NEXT: "offset": 197,
// CHECK-NEXT: "col": 33,
// CHECK-NEXT: "tokLen": 1
-// CHECK-NEXT: },
-// CHECK-NEXT: "range": {
-// CHECK-NEXT: "begin": {
-// CHECK-NEXT: "offset": 193,
-// CHECK-NEXT: "col": 29,
-// CHECK-NEXT: "tokLen": 4
-// CHECK-NEXT: },
-// CHECK-NEXT: "end": {
-// CHECK-NEXT: "offset": 197,
-// CHECK-NEXT: "col": 33,
-// CHECK-NEXT: "tokLen": 1
-// CHECK-NEXT: }
+// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "isImplicit": true,
// CHECK-NEXT: "name": "auto:1",
// CHECK-NEXT: "id": "0x{{.*}}",
// CHECK-NEXT: "kind": "TemplateTypeParmDecl",
// CHECK-NEXT: "loc": {
+// CHECK-NEXT: "offset": 197,
+// CHECK-NEXT: "col": 33,
+// CHECK-NEXT: "tokLen": 1
+// CHECK-NEXT: },
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "begin": {
+// CHECK-NEXT: "offset": 193,
+// CHECK-NEXT: "col": 29,
+// CHECK-NEXT: "tokLen": 4
+// CHECK-NEXT: },
+// CHECK-NEXT: "end": {
// CHECK-NEXT: "offset": 197,
// CHECK-NEXT: "col": 33,
// CHECK-NEXT: "tokLen": 1
-// CHECK-NEXT: },
-// CHECK-NEXT: "range": {
-// CHECK-NEXT: "begin": {
-// CHECK-NEXT: "offset": 193,
-// CHECK-NEXT: "col": 29,
-// CHECK-NEXT: "tokLen": 4
-// CHECK-NEXT: },
-// CHECK-NEXT: "end": {
-// CHECK-NEXT: "offset": 197,
-// CHECK-NEXT: "col": 33,
-// CHECK-NEXT: "tokLen": 1
-// CHECK-NEXT: }
+// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "isImplicit": true,
// CHECK-NEXT: "name": "auto:1",
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "copyAssign": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
-// CHECK-NEXT: "nonTrivial": true
+// CHECK-NEXT: "nonTrivial": true,
+// CHECK-NEXT: "simple": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "copyAssign": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
-// CHECK-NEXT: "nonTrivial": true
+// CHECK-NEXT: "nonTrivial": true,
+// CHECK-NEXT: "simple": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "copyAssign": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
-// CHECK-NEXT: "nonTrivial": true
+// CHECK-NEXT: "nonTrivial": true,
+// CHECK-NEXT: "simple": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "copyAssign": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
-// CHECK-NEXT: "nonTrivial": true
+// CHECK-NEXT: "nonTrivial": true,
+// CHECK-NEXT: "simple": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "copyAssign": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
-// CHECK-NEXT: "needsOverloadResolution": true,
+// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
-// CHECK-NEXT: "needsOverloadResolution": true,
+// CHECK-NEXT: "needsImplicit": true,
// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "qualType": "int"
// CHECK-NEXT: },
// CHECK-NEXT: "mutable": true
-// CHECK-NEXT: },
-// CHECK-NEXT: {
-// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "CXXConstructorDecl",
-// CHECK-NEXT: "loc": {
-// CHECK-NEXT: "offset": 1497,
-// CHECK-NEXT: "line": 102,
-// CHECK-NEXT: "col": 8,
-// CHECK-NEXT: "tokLen": 16
-// CHECK-NEXT: },
-// CHECK-NEXT: "range": {
-// CHECK-NEXT: "begin": {
-// CHECK-NEXT: "offset": 1497,
-// CHECK-NEXT: "col": 8,
-// CHECK-NEXT: "tokLen": 16
-// CHECK-NEXT: },
-// CHECK-NEXT: "end": {
-// CHECK-NEXT: "offset": 1497,
-// CHECK-NEXT: "col": 8,
-// CHECK-NEXT: "tokLen": 16
-// CHECK-NEXT: }
-// CHECK-NEXT: },
-// CHECK-NEXT: "isImplicit": true,
-// CHECK-NEXT: "name": "HasMutableFields",
-// CHECK-NEXT: "mangledName": "_ZN16HasMutableFieldsC1ERKS_",
-// CHECK-NEXT: "type": {
-// CHECK-NEXT: "qualType": "void (const HasMutableFields &)"
-// CHECK-NEXT: },
-// CHECK-NEXT: "inline": true,
-// CHECK-NEXT: "constexpr": true,
-// CHECK-NEXT: "explicitlyDefaulted": "default",
-// CHECK-NEXT: "inner": [
-// CHECK-NEXT: {
-// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "ParmVarDecl",
-// CHECK-NEXT: "loc": {
-// CHECK-NEXT: "offset": 1497,
-// CHECK-NEXT: "col": 8,
-// CHECK-NEXT: "tokLen": 16
-// CHECK-NEXT: },
-// CHECK-NEXT: "range": {
-// CHECK-NEXT: "begin": {
-// CHECK-NEXT: "offset": 1497,
-// CHECK-NEXT: "col": 8,
-// CHECK-NEXT: "tokLen": 16
-// CHECK-NEXT: },
-// CHECK-NEXT: "end": {
-// CHECK-NEXT: "offset": 1497,
-// CHECK-NEXT: "col": 8,
-// CHECK-NEXT: "tokLen": 16
-// CHECK-NEXT: }
-// CHECK-NEXT: },
-// CHECK-NEXT: "type": {
-// CHECK-NEXT: "qualType": "const HasMutableFields &"
-// CHECK-NEXT: }
-// CHECK-NEXT: }
-// CHECK-NEXT: ]
-// CHECK-NEXT: },
-// CHECK-NEXT: {
-// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "CXXMethodDecl",
-// CHECK-NEXT: "loc": {
-// CHECK-NEXT: "offset": 1497,
-// CHECK-NEXT: "col": 8,
-// CHECK-NEXT: "tokLen": 16
-// CHECK-NEXT: },
-// CHECK-NEXT: "range": {
-// CHECK-NEXT: "begin": {
-// CHECK-NEXT: "offset": 1497,
-// CHECK-NEXT: "col": 8,
-// CHECK-NEXT: "tokLen": 16
-// CHECK-NEXT: },
-// CHECK-NEXT: "end": {
-// CHECK-NEXT: "offset": 1497,
-// CHECK-NEXT: "col": 8,
-// CHECK-NEXT: "tokLen": 16
-// CHECK-NEXT: }
-// CHECK-NEXT: },
-// CHECK-NEXT: "isImplicit": true,
-// CHECK-NEXT: "name": "operator=",
-// CHECK-NEXT: "mangledName": "_ZN16HasMutableFieldsaSERKS_",
-// CHECK-NEXT: "type": {
-// CHECK-NEXT: "qualType": "HasMutableFields &(const HasMutableFields &)"
-// CHECK-NEXT: },
-// CHECK-NEXT: "inline": true,
-// CHECK-NEXT: "constexpr": true,
-// CHECK-NEXT: "explicitlyDefaulted": "default",
-// CHECK-NEXT: "inner": [
-// CHECK-NEXT: {
-// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "ParmVarDecl",
-// CHECK-NEXT: "loc": {
-// CHECK-NEXT: "offset": 1497,
-// CHECK-NEXT: "col": 8,
-// CHECK-NEXT: "tokLen": 16
-// CHECK-NEXT: },
-// CHECK-NEXT: "range": {
-// CHECK-NEXT: "begin": {
-// CHECK-NEXT: "offset": 1497,
-// CHECK-NEXT: "col": 8,
-// CHECK-NEXT: "tokLen": 16
-// CHECK-NEXT: },
-// CHECK-NEXT: "end": {
-// CHECK-NEXT: "offset": 1497,
-// CHECK-NEXT: "col": 8,
-// CHECK-NEXT: "tokLen": 16
-// CHECK-NEXT: }
-// CHECK-NEXT: },
-// CHECK-NEXT: "type": {
-// CHECK-NEXT: "qualType": "const HasMutableFields &"
-// CHECK-NEXT: }
-// CHECK-NEXT: }
-// CHECK-NEXT: ]
// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-NEXT: }
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "copyAssign": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "copyAssign": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "copyAssign": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "copyAssign": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
-// CHECK-NEXT: "nonTrivial": true
+// CHECK-NEXT: "nonTrivial": true,
+// CHECK-NEXT: "simple": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "copyAssign": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
-// CHECK-NEXT: "nonTrivial": true
+// CHECK-NEXT: "nonTrivial": true,
+// CHECK-NEXT: "simple": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "copyAssign": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
-// CHECK-NEXT: "nonTrivial": true
+// CHECK-NEXT: "nonTrivial": true,
+// CHECK-NEXT: "simple": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: DefaultConstructor exists trivial needs_implicit
// CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit
- // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+ // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit
// CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit
// CHECK-NEXT: DefaultConstructor exists trivial needs_implicit
// CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit
- // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+ // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit
// CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit
// CHECK-NEXT: DefaultConstructor exists trivial needs_implicit
// CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit
- // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+ // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit
// CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit
int a;
// CHECK-NEXT: DefaultConstructor exists trivial needs_implicit
// CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit
- // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+ // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit
// CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit
int c;
// CHECK-NEXT: DefaultConstructor exists trivial needs_implicit
// CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit
- // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+ // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit
// CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit
int e, f;
// CHECK-NEXT: DefaultConstructor exists trivial needs_implicit
// CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit
- // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+ // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit
// CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit
// CHECK-NEXT: DefaultConstructor exists trivial needs_implicit
// CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit
- // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+ // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit
// CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit
// CHECK-NEXT: DefaultConstructor exists trivial needs_implicit
// CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit
- // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+ // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit
// CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit
// CHECK-NEXT: DefaultConstructor exists trivial needs_implicit
// CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit
- // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+ // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit
// CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit
// CHECK-NEXT: DefaultConstructor exists trivial needs_implicit
// CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit
- // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+ // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit
// CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit
// CHECK-NEXT: DefaultConstructor exists trivial needs_implicit
// CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit
- // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+ // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit
// CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit
DoesNotNeedImplicitCopyAssignment& operator=(const DoesNotNeedImplicitCopyAssignment&) {}
};
+struct DeclaresCopyAssignment {
+ DeclaresCopyAssignment &operator=(const DeclaresCopyAssignment&) &;
+};
+
struct CopyAssignmentNeedsOverloadResolution {
// CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct CopyAssignmentNeedsOverloadResolution definition
// CHECK: CopyAssignment {{.*}}needs_overload_resolution{{.*}}
- mutable int i;
+ DeclaresCopyAssignment i;
};
struct CopyAssignmentDoesNotNeedOverloadResolution {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
// CHECK-NEXT: "hasConstParam": true,
// CHECK-NEXT: "implicitHasConstParam": true,
// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
// CHECK-NEXT: "trivial": true
// CHECK-NEXT: },
// CHECK-NEXT: "copyCtor": {
};
bool b = __has_unique_object_representations(T);
};
+
+namespace PR46209 {
+ // Foo has both a trivial assignment operator and a non-trivial one.
+ struct Foo {
+ Foo &operator=(const Foo &) & { return *this; }
+ Foo &operator=(const Foo &) && = default;
+ };
+
+ // Bar's copy assignment calls Foo's non-trivial assignment.
+ struct Bar {
+ Foo foo;
+ };
+
+ static_assert(!__is_trivially_assignable(Foo &, const Foo &), "");
+ static_assert(!__is_trivially_assignable(Bar &, const Bar &), "");
+
+ // Foo2 has both a trivial assignment operator and a non-trivial one.
+ struct Foo2 {
+ Foo2 &operator=(const Foo2 &) & = default;
+ Foo2 &operator=(const Foo2 &) && { return *this; }
+ };
+
+ // Bar2's copy assignment calls Foo2's trivial assignment.
+ struct Bar2 {
+ Foo2 foo;
+ };
+
+ static_assert(__is_trivially_assignable(Foo2 &, const Foo2 &), "");
+ static_assert(__is_trivially_assignable(Bar2 &, const Bar2 &), "");
+}
+
+namespace ConstClass {
+ struct A {
+ A &operator=(const A&) = default;
+ };
+ struct B {
+ const A a;
+ };
+ static_assert(!__is_trivially_assignable(B&, const B&), "");
+}
struct S1 {
union {
- union { // expected-note 2 {{'S1' is implicitly deleted because variant field '' has a non-trivial}} expected-note 5 {{'S1' is implicitly deleted because field '' has a deleted}}
+ union { // expected-note 7 {{'S1' is implicitly deleted because field '' has a deleted}}
id f0; // expected-note 3 {{'' is implicitly deleted because variant field 'f0' is an ObjC pointer}}
char f1;
};
}
TEST(Matcher, MatchesCopyAssignmentOperator) {
- EXPECT_TRUE(matches("class X { X &operator=(X); };",
- cxxMethodDecl(isCopyAssignmentOperator())));
- EXPECT_TRUE(matches("class X { X &operator=(X &); };",
- cxxMethodDecl(isCopyAssignmentOperator())));
- EXPECT_TRUE(matches("class X { X &operator=(const X &); };",
- cxxMethodDecl(isCopyAssignmentOperator())));
- EXPECT_TRUE(matches("class X { X &operator=(volatile X &); };",
- cxxMethodDecl(isCopyAssignmentOperator())));
+ auto CopyAssignment =
+ cxxMethodDecl(isCopyAssignmentOperator(), unless(isImplicit()));
+ EXPECT_TRUE(matches("class X { X &operator=(X); };", CopyAssignment));
+ EXPECT_TRUE(matches("class X { X &operator=(X &); };", CopyAssignment));
+ EXPECT_TRUE(matches("class X { X &operator=(const X &); };", CopyAssignment));
+ EXPECT_TRUE(matches("class X { X &operator=(volatile X &); };", //
+ CopyAssignment));
EXPECT_TRUE(matches("class X { X &operator=(const volatile X &); };",
- cxxMethodDecl(isCopyAssignmentOperator())));
- EXPECT_TRUE(notMatches("class X { X &operator=(X &&); };",
- cxxMethodDecl(isCopyAssignmentOperator())));
+ CopyAssignment));
+ EXPECT_TRUE(notMatches("class X { X &operator=(X &&); };", CopyAssignment));
}
TEST(Matcher, MatchesMoveAssignmentOperator) {
- EXPECT_TRUE(notMatches("class X { X &operator=(X); };",
- cxxMethodDecl(isMoveAssignmentOperator())));
- EXPECT_TRUE(matches("class X { X &operator=(X &&); };",
- cxxMethodDecl(isMoveAssignmentOperator())));
- EXPECT_TRUE(matches("class X { X &operator=(const X &&); };",
- cxxMethodDecl(isMoveAssignmentOperator())));
- EXPECT_TRUE(matches("class X { X &operator=(volatile X &&); };",
- cxxMethodDecl(isMoveAssignmentOperator())));
+ auto MoveAssignment =
+ cxxMethodDecl(isMoveAssignmentOperator(), unless(isImplicit()));
+ EXPECT_TRUE(notMatches("class X { X &operator=(X); };", MoveAssignment));
+ EXPECT_TRUE(matches("class X { X &operator=(X &&); };", MoveAssignment));
+ EXPECT_TRUE(matches("class X { X &operator=(const X &&); };", //
+ MoveAssignment));
+ EXPECT_TRUE(matches("class X { X &operator=(volatile X &&); };", //
+ MoveAssignment));
EXPECT_TRUE(matches("class X { X &operator=(const volatile X &&); };",
- cxxMethodDecl(isMoveAssignmentOperator())));
- EXPECT_TRUE(notMatches("class X { X &operator=(X &); };",
- cxxMethodDecl(isMoveAssignmentOperator())));
+ MoveAssignment));
+ EXPECT_TRUE(notMatches("class X { X &operator=(X &); };", MoveAssignment));
}
TEST(Matcher, MatchesConstMethod) {