mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-15 03:46:07 +00:00
[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. llvm-svn: 342240
This commit is contained in:
parent
c0b474f67a
commit
b51a70396e
@ -9724,6 +9724,14 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
|
|||||||
cast<FunctionDecl>(D)->getTemplateSpecializationKind() ==
|
cast<FunctionDecl>(D)->getTemplateSpecializationKind() ==
|
||||||
TSK_ExplicitInstantiationDefinition;
|
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)
|
if (getExternalSource()->DeclIsFromPCHWithObjectFile(D) && !IsExpInstDef)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,13 @@ extern template void explicitInstantiationDefAfterDecl<int>(int);
|
|||||||
template <typename T> T __declspec(dllexport) variableTemplate;
|
template <typename T> T __declspec(dllexport) variableTemplate;
|
||||||
extern template int variableTemplate<int>;
|
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
|
#else
|
||||||
|
|
||||||
void use() {
|
void use() {
|
||||||
@ -81,4 +88,9 @@ template void __declspec(dllexport) explicitInstantiationDefAfterDecl<int>(int);
|
|||||||
template int __declspec(dllexport) variableTemplate<int>;
|
template int __declspec(dllexport) variableTemplate<int>;
|
||||||
// PCHWITHOBJVARS: @"??$variableTemplate@H@@3HA" = weak_odr dso_local dllexport global
|
// 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
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user