diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 81 |
1 files changed, 52 insertions, 29 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index ca8ed71fcef..38b4acfbdc3 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -4811,11 +4811,17 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) { // MSVC versions before 2015 don't export the move assignment operators // and move constructor, so don't attempt to import/export them if // we have a definition. - auto *CXXC = dyn_cast<CXXConstructorDecl>(MD); + auto *Ctor = dyn_cast<CXXConstructorDecl>(MD); if ((MD->isMoveAssignmentOperator() || - (CXXC && CXXC->isMoveConstructor())) && + (Ctor && Ctor->isMoveConstructor())) && !getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015)) continue; + + // MSVC2015 doesn't export trivial defaulted x-tor but copy assign + // operator is exported anyway. + if (getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015) && + (Ctor || isa<CXXDestructorDecl>(MD)) && MD->isTrivial()) + continue; } } @@ -4889,6 +4895,33 @@ void Sema::propagateDLLAttrToBaseClassTemplate( } } +static void DefineImplicitSpecialMember(Sema &S, CXXMethodDecl *MD, + SourceLocation DefaultLoc) { + switch (S.getSpecialMember(MD)) { + case Sema::CXXDefaultConstructor: + S.DefineImplicitDefaultConstructor(DefaultLoc, + cast<CXXConstructorDecl>(MD)); + break; + case Sema::CXXCopyConstructor: + S.DefineImplicitCopyConstructor(DefaultLoc, cast<CXXConstructorDecl>(MD)); + break; + case Sema::CXXCopyAssignment: + S.DefineImplicitCopyAssignment(DefaultLoc, MD); + break; + case Sema::CXXDestructor: + S.DefineImplicitDestructor(DefaultLoc, cast<CXXDestructorDecl>(MD)); + break; + case Sema::CXXMoveConstructor: + S.DefineImplicitMoveConstructor(DefaultLoc, cast<CXXConstructorDecl>(MD)); + break; + case Sema::CXXMoveAssignment: + S.DefineImplicitMoveAssignment(DefaultLoc, MD); + break; + case Sema::CXXInvalid: + llvm_unreachable("Invalid special member."); + } +} + /// \brief Perform semantic checks on a class definition that has been /// completing, introducing implicitly-declared members, checking for /// abstract types, etc. @@ -4984,8 +5017,8 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) { // 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()) { - CXXSpecialMember CSM = getSpecialMember(M); if (CSM != CXXInvalid) { M->setTrivial(SpecialMemberIsTrivial(M, CSM)); @@ -4993,6 +5026,20 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) { Record->finishedDefaultedOrDeletedMember(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); + } + } } } @@ -13063,32 +13110,8 @@ void Sema::SetDeclDefaulted(Decl *Dcl, SourceLocation DefaultLoc) { CheckExplicitlyDefaultedSpecialMember(MD); - if (MD->isInvalidDecl()) - return; - - switch (Member) { - case CXXDefaultConstructor: - DefineImplicitDefaultConstructor(DefaultLoc, - cast<CXXConstructorDecl>(MD)); - break; - case CXXCopyConstructor: - DefineImplicitCopyConstructor(DefaultLoc, cast<CXXConstructorDecl>(MD)); - break; - case CXXCopyAssignment: - DefineImplicitCopyAssignment(DefaultLoc, MD); - break; - case CXXDestructor: - DefineImplicitDestructor(DefaultLoc, cast<CXXDestructorDecl>(MD)); - break; - case CXXMoveConstructor: - DefineImplicitMoveConstructor(DefaultLoc, cast<CXXConstructorDecl>(MD)); - break; - case CXXMoveAssignment: - DefineImplicitMoveAssignment(DefaultLoc, MD); - break; - case CXXInvalid: - llvm_unreachable("Invalid special member."); - } + if (!MD->isInvalidDecl()) + DefineImplicitSpecialMember(*this, MD, DefaultLoc); } else { Diag(DefaultLoc, diag::err_default_special_members); } |