nwilson created this revision. nwilson added reviewers: rsmith, hubert.reinterpretcast, aaron.ballman, faisalv, fraggamuffin. nwilson added a subscriber: cfe-commits.
http://reviews.llvm.org/D13357 Files: include/clang/AST/Decl.h include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp lib/Sema/SemaTemplate.cpp test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.concept/p7.cpp
Index: test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.concept/p7.cpp =================================================================== --- /dev/null +++ test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.concept/p7.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s + +template<typename T> concept bool VCEI { true }; +template concept bool VCEI<int>; // expected-error {{variable concept cannot be explicitly instantiated}} + +template<typename T> concept bool VCPS { true }; +template<typename T> concept bool VCPS<T*> { true }; // expected-error {{variable concept cannot be partially specialized}} + +template<typename T> concept bool VCES { true }; +template<> concept bool VCES<int> { true }; // expected-error {{variable concept cannot be explicitly specialized}} + +template<typename T> concept bool FCEI() { return true; } +template concept bool FCEI<int>(); // expected-error {{function concept cannot be explicitly instantiated}} + +template<typename T> concept bool FCES() { return true; } +template<> concept bool FCES<bool>() { return true; } // expected-error {{function concept cannot be explicitly specialized}} Index: lib/Sema/SemaTemplate.cpp =================================================================== --- lib/Sema/SemaTemplate.cpp +++ lib/Sema/SemaTemplate.cpp @@ -7588,6 +7588,14 @@ Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_explicit_instantiation_constexpr); + // C++ Concepts TS [dcl.spec.concept]p7: A program shall not declare an + // explicit instantiation, [...] of a concept definition. + if (D.getDeclSpec().isConceptSpecified() && R->isFunctionType()) { + Diag(D.getIdentifierLoc(), diag::err_concept_decl_specialized) + << 1 << 0; + return true; + } + // C++0x [temp.explicit]p2: // There are two forms of explicit instantiation: an explicit instantiation // definition and an explicit instantiation declaration. An explicit @@ -7659,6 +7667,14 @@ return true; } + // C++ Concepts TS [dcl.spec.concept]p7: A program shall not declare an + // explicit instantiation, [...] of a concept definition. + if (D.getDeclSpec().isConceptSpecified()) { + Diag(D.getIdentifierLoc(), diag::err_concept_decl_specialized) + << 0 << 0; + return true; + } + // Translate the parser's template argument list into our AST format. TemplateArgumentListInfo TemplateArgs = makeTemplateArgumentListInfo(*this, *D.getName().TemplateId); Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -5898,6 +5898,21 @@ << 0 << 3; NewVD->setInvalidDecl(true); } + + // C++ Concepts TS [dcl.spec.concept]p7: A program shall not declare [...] + // an explicit specialization, or a partial specialization of a concept + // definition + if (IsVariableTemplateSpecialization && !IsPartialSpecialization) { + Diag(NewVD->getLocation(), diag::err_concept_decl_specialized) + << 0 << 1; + NewVD->setInvalidDecl(true); + } + + if (IsVariableTemplateSpecialization && IsPartialSpecialization) { + Diag(NewVD->getLocation(), diag::err_concept_decl_specialized) + << 0 << 2; + NewVD->setInvalidDecl(true); + } } } @@ -7544,6 +7559,9 @@ } if (isConcept) { + // This is a function concept + NewFD->setConcept(true); + // C++ Concepts TS [dcl.spec.concept]p1: The concept specifier shall be // applied only to the definition of a function template [...] if (!D.isFunctionDefinition()) { @@ -7595,6 +7613,14 @@ << 1 << 3; NewFD->setInvalidDecl(true); } + + // C++ Concepts TS [dcl.spec.concept]p7: A program shall not declare [...] + // an explicit specialization, [...] of a concept definition. + if (isFunctionTemplateSpecialization) { + Diag(NewFD->getLocation(), diag::err_concept_decl_specialized) + << 1 << 1; + NewFD->setInvalidDecl(); + } } // If __module_private__ was specified, mark the function accordingly. @@ -7858,8 +7884,8 @@ TemplateArgs); HasExplicitTemplateArgs = true; - - if (NewFD->isInvalidDecl()) { + + if (NewFD->isInvalidDecl() && !NewFD->isConcept()) { HasExplicitTemplateArgs = false; } else if (FunctionTemplate) { // Function template with explicit template arguments. Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -1986,6 +1986,9 @@ def err_concept_decl_invalid_specifiers : Error< "%select{variable|function}0 concept cannot be declared " "'%select{thread_local|inline|friend|constexpr}1'">; +def err_concept_decl_specialized : Error< + "%select{variable|function}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< Index: include/clang/AST/Decl.h =================================================================== --- include/clang/AST/Decl.h +++ include/clang/AST/Decl.h @@ -1574,6 +1574,7 @@ bool HasImplicitReturnZero : 1; bool IsLateTemplateParsed : 1; bool IsConstexpr : 1; + bool IsConcept : 1; /// \brief Indicates if the function uses __try. bool UsesSEHTry : 1; @@ -1847,6 +1848,10 @@ bool isConstexpr() const { return IsConstexpr; } void setConstexpr(bool IC) { IsConstexpr = IC; } + /// Whether this is a (C++ Concepts TS) function concept. + bool isConcept() const { return IsConcept; } + void setConcept(bool IC) { IsConcept = IC; } + /// \brief Indicates the function uses __try. bool usesSEHTry() const { return UsesSEHTry; } void setUsesSEHTry(bool UST) { UsesSEHTry = UST; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits