From bb1983cf3a1b7ff57d6cfdc05a04128bfa3721d1 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 9 Jun 2015 00:39:03 +0000 Subject: Enable propagation of dll attributes to previously instantiated base class templates in some cases It is safe to add a dll attribute if the base class template previously only had an explicit instantiation declaration, or was implicitly instantiated. I both those cases, the members would not have been codegenned yet. In the case of explicit instantiation declaration this is natural, and for implicit instantiations, codegen is deferred (see r225570). This is work towards fixing PR23770. llvm-svn: 239373 --- clang/lib/Sema/SemaDeclCXX.cpp | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) (limited to 'clang/lib/Sema/SemaDeclCXX.cpp') diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index b67dfb8e342..8859cc1b67d 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1356,11 +1356,23 @@ static void propagateDLLAttrToBaseClassTemplate( return; } - if (BaseTemplateSpec->getSpecializationKind() == TSK_Undeclared) { - // If the base class is not already specialized, we can do the propagation. + auto TSK = BaseTemplateSpec->getSpecializationKind(); + if (!getDLLAttr(BaseTemplateSpec) && + (TSK == TSK_Undeclared || TSK == TSK_ExplicitInstantiationDeclaration || + TSK == TSK_ImplicitInstantiation)) { + // The template hasn't been instantiated yet (or it has, but only as an + // explicit instantiation declaration or implicit instantiation, which means + // we haven't codegenned any members yet), so propagate the attribute. auto *NewAttr = cast(ClassAttr->clone(S.getASTContext())); NewAttr->setInherited(true); BaseTemplateSpec->addAttr(NewAttr); + + // If the template is already instantiated, checkDLLAttributeRedeclaration() + // needs to be run again to work see the new attribute. Otherwise this will + // get run whenever the template is instantiated. + if (TSK != TSK_Undeclared) + S.checkClassLevelDLLAttribute(BaseTemplateSpec); + return; } @@ -4783,8 +4795,9 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) { TemplateSpecializationKind TSK = Class->getTemplateSpecializationKind(); - // Don't dllexport explicit class template instantiation declarations. - if (ClassExported && TSK == TSK_ExplicitInstantiationDeclaration) { + // Ignore explicit dllexport on explicit class template instantiation declarations. + if (ClassExported && !ClassAttr->isInherited() && + TSK == TSK_ExplicitInstantiationDeclaration) { Class->dropAttr(); return; } @@ -4832,12 +4845,15 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) { } if (MD && ClassExported) { + if (TSK == TSK_ExplicitInstantiationDeclaration) + // Don't go any further if this is just an explicit instantiation + // declaration. + continue; + if (MD->isUserProvided()) { // Instantiate non-default class member functions ... // .. except for certain kinds of template specializations. - if (TSK == TSK_ExplicitInstantiationDeclaration) - continue; if (TSK == TSK_ImplicitInstantiation && !ClassAttr->isInherited()) continue; -- cgit v1.2.3