summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2015-03-17 19:00:50 +0000
committerReid Kleckner <reid@kleckner.net>2015-03-17 19:00:50 +0000
commitbba3cb95cc548e8700eaf00f74268c1cfcef2fa8 (patch)
tree7ef4d47f50ac517278043a5b855e70d1c8427257 /clang/lib/Sema/SemaDeclCXX.cpp
parent426025222228658060bba5aaea98a1bc1b090cb0 (diff)
downloadbcm5719-llvm-bba3cb95cc548e8700eaf00f74268c1cfcef2fa8.tar.gz
bcm5719-llvm-bba3cb95cc548e8700eaf00f74268c1cfcef2fa8.zip
MS ABI: Delay default constructor closure checking until the outermost class scope ends
Previously, we would error out on this code because the default argument wasn't parsed until the end of Outer: struct __declspec(dllexport) Outer { struct __declspec(dllexport) Inner { Inner(void *p = 0); }; }; Now we do the checking on the closing brace of Outer instead of Inner. llvm-svn: 232519
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp38
1 files changed, 38 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 45ba685d118..4e64595e114 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -9421,6 +9421,44 @@ void Sema::ActOnFinishCXXMemberDecls() {
}
}
+static void getDefaultArgExprsForConstructors(Sema &S, CXXRecordDecl *Class) {
+ // Don't do anything for template patterns.
+ if (Class->getDescribedClassTemplate())
+ return;
+
+ for (Decl *Member : Class->decls()) {
+ auto *CD = dyn_cast<CXXConstructorDecl>(Member);
+ if (!CD) {
+ // Recurse on nested classes.
+ if (auto *NestedRD = dyn_cast<CXXRecordDecl>(Member))
+ getDefaultArgExprsForConstructors(S, NestedRD);
+ continue;
+ } else if (!CD->isDefaultConstructor() || !CD->hasAttr<DLLExportAttr>()) {
+ continue;
+ }
+
+ for (unsigned I = 0, E = CD->getNumParams(); I != E; ++I) {
+ // Skip any default arguments that we've already instantiated.
+ if (S.Context.getDefaultArgExprForConstructor(CD, I))
+ continue;
+
+ Expr *DefaultArg = S.BuildCXXDefaultArgExpr(Class->getLocation(), CD,
+ CD->getParamDecl(I)).get();
+ S.Context.addDefaultArgExprForConstructor(CD, I, DefaultArg);
+ }
+ }
+}
+
+void Sema::ActOnFinishCXXMethodDefs(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())
+ getDefaultArgExprsForConstructors(*this, RD);
+}
+
void Sema::AdjustDestructorExceptionSpec(CXXRecordDecl *ClassDecl,
CXXDestructorDecl *Destructor) {
assert(getLangOpts().CPlusPlus11 &&
OpenPOWER on IntegriCloud