Author: hans Date: Fri Sep 14 08:18:30 2018 New Revision: 342240 URL: http://llvm.org/viewvc/llvm-project?rev=342240&view=rev Log: [clang-cl] Fix PR38934: failing to dllexport class template member w/ explicit instantiation and PCH
The code in ASTContext::DeclMustBeEmitted was supposed to handle this, but didn't take into account that synthesized members such as operator= might not get marked as template specializations, because they're synthesized on the instantiation directly when handling the class-level dllexport attribute. Modified: cfe/trunk/lib/AST/ASTContext.cpp cfe/trunk/test/CodeGen/pch-dllexport.cpp Modified: cfe/trunk/lib/AST/ASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=342240&r1=342239&r2=342240&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTContext.cpp (original) +++ cfe/trunk/lib/AST/ASTContext.cpp Fri Sep 14 08:18:30 2018 @@ -9724,6 +9724,14 @@ bool ASTContext::DeclMustBeEmitted(const cast<FunctionDecl>(D)->getTemplateSpecializationKind() == TSK_ExplicitInstantiationDefinition; + // Implicit member function definitions, such as operator= might not be + // marked as template specializations, since they're not coming from a + // template but synthesized directly on the class. + IsExpInstDef |= + isa<CXXMethodDecl>(D) && + cast<CXXMethodDecl>(D)->getParent()->getTemplateSpecializationKind() == + TSK_ExplicitInstantiationDefinition; + if (getExternalSource()->DeclIsFromPCHWithObjectFile(D) && !IsExpInstDef) return false; } Modified: cfe/trunk/test/CodeGen/pch-dllexport.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/pch-dllexport.cpp?rev=342240&r1=342239&r2=342240&view=diff ============================================================================== --- cfe/trunk/test/CodeGen/pch-dllexport.cpp (original) +++ cfe/trunk/test/CodeGen/pch-dllexport.cpp Fri Sep 14 08:18:30 2018 @@ -57,6 +57,13 @@ extern template void explicitInstantiati template <typename T> T __declspec(dllexport) variableTemplate; extern template int variableTemplate<int>; +namespace pr38934 { +template <typename T> struct S {}; +extern template struct S<int>; +// The use here causes the S<int>::operator= decl to go into the PCH. +inline void use(S<int> *a, S<int> *b) { *a = *b; }; +} + #else void use() { @@ -81,4 +88,9 @@ template void __declspec(dllexport) expl template int __declspec(dllexport) variableTemplate<int>; // PCHWITHOBJVARS: @"??$variableTemplate@H@@3HA" = weak_odr dso_local dllexport global +// PR38934: Make sure S<int>::operator= gets emitted. While it itself isn't a +// template specialization, its parent is. +template struct __declspec(dllexport) pr38934::S<int>; +// PCHWITHOBJ: define weak_odr dso_local dllexport x86_thiscallcc dereferenceable(1) %"struct.pr38934::S"* @"??4?$S@H@pr38934@@QAEAAU01@ABU01@@Z" + #endif _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits