From 9c70593866c21916cd79ac29a6d5c71a06a08131 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Tue, 17 Mar 2015 21:51:43 +0000 Subject: [PATCH] MS ABI: Build C++ default argument exprs for exported template classes This was an omission from r232229. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@232554 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Sema/Sema.h | 2 +- lib/CodeGen/MicrosoftCXXABI.cpp | 7 +++++-- lib/Parse/ParseDeclCXX.cpp | 2 +- lib/Sema/SemaDeclCXX.cpp | 2 +- lib/Sema/SemaTemplateInstantiate.cpp | 4 ++++ test/CodeGenCXX/dllexport.cpp | 9 +++++++++ 6 files changed, 21 insertions(+), 5 deletions(-) diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 30d35f61c2..7671ab3f3a 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -5012,7 +5012,7 @@ public: SourceLocation RBrac, AttributeList *AttrList); void ActOnFinishCXXMemberDecls(); - void ActOnFinishCXXMethodDefs(Decl *D); + void ActOnFinishCXXMemberDefaultArgs(Decl *D); void ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param); unsigned ActOnReenterTemplateScope(Scope *S, Decl *Template); diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp index 6417b87444..b09d658c82 100644 --- a/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/lib/CodeGen/MicrosoftCXXABI.cpp @@ -3411,8 +3411,11 @@ MicrosoftCXXABI::getAddrOfCXXCtorClosure(const CXXConstructorDecl *CD, // Add the rest of the default arguments. std::vector ArgVec; - for (unsigned I = IsCopy ? 1 : 0, E = CD->getNumParams(); I != E; ++I) - ArgVec.push_back(getContext().getDefaultArgExprForConstructor(CD, I)); + for (unsigned I = IsCopy ? 1 : 0, E = CD->getNumParams(); I != E; ++I) { + Stmt *DefaultArg = getContext().getDefaultArgExprForConstructor(CD, I); + assert(DefaultArg && "sema forgot to instantiate default args"); + ArgVec.push_back(DefaultArg); + } CodeGenFunction::RunCleanupsScope Cleanups(CGF); diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index d5497085f2..c565594118 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -2918,7 +2918,7 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, // We've finished parsing everything, including default argument // initializers. - Actions.ActOnFinishCXXMethodDefs(TagDecl); + Actions.ActOnFinishCXXMemberDefaultArgs(TagDecl); } if (TagDecl) diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 4e64595e11..f7183bc2c4 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -9449,7 +9449,7 @@ static void getDefaultArgExprsForConstructors(Sema &S, CXXRecordDecl *Class) { } } -void Sema::ActOnFinishCXXMethodDefs(Decl *D) { +void Sema::ActOnFinishCXXMemberDefaultArgs(Decl *D) { auto *RD = dyn_cast(D); // Default constructors that are annotated with __declspec(dllexport) which diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 8ea1e6be91..8e4fe85077 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -2043,6 +2043,10 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, SourceLocation(), SourceLocation(), nullptr); CheckCompletedCXXClass(Instantiation); + // Default arguments are parsed, if not instantiated. We can go instantiate + // default arg exprs for default constructors if necessary now. + ActOnFinishCXXMemberDefaultArgs(Instantiation); + // Instantiate late parsed attributes, and attach them to their decls. // See Sema::InstantiateAttrs for (LateInstantiatedAttrVec::iterator I = LateAttrs.begin(), diff --git a/test/CodeGenCXX/dllexport.cpp b/test/CodeGenCXX/dllexport.cpp index c71ab5c67d..c6ab232a76 100644 --- a/test/CodeGenCXX/dllexport.cpp +++ b/test/CodeGenCXX/dllexport.cpp @@ -523,6 +523,15 @@ struct __declspec(dllexport) NestedOuter { // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FNestedOuter@@QAEXXZ" // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FNestedInner@NestedOuter@@QAEXXZ" +template +struct SomeTemplate { + SomeTemplate(T o = T()) : o(o) {} + T o; +}; +struct __declspec(dllexport) InheritFromTemplate : SomeTemplate {}; + +// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_F?$SomeTemplate@H@@QAEXXZ" + struct __declspec(dllexport) T { // Copy assignment operator: // M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"\01??4T@@QAEAAU0@ABU0@@Z" -- 2.40.0