From 93f661a1dadcdf8ab8af08661d6ea325a6da8ce0 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. llvm-svn: 232554 --- clang/include/clang/Sema/Sema.h | 2 +- clang/lib/CodeGen/MicrosoftCXXABI.cpp | 7 +++++-- clang/lib/Parse/ParseDeclCXX.cpp | 2 +- clang/lib/Sema/SemaDeclCXX.cpp | 2 +- clang/lib/Sema/SemaTemplateInstantiate.cpp | 4 ++++ clang/test/CodeGenCXX/dllexport.cpp | 9 +++++++++ 6 files changed, 21 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 30d35f6..7671ab3 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/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/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index 6417b87..b09d658 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/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/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index d549708..c565594 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/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/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 4e64595..f7183bc 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/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/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 8ea1e6b..8e4fe85 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/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/clang/test/CodeGenCXX/dllexport.cpp b/clang/test/CodeGenCXX/dllexport.cpp index c71ab5c..c6ab232 100644 --- a/clang/test/CodeGenCXX/dllexport.cpp +++ b/clang/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.7.4