diff options
| author | Hubert Tong <hubert.reinterpretcast@gmail.com> | 2015-07-22 13:32:36 +0000 |
|---|---|---|
| committer | Hubert Tong <hubert.reinterpretcast@gmail.com> | 2015-07-22 13:32:36 +0000 |
| commit | 27f0697308e17861c0d71a223563093184f3ace2 (patch) | |
| tree | 786dbbbc2d8d241f318a9f9d26f5c115e43bd72b | |
| parent | 7da34f1549a9514ece2a7c4534ca42af58a36461 (diff) | |
| download | bcm5719-llvm-27f0697308e17861c0d71a223563093184f3ace2.tar.gz bcm5719-llvm-27f0697308e17861c0d71a223563093184f3ace2.zip | |
[CONCEPTS] Add diagnostics: non-defining function; non-namespace scope
Summary:
Create diagnostic for function concept declaration which is not a
definition.
Create diagnostic for concept declaration which isn't in namespace
scope.
Create associated tests.
Reviewers: rsmith, faisalv, fraggamuffin, hubert.reinterpretcast
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D11027
Patch by Nathan Wilson!
llvm-svn: 242899
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 6 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 26 | ||||
| -rw-r--r-- | clang/test/SemaCXX/cxx-concept-declaration.cpp | 17 |
3 files changed, 49 insertions, 0 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 7174bbe95ef..56597714ff9 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1965,6 +1965,12 @@ def warn_private_extern : Warning< def note_private_extern : Note< "use __attribute__((visibility(\"hidden\"))) attribute instead">; +// C++ Concepts TS +def err_concept_decls_may_only_appear_in_namespace_scope : Error< + "concept declarations may only appear in namespace scope">; +def err_function_concept_not_defined : Error< + "function concept declaration must be a definition">; + // C++11 char16_t/char32_t def warn_cxx98_compat_unicode_type : Warning< "'%0' type specifier is incompatible with C++98">, diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 22803653edf..d25b4dda885 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -4861,6 +4861,17 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D, if (getLangOpts().CPlusPlus) CheckExtraCXXDefaultArguments(D); + if (D.getDeclSpec().isConceptSpecified()) { + // 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 (!DC->getRedeclContext()->isFileContext()) { + Diag(D.getIdentifierLoc(), + diag::err_concept_decls_may_only_appear_in_namespace_scope); + return nullptr; + } + } + NamedDecl *New; bool AddToScope = true; @@ -7203,6 +7214,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, 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 @@ -7419,6 +7431,20 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, 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... + if (!D.isFunctionDefinition()) { + Diag(D.getDeclSpec().getConceptSpecLoc(), + diag::err_function_concept_not_defined); + NewFD->setInvalidDecl(); + } + + // C++ Concepts TS [dcl.spec.concept]p2: Every concept 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) { diff --git a/clang/test/SemaCXX/cxx-concept-declaration.cpp b/clang/test/SemaCXX/cxx-concept-declaration.cpp new file mode 100644 index 00000000000..6bc2d482dcb --- /dev/null +++ b/clang/test/SemaCXX/cxx-concept-declaration.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s + +namespace A { + template<typename T> concept bool C1() { return true; } + + template<typename T> concept bool C2 = true; +} + +template<typename T> concept bool D1(); // expected-error {{function concept declaration must be a definition}} + +struct B { + template<typename T> concept bool D2() { return true; } // expected-error {{concept declarations may only appear in namespace scope}} +}; + +struct C { + template<typename T> static concept bool D3 = true; // expected-error {{concept declarations may only appear in namespace scope}} +}; |

