summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2015-06-09 00:39:03 +0000
committerHans Wennborg <hans@hanshq.net>2015-06-09 00:39:03 +0000
commitbb1983cf3a1b7ff57d6cfdc05a04128bfa3721d1 (patch)
tree1959f912066e95ccb39cb246bf9976678c3f6030 /clang/lib/Sema/SemaDeclCXX.cpp
parent29b7a939350ed4fb577545c56d54e23b06bce6d9 (diff)
downloadbcm5719-llvm-bb1983cf3a1b7ff57d6cfdc05a04128bfa3721d1.tar.gz
bcm5719-llvm-bb1983cf3a1b7ff57d6cfdc05a04128bfa3721d1.zip
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
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp28
1 files changed, 22 insertions, 6 deletions
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<InheritableAttr>(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<DLLExportAttr>();
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;
OpenPOWER on IntegriCloud