aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplate.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-02-11 01:33:53 +0000
committerJohn McCall <rjmccall@apple.com>2010-02-11 01:33:53 +0000
commit75042398c34413594a9f5f56f5f3761ea37fd2d0 (patch)
treedbfbe5dcd63c109c06433285a263e1c3c4fb9579 /lib/Sema/SemaTemplate.cpp
parent2d5b70386d6f5553b667b6e407ca781b4ca2009e (diff)
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
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r--lib/Sema/SemaTemplate.cpp42
1 files 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<FunctionDecl>(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,