From 75042398c34413594a9f5f56f5f3761ea37fd2d0 Mon Sep 17 00:00:00 2001 From: John McCall Date: Thu, 11 Feb 2010 01:33:53 +0000 Subject: [PATCH] Strip attributes and 'inline' off the "previous declaration" of a template explicit specialization. Complete an apparently stalled refactor towards using CheckSpecializationInstantiationRedecl(). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95845 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaTemplate.cpp | 42 +++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 63cf4aef37..c2f0fbc641 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -3655,6 +3655,16 @@ Sema::ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope, return DeclPtrTy(); } +/// \brief Strips various properties off an implicit instantiation +/// that has just been explicitly specialized. +static void StripImplicitInstantiation(NamedDecl *D) { + D->invalidateAttrs(); + + if (FunctionDecl *FD = dyn_cast(D)) { + FD->setInlineSpecified(false); + } +} + /// \brief Diagnose cases where we have an explicit template specialization /// before/after an explicit template instantiation, producing diagnostics /// for those cases where they are required and determining whether the @@ -3705,6 +3715,7 @@ Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc, if (PrevPointOfInstantiation.isInvalid()) { // The declaration itself has not actually been instantiated, so it is // still okay to specialize it. + StripImplicitInstantiation(PrevDecl); return false; } // Fall through @@ -3924,15 +3935,15 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD, FunctionTemplateSpecializationInfo *SpecInfo = Specialization->getTemplateSpecializationInfo(); assert(SpecInfo && "Function template specialization info missing?"); - if (SpecInfo->getPointOfInstantiation().isValid()) { - Diag(FD->getLocation(), diag::err_specialization_after_instantiation) - << FD; - Diag(SpecInfo->getPointOfInstantiation(), - diag::note_instantiation_required_here) - << (Specialization->getTemplateSpecializationKind() - != TSK_ImplicitInstantiation); + + bool SuppressNew = false; + if (CheckSpecializationInstantiationRedecl(FD->getLocation(), + TSK_ExplicitSpecialization, + Specialization, + SpecInfo->getTemplateSpecializationKind(), + SpecInfo->getPointOfInstantiation(), + SuppressNew)) return true; - } // Mark the prior declaration as an explicit specialization, so that later // clients know that this is an explicit specialization. @@ -4033,14 +4044,15 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) { // instantiation to take place, in every translation unit in which such a // use occurs; no diagnostic is required. assert(MSInfo && "Member specialization info missing?"); - if (MSInfo->getPointOfInstantiation().isValid()) { - Diag(Member->getLocation(), diag::err_specialization_after_instantiation) - << Member; - Diag(MSInfo->getPointOfInstantiation(), - diag::note_instantiation_required_here) - << (MSInfo->getTemplateSpecializationKind() != TSK_ImplicitInstantiation); + + bool SuppressNew = false; + if (CheckSpecializationInstantiationRedecl(Member->getLocation(), + TSK_ExplicitSpecialization, + Instantiation, + MSInfo->getTemplateSpecializationKind(), + MSInfo->getPointOfInstantiation(), + SuppressNew)) return true; - } // Check the scope of this explicit specialization. if (CheckTemplateSpecializationScope(*this, -- 2.40.0