nwilson updated this revision to Diff 37099. nwilson added a comment. Moving tests to the correct file. Modifying the diagnostic id and message so it's more applicable to the checks in this Patch. Update the quoted sections of the standard as well. Use ternary operator for Partial Specialization check. Add missing period in comment.
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.spec.concept/p1.cpp
Index: test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p1.cpp =================================================================== --- test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p1.cpp +++ test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p1.cpp @@ -39,3 +39,20 @@ template <typename T> concept union TCU1 {}; // expected-error {{'concept' can only appear on the definition of a function template or variable template}} concept bool; // expected-error {{'concept' can only appear on the definition of a function template or variable template}} + +template<typename T> concept bool VCEI { true }; +template concept bool VCEI<int>; // expected-error {{'concept' cannot be applied on an explicit instantiation}} +extern template concept bool VCEI<int>; // expected-error {{'concept' cannot be applied on an explicit instantiation}} + +template<typename T> concept bool VCPS { true }; +template<typename T> concept bool VCPS<T*> { true }; // expected-error {{'concept' cannot be applied on an partial specialization}} + +template<typename T> concept bool VCES { true }; +template<> concept bool VCES<int> { true }; // expected-error {{'concept' cannot be applied on an explicit specialization}} + +template<typename T> concept bool FCEI() { return true; } +template concept bool FCEI<int>(); // expected-error {{'concept' cannot be applied on an explicit instantiation}} +extern template concept bool FCEI<int>(); // expected-error {{'concept' cannot be applied on an explicit instantiation}} + +template<typename T> concept bool FCES() { return true; } +template<> concept bool FCES<bool>() { return true; } // expected-error {{'concept' cannot be applied on an explicit specialization}} Index: lib/Sema/SemaTemplate.cpp =================================================================== --- lib/Sema/SemaTemplate.cpp +++ lib/Sema/SemaTemplate.cpp @@ -7597,6 +7597,17 @@ Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_explicit_instantiation_constexpr); + // C++ Concepts TS [dcl.spec.concept]p1: The concept specifier shall be + // applied only to the definition of a function template or variable template, + // declared in namespace scope. A concept definition refers to either a + // function concept and its definition or a variable concept and its + // initializer. + if (D.getDeclSpec().isConceptSpecified()) { + Diag(D.getDeclSpec().getConceptSpecLoc(), + diag:: err_concept_specified_specialization) << 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 Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -5898,6 +5898,17 @@ << 0 << 3; NewVD->setInvalidDecl(true); } + + // C++ Concepts TS [dcl.spec.concept]p1: The concept specifier shall be + // applied only to the definition of a [...] variable template, declared + // in namespace scope. [...] A concept definition refers to [...] a + // variable concept and its initializer. + if (IsVariableTemplateSpecialization) { + Diag(D.getDeclSpec().getConceptSpecLoc(), + diag::err_concept_specified_specialization) + << (IsPartialSpecialization ? 2 : 1); + NewVD->setInvalidDecl(true); + } } } @@ -7544,6 +7555,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 +7609,16 @@ << 1 << 3; NewFD->setInvalidDecl(true); } + + // C++ Concepts TS [dcl.spec.concept]p1: The concept specifier shall be + // applied only to the definition of a function template [...], declared + // in namespace scope. [...] A concept definition refers to either a + // function concept and its definition [...]. + if (isFunctionTemplateSpecialization) { + Diag(D.getDeclSpec().getConceptSpecLoc(), + diag::err_concept_specified_specialization) << 1; + NewFD->setInvalidDecl(); + } } // If __module_private__ was specified, mark the function accordingly. @@ -7858,8 +7882,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_specified_specialization : Error< + "%'concept' cannot be applied on an " + "%select{explicit instantiation|explicit specialization|partial specialization}0">; // 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