Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -1959,6 +1959,12 @@ def note_private_extern : Note< "use __attribute__((visibility(\"hidden\"))) attribute instead">; +// C++ Concepts TS +def err_invalid_concept_scope : Error< + "concept declaration required to be in namespace scope">; +def err_function_concept_not_defined : Error< + "function concept requires definition">; + // C++11 char16_t/char32_t def warn_cxx98_compat_unicode_type : Warning< "'%0' type specifier is incompatible with C++98">, Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -7223,6 +7223,7 @@ bool isVirtual = D.getDeclSpec().isVirtualSpecified(); bool isExplicit = D.getDeclSpec().isExplicitSpecified(); bool isConstexpr = D.getDeclSpec().isConstexprSpecified(); + bool isConcept = D.getDeclSpec().isConceptSpecified(); isFriend = D.getDeclSpec().isFriendSpecified(); if (isFriend && !isInline && D.isFunctionDefinition()) { // C++ [class.friend]p5 @@ -7439,6 +7440,28 @@ Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_constexpr_dtor); } + if (isConcept) { + // 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 + if (!NewFD->getParent()->getRedeclContext()->isFileContext()) { + Diag(D.getIdentifierLoc(), diag::err_invalid_concept_scope); + NewFD->setInvalidDecl(); + } + + // C++ Concepts TS [dcl.spec.concept]p1: A concept definition refers to a + // function concept and its definition + if (!D.isFunctionDefinition()) { + Diag(D.getDeclSpec().getConceptSpecLoc(), + diag::err_function_concept_not_defined); + NewFD->setInvalidDecl(); + } + + // C++ Concepts TS [dcl.spec.concept]p2: Every concepts definition is + // implicity defined to be a constexpr declaration (implicitly inline) + NewFD->setImplicitlyInline(); + } + // If __module_private__ was specified, mark the function accordingly. if (D.getDeclSpec().isModulePrivateSpecified()) { if (isFunctionTemplateSpecialization) { Index: test/SemaCXX/cxx-concept-declaration.cpp =================================================================== --- /dev/null +++ test/SemaCXX/cxx-concept-declaration.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s + +template concept bool C1 = true; + +template concept decltype(!0) C2 = true; + +template concept bool D1(); // expected-error {{function concept requires definition}} + +struct A { + template concept bool D1() { return true; } // expected-error {{concept declaration required to be in namespace scope}} +};