forked from OSchip/llvm-project
[Concepts] Implement subsection [dcl.spec.concept]p7 of the Concepts TS
Summary: A program shall not declare an explicit instantiation (14.8.2), an explicit specialization (14.8.3), or a partial specialization of a concept definition. Reviewers: rsmith, hubert.reinterpretcast, faisalv, aaron.ballman Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D18221 llvm-svn: 265868
This commit is contained in:
parent
dd77e1e6a5
commit
8383912f87
|
@ -2098,6 +2098,9 @@ def err_variable_concept_bool_decl : Error<
|
|||
def err_concept_specified_specialization : Error<
|
||||
"'concept' cannot be applied on an "
|
||||
"%select{explicit instantiation|explicit specialization|partial specialization}0">;
|
||||
def err_concept_specialized : Error<
|
||||
"%select{function|variable}0 concept cannot be "
|
||||
"%select{explicitly instantiated|explicitly specialized|partially specialized}1">;
|
||||
|
||||
// C++11 char16_t/char32_t
|
||||
def warn_cxx98_compat_unicode_type : Warning<
|
||||
|
|
|
@ -6285,6 +6285,25 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
|
|||
if (!IsVariableTemplateSpecialization)
|
||||
D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous));
|
||||
|
||||
// C++ Concepts TS [dcl.spec.concept]p7: A program shall not declare [...]
|
||||
// an explicit specialization (14.8.3) or a partial specialization of a
|
||||
// concept definition.
|
||||
if (IsVariableTemplateSpecialization &&
|
||||
!D.getDeclSpec().isConceptSpecified() && !Previous.empty() &&
|
||||
Previous.isSingleResult()) {
|
||||
NamedDecl *PreviousDecl = Previous.getFoundDecl();
|
||||
if (VarTemplateDecl *VarTmpl = dyn_cast<VarTemplateDecl>(PreviousDecl)) {
|
||||
if (VarTmpl->isConcept()) {
|
||||
Diag(NewVD->getLocation(), diag::err_concept_specialized)
|
||||
<< 1 /*variable*/
|
||||
<< (IsPartialSpecialization ? 2 /*partially specialized*/
|
||||
: 1 /*explicitly specialized*/);
|
||||
Diag(VarTmpl->getLocation(), diag::note_previous_declaration);
|
||||
NewVD->setInvalidDecl();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (NewTemplate) {
|
||||
VarTemplateDecl *PrevVarTemplate =
|
||||
NewVD->getPreviousDecl()
|
||||
|
@ -7823,6 +7842,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
|
|||
if (isFunctionTemplateSpecialization) {
|
||||
Diag(D.getDeclSpec().getConceptSpecLoc(),
|
||||
diag::err_concept_specified_specialization) << 1;
|
||||
NewFD->setInvalidDecl(true);
|
||||
return NewFD;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6920,6 +6920,15 @@ bool Sema::CheckFunctionTemplateSpecialization(
|
|||
// Ignore access information; it doesn't figure into redeclaration checking.
|
||||
FunctionDecl *Specialization = cast<FunctionDecl>(*Result);
|
||||
|
||||
// C++ Concepts TS [dcl.spec.concept]p7: A program shall not declare [...]
|
||||
// an explicit specialization (14.8.3) [...] of a concept definition.
|
||||
if (Specialization->getPrimaryTemplate()->isConcept()) {
|
||||
Diag(FD->getLocation(), diag::err_concept_specialized)
|
||||
<< 0 /*function*/ << 1 /*explicitly specialized*/;
|
||||
Diag(Specialization->getLocation(), diag::note_previous_declaration);
|
||||
return true;
|
||||
}
|
||||
|
||||
FunctionTemplateSpecializationInfo *SpecInfo
|
||||
= Specialization->getTemplateSpecializationInfo();
|
||||
assert(SpecInfo && "Function template specialization info missing?");
|
||||
|
@ -7774,6 +7783,15 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
|
|||
return true;
|
||||
}
|
||||
|
||||
// C++ Concepts TS [dcl.spec.concept]p7: A program shall not declare an
|
||||
// explicit instantiation (14.8.2) [...] of a concept definition.
|
||||
if (PrevTemplate->isConcept()) {
|
||||
Diag(D.getIdentifierLoc(), diag::err_concept_specialized)
|
||||
<< 1 /*variable*/ << 0 /*explicitly instantiated*/;
|
||||
Diag(PrevTemplate->getLocation(), diag::note_previous_declaration);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Translate the parser's template argument list into our AST format.
|
||||
TemplateArgumentListInfo TemplateArgs =
|
||||
makeTemplateArgumentListInfo(*this, *D.getName().TemplateId);
|
||||
|
@ -7988,6 +8006,16 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
|
|||
diag::ext_explicit_instantiation_without_qualified_id)
|
||||
<< Specialization << D.getCXXScopeSpec().getRange();
|
||||
|
||||
// C++ Concepts TS [dcl.spec.concept]p7: A program shall not declare an
|
||||
// explicit instantiation (14.8.2) [...] of a concept definition.
|
||||
if (FunTmpl && FunTmpl->isConcept() &&
|
||||
!D.getDeclSpec().isConceptSpecified()) {
|
||||
Diag(D.getIdentifierLoc(), diag::err_concept_specialized)
|
||||
<< 0 /*function*/ << 0 /*explicitly instantiated*/;
|
||||
Diag(FunTmpl->getLocation(), diag::note_previous_declaration);
|
||||
return true;
|
||||
}
|
||||
|
||||
CheckExplicitInstantiationScope(*this,
|
||||
FunTmpl? (NamedDecl *)FunTmpl
|
||||
: Specialization->getInstantiatedFromMemberFunction(),
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s
|
||||
|
||||
template <typename T> concept bool FCEI() { return true; } // expected-note {{previous declaration is here}} expected-note {{previous declaration is here}}
|
||||
template bool FCEI<int>(); // expected-error {{function concept cannot be explicitly instantiated}}
|
||||
extern template bool FCEI<double>(); // expected-error {{function concept cannot be explicitly instantiated}}
|
||||
|
||||
template <typename T> concept bool FCES() { return true; } // expected-note {{previous declaration is here}}
|
||||
template <> bool FCES<int>() { return true; } // expected-error {{function concept cannot be explicitly specialized}}
|
||||
|
||||
template <typename T> concept bool VC { true }; // expected-note {{previous declaration is here}} expected-note {{previous declaration is here}}
|
||||
template bool VC<int>; // expected-error {{variable concept cannot be explicitly instantiated}}
|
||||
extern template bool VC<double>; // expected-error {{variable concept cannot be explicitly instantiated}}
|
||||
|
||||
template <typename T> concept bool VCES { true }; // expected-note {{previous declaration is here}}
|
||||
template <> bool VCES<int> { true }; // expected-error {{variable concept cannot be explicitly specialized}}
|
||||
|
||||
template <typename T> concept bool VCPS { true }; // expected-note {{previous declaration is here}}
|
||||
template <typename T> bool VCPS<T *> { true }; // expected-error {{variable concept cannot be partially specialized}}
|
Loading…
Reference in New Issue