summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp81
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);
}
OpenPOWER on IntegriCloud