diff options
author | Hans Wennborg <hans@hanshq.net> | 2015-06-09 00:39:09 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2015-06-09 00:39:09 +0000 |
commit | fce87cae44aa89aa92d0fdb107ba1d88d5d9b3ca (patch) | |
tree | 566afe5697e3f3457ffc6363d352e60f428ee49d /clang/lib/Sema/SemaDeclCXX.cpp | |
parent | c0875507becfe14ad83acd50cceb66d1de641d1c (diff) | |
download | bcm5719-llvm-fce87cae44aa89aa92d0fdb107ba1d88d5d9b3ca.tar.gz bcm5719-llvm-fce87cae44aa89aa92d0fdb107ba1d88d5d9b3ca.zip |
Enable DLL attribute propagation on explicit instantiation definitions (PR23770)
This is a follow-up to r225570 which enabled adding DLL attributes when a
class template goes from explicit instantiation declaration to explicit
instantiation definition.
llvm-svn: 239375
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 114 |
1 files changed, 57 insertions, 57 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 8859cc1b67d..c80ef2d2bdc 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1345,61 +1345,6 @@ static bool findCircularInheritance(const CXXRecordDecl *Class, return false; } -/// \brief Perform propagation of DLL attributes from a derived class to a -/// templated base class for MS compatibility. -static void propagateDLLAttrToBaseClassTemplate( - Sema &S, CXXRecordDecl *Class, Attr *ClassAttr, - ClassTemplateSpecializationDecl *BaseTemplateSpec, SourceLocation BaseLoc) { - if (getDLLAttr( - BaseTemplateSpec->getSpecializedTemplate()->getTemplatedDecl())) { - // If the base class template has a DLL attribute, don't try to change it. - return; - } - - 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; - } - - if (getDLLAttr(BaseTemplateSpec)) { - // The template has already been specialized or instantiated with an - // attribute, explicitly or through propagation. We should not try to change - // it. - return; - } - - // The template was previously instantiated or explicitly specialized without - // a dll attribute, It's too late for us to add an attribute, so warn that - // this is unsupported. - S.Diag(BaseLoc, diag::warn_attribute_dll_instantiated_base_class) - << BaseTemplateSpec->isExplicitSpecialization(); - S.Diag(ClassAttr->getLocation(), diag::note_attribute); - if (BaseTemplateSpec->isExplicitSpecialization()) { - S.Diag(BaseTemplateSpec->getLocation(), - diag::note_template_class_explicit_specialization_was_here) - << BaseTemplateSpec; - } else { - S.Diag(BaseTemplateSpec->getPointOfInstantiation(), - diag::note_template_class_instantiation_was_here) - << BaseTemplateSpec; - } -} - /// \brief Check the validity of a C++ base class specifier. /// /// \returns a new CXXBaseSpecifier if well-formed, emits diagnostics @@ -1471,8 +1416,8 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class, if (Attr *ClassAttr = getDLLAttr(Class)) { if (auto *BaseTemplate = dyn_cast_or_null<ClassTemplateSpecializationDecl>( BaseType->getAsCXXRecordDecl())) { - propagateDLLAttrToBaseClassTemplate(*this, Class, ClassAttr, - BaseTemplate, BaseLoc); + propagateDLLAttrToBaseClassTemplate(Class, ClassAttr, BaseTemplate, + BaseLoc); } } } @@ -4884,6 +4829,61 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) { } } +/// \brief Perform propagation of DLL attributes from a derived class to a +/// templated base class for MS compatibility. +void Sema::propagateDLLAttrToBaseClassTemplate( + CXXRecordDecl *Class, Attr *ClassAttr, + ClassTemplateSpecializationDecl *BaseTemplateSpec, SourceLocation BaseLoc) { + if (getDLLAttr( + BaseTemplateSpec->getSpecializedTemplate()->getTemplatedDecl())) { + // If the base class template has a DLL attribute, don't try to change it. + return; + } + + 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(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) + checkClassLevelDLLAttribute(BaseTemplateSpec); + + return; + } + + if (getDLLAttr(BaseTemplateSpec)) { + // The template has already been specialized or instantiated with an + // attribute, explicitly or through propagation. We should not try to change + // it. + return; + } + + // The template was previously instantiated or explicitly specialized without + // a dll attribute, It's too late for us to add an attribute, so warn that + // this is unsupported. + Diag(BaseLoc, diag::warn_attribute_dll_instantiated_base_class) + << BaseTemplateSpec->isExplicitSpecialization(); + Diag(ClassAttr->getLocation(), diag::note_attribute); + if (BaseTemplateSpec->isExplicitSpecialization()) { + Diag(BaseTemplateSpec->getLocation(), + diag::note_template_class_explicit_specialization_was_here) + << BaseTemplateSpec; + } else { + Diag(BaseTemplateSpec->getPointOfInstantiation(), + diag::note_template_class_instantiation_was_here) + << BaseTemplateSpec; + } +} + /// \brief Perform semantic checks on a class definition that has been /// completing, introducing implicitly-declared members, checking for /// abstract types, etc. |