summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2017-01-05 01:08:22 +0000
committerReid Kleckner <rnk@google.com>2017-01-05 01:08:22 +0000
commitf228bfa79ddef85ccdeef173a3e97fd6683e8f7c (patch)
tree3683e05e582445c98badcdfc2c40cc6c3f9a0b9f /lib/Sema/SemaDeclCXX.cpp
parentb0c114c8f684b3b8b8b5d37825a19a889589ebb3 (diff)
[MS] Instantiate default args during instantiation of exported default ctors
Summary: Replace some old code that probably pre-dated the change to delay emission of dllexported code until after the closing brace of the outermost record type. Only uninstantiated default argument expressions need to be handled now. It is enough to instantiate default argument expressions when instantiating dllexported default ctors. This also fixes some double-diagnostic issues in this area. Fixes PR31500 Reviewers: rsmith Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D28274 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@291045 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-rw-r--r--lib/Sema/SemaDeclCXX.cpp75
1 files changed, 21 insertions, 54 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 084bd4c45e..a650621b57 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -5395,6 +5395,26 @@ static void ReferenceDllExportedMethods(Sema &S, CXXRecordDecl *Class) {
}
}
+static void checkForMultipleExportedDefaultConstructors(Sema &S, CXXRecordDecl *Class) {
+ CXXConstructorDecl *LastExportedDefaultCtor = nullptr;
+ for (Decl *Member : Class->decls()) {
+ // Look for exported default constructors.
+ auto *CD = dyn_cast<CXXConstructorDecl>(Member);
+ if (!CD || !CD->isDefaultConstructor() || !CD->hasAttr<DLLExportAttr>())
+ continue;
+
+ if (LastExportedDefaultCtor) {
+ S.Diag(LastExportedDefaultCtor->getLocation(),
+ diag::err_attribute_dll_ambiguous_default_ctor)
+ << Class;
+ S.Diag(CD->getLocation(), diag::note_entity_declared_at)
+ << CD->getDeclName();
+ return;
+ }
+ LastExportedDefaultCtor = CD;
+ }
+}
+
/// \brief Check class-level dllimport/dllexport attribute.
void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) {
Attr *ClassAttr = getDLLAttr(Class);
@@ -10362,64 +10382,11 @@ void Sema::ActOnFinishCXXMemberDecls() {
DelayedExceptionSpecChecks.clear();
return;
}
- }
-}
-
-static void checkDefaultArgExprsForConstructors(Sema &S, CXXRecordDecl *Class) {
- // Don't do anything for template patterns.
- if (Class->getDescribedClassTemplate())
- return;
-
- CallingConv ExpectedCallingConv = S.Context.getDefaultCallingConvention(
- /*IsVariadic=*/false, /*IsCXXMethod=*/true);
-
- CXXConstructorDecl *LastExportedDefaultCtor = nullptr;
- for (Decl *Member : Class->decls()) {
- auto *CD = dyn_cast<CXXConstructorDecl>(Member);
- if (!CD) {
- // Recurse on nested classes.
- if (auto *NestedRD = dyn_cast<CXXRecordDecl>(Member))
- checkDefaultArgExprsForConstructors(S, NestedRD);
- continue;
- } else if (!CD->isDefaultConstructor() || !CD->hasAttr<DLLExportAttr>()) {
- continue;
- }
-
- CallingConv ActualCallingConv =
- CD->getType()->getAs<FunctionProtoType>()->getCallConv();
-
- // Skip default constructors with typical calling conventions and no default
- // arguments.
- unsigned NumParams = CD->getNumParams();
- if (ExpectedCallingConv == ActualCallingConv && NumParams == 0)
- continue;
-
- if (LastExportedDefaultCtor) {
- S.Diag(LastExportedDefaultCtor->getLocation(),
- diag::err_attribute_dll_ambiguous_default_ctor) << Class;
- S.Diag(CD->getLocation(), diag::note_entity_declared_at)
- << CD->getDeclName();
- return;
- }
- LastExportedDefaultCtor = CD;
-
- for (unsigned I = 0; I != NumParams; ++I) {
- (void)S.CheckCXXDefaultArgExpr(Class->getLocation(), CD,
- CD->getParamDecl(I));
- S.DiscardCleanupsInEvaluationContext();
- }
+ checkForMultipleExportedDefaultConstructors(*this, Record);
}
}
void Sema::ActOnFinishCXXNonNestedClass(Decl *D) {
- auto *RD = dyn_cast<CXXRecordDecl>(D);
-
- // Default constructors that are annotated with __declspec(dllexport) which
- // have default arguments or don't use the standard calling convention are
- // wrapped with a thunk called the default constructor closure.
- if (RD && Context.getTargetInfo().getCXXABI().isMicrosoft())
- checkDefaultArgExprsForConstructors(*this, RD);
-
referenceDLLExportedClassMethods();
}