diff options
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 92 |
1 files changed, 53 insertions, 39 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 35863a32662..0956aff21e1 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -6125,9 +6125,60 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) { 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. @@ -6137,46 +6188,9 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) { 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); } } |