if (HasTrivialABI)
Record->setHasTrivialSpecialMemberForCall();
+ auto CompleteMemberFunction = [&](CXXMethodDecl *M) {
+ // Check whether the explicitly-defaulted special members are valid.
+ if (!M->isInvalidDecl() && M->isExplicitlyDefaulted())
+ CheckExplicitlyDefaultedSpecialMember(M);
+
+ // For an explicitly defaulted or deleted special member, we defer
+ // determining triviality until the class is complete. That time is now!
+ CXXSpecialMember CSM = getSpecialMember(M);
+ if (!M->isImplicit() && !M->isUserProvided()) {
+ if (CSM != CXXInvalid) {
+ M->setTrivial(SpecialMemberIsTrivial(M, CSM));
+ // Inform the class that we've finished declaring this member.
+ Record->finishedDefaultedOrDeletedMember(M);
+ M->setTrivialForCall(
+ HasTrivialABI ||
+ SpecialMemberIsTrivial(M, CSM, TAH_ConsiderTrivialABI));
+ Record->setTrivialForCallFlags(M);
+ }
+ }
+
+ // Set triviality for the purpose of calls if this is a user-provided
+ // copy/move constructor or destructor.
+ if ((CSM == CXXCopyConstructor || CSM == CXXMoveConstructor ||
+ CSM == CXXDestructor) && M->isUserProvided()) {
+ M->setTrivialForCall(HasTrivialABI);
+ Record->setTrivialForCallFlags(M);
+ }
+
+ if (!M->isInvalidDecl() && M->isExplicitlyDefaulted() &&
+ M->hasAttr<DLLExportAttr>()) {
+ if (getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015) &&
+ M->isTrivial() &&
+ (CSM == CXXDefaultConstructor || CSM == CXXCopyConstructor ||
+ CSM == CXXDestructor))
+ M->dropAttr<DLLExportAttr>();
+
+ if (M->hasAttr<DLLExportAttr>()) {
+ DefineImplicitSpecialMember(*this, M, M->getLocation());
+ ActOnFinishInlineFunctionDef(M);
+ }
+ }
+ };
+
bool HasMethodWithOverrideControl = false,
HasOverridingMethodWithoutOverrideControl = false;
if (!Record->isDependentType()) {
+ // Check the destructor before any other member function. We need to
+ // determine whether it's trivial in order to determine whether the claas
+ // type is a literal type, which is a prerequisite for determining whether
+ // other special member functions are valid and whether they're implicitly
+ // 'constexpr'.
+ if (CXXDestructorDecl *Dtor = Record->getDestructor())
+ CompleteMemberFunction(Dtor);
+
for (auto *M : Record->methods()) {
// See if a method overloads virtual methods in a base
// class without overriding any.
HasMethodWithOverrideControl = true;
else if (M->size_overridden_methods() > 0)
HasOverridingMethodWithoutOverrideControl = true;
- // Check whether the explicitly-defaulted special members are valid.
- if (!M->isInvalidDecl() && M->isExplicitlyDefaulted())
- CheckExplicitlyDefaultedSpecialMember(M);
-
- // For an explicitly defaulted or deleted special member, we defer
- // determining triviality until the class is complete. That time is now!
- CXXSpecialMember CSM = getSpecialMember(M);
- if (!M->isImplicit() && !M->isUserProvided()) {
- if (CSM != CXXInvalid) {
- M->setTrivial(SpecialMemberIsTrivial(M, CSM));
- // Inform the class that we've finished declaring this member.
- Record->finishedDefaultedOrDeletedMember(M);
- M->setTrivialForCall(
- HasTrivialABI ||
- SpecialMemberIsTrivial(M, CSM, TAH_ConsiderTrivialABI));
- Record->setTrivialForCallFlags(M);
- }
- }
-
- // Set triviality for the purpose of calls if this is a user-provided
- // copy/move constructor or destructor.
- if ((CSM == CXXCopyConstructor || CSM == CXXMoveConstructor ||
- CSM == CXXDestructor) && M->isUserProvided()) {
- M->setTrivialForCall(HasTrivialABI);
- Record->setTrivialForCallFlags(M);
- }
- if (!M->isInvalidDecl() && M->isExplicitlyDefaulted() &&
- M->hasAttr<DLLExportAttr>()) {
- if (getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015) &&
- M->isTrivial() &&
- (CSM == CXXDefaultConstructor || CSM == CXXCopyConstructor ||
- CSM == CXXDestructor))
- M->dropAttr<DLLExportAttr>();
-
- if (M->hasAttr<DLLExportAttr>()) {
- DefineImplicitSpecialMember(*this, M, M->getLocation());
- ActOnFinishInlineFunctionDef(M);
- }
- }
+ if (!isa<CXXDestructorDecl>(M))
+ CompleteMemberFunction(M);
}
}