From 37fd66e78bc578e07b5b3fa61bb96e1432a2543e Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Fri, 13 Mar 2015 22:36:55 +0000 Subject: MS ABI: Generate default constructor closures The MS ABI utilizes a compiler generated function called the "vector constructor iterator" to construct arrays of objects with non-trivial constructors/destructors. For this to work, the constructor must follow a specific calling convention. A thunk must be created if the default constructor has default arguments, is variadic or is otherwise incompatible. This thunk is called the default constructor closure. N.B. Default constructor closures are only generated if the default constructor is exported because clang itself does not utilize vector constructor iterators. Failing to export the default constructor closure will result in link/load failure if a translation unit compiled with MSVC is on the import side. Differential Revision: http://reviews.llvm.org/D8331 llvm-svn: 232229 --- clang/lib/Sema/SemaDecl.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'clang/lib/Sema') diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 9c6f638119b..7a70cddf9d0 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -12064,6 +12064,24 @@ void Sema::ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagD, "Broken injected-class-name"); } +static void getDefaultArgExprsForConstructors(Sema &S, CXXRecordDecl *Class) { + for (Decl *Member : Class->decls()) { + auto *CD = dyn_cast(Member); + if (!CD || !CD->isDefaultConstructor() || !CD->hasAttr()) + 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::ActOnTagFinishDefinition(Scope *S, Decl *TagD, SourceLocation RBraceLoc) { AdjustDeclIfTemplate(TagD); @@ -12077,9 +12095,17 @@ void Sema::ActOnTagFinishDefinition(Scope *S, Decl *TagD, RD->completeDefinition(); } - if (isa(Tag)) + if (auto *Class = dyn_cast(Tag)) { FieldCollector->FinishClass(); + // 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 (!Class->getDescribedClassTemplate() && + Context.getTargetInfo().getCXXABI().isMicrosoft()) + getDefaultArgExprsForConstructors(*this, Class); + } + // Exit this scope of this tag's definition. PopDeclContext(); -- cgit v1.2.3