nwilson created this revision. nwilson added reviewers: rsmith, fraggamuffin, hubert.reinterpretcast, faisalv, aaron.ballman. nwilson added a subscriber: cfe-commits. Herald added a subscriber: aemerson.
Add IsConcept bit to VarDecl::NonParmVarDeclBitfields and associated isConcept/setConcept member functions. Set IsConcept to true when 'concept' specifier is in variable declaration. Create diagnostic when variable concept is not initialized. http://reviews.llvm.org/D11600 Files: include/clang/AST/Decl.h include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp test/SemaCXX/cxx-concept-declaration.cpp Index: test/SemaCXX/cxx-concept-declaration.cpp =================================================================== --- test/SemaCXX/cxx-concept-declaration.cpp +++ test/SemaCXX/cxx-concept-declaration.cpp @@ -15,3 +15,6 @@ struct C { template<typename T> static concept bool D3 = true; // expected-error {{concept declarations may only appear in namespace scope}} }; + +template<typename T> +concept bool D6; // expected-error {{variable concept declaration must be initialized}} Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -5849,6 +5849,9 @@ if (D.getDeclSpec().isConstexprSpecified()) NewVD->setConstexpr(true); + + if (D.getDeclSpec().isConceptSpecified()) + NewVD->setConcept(true); } // Set the lexical context. If the declarator has a C++ scope specifier, the @@ -9407,6 +9410,16 @@ return; } + // C++ Concepts TS [dcl.spec.concept]p1: [...] A variable template + // definition having the concept specifier is called a variable concept. A + // concept definition refers to [...] a variable concept and its initializer. + if (Var->isConcept()) { + Diag(Var->getLocation(), + diag::err_var_concept_not_initialized); + Var->setInvalidDecl(); + return; + } + // OpenCL v1.1 s6.5.3: variables declared in the constant address space must // be initialized. if (!Var->isInvalidDecl() && Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -1970,6 +1970,8 @@ "concept declarations may only appear in namespace scope">; def err_function_concept_not_defined : Error< "function concept declaration must be a definition">; +def err_var_concept_not_initialized : Error< + "variable concept declaration must be initialized">; // 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 @@ -815,6 +815,9 @@ /// \brief Whether this variable is (C++0x) constexpr. unsigned IsConstexpr : 1; + /// \brief Whether this variable is (C++ Concepts TS) concept. + unsigned IsConcept : 1; + /// \brief Whether this variable is the implicit variable for a lambda /// init-capture. unsigned IsInitCapture : 1; @@ -1238,6 +1241,15 @@ NonParmVarDeclBits.IsConstexpr = IC; } + /// Whether this variable is (C++ Concepts TS) concept. + bool isConcept() const { + return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsConcept; + } + void setConcept(bool IC) { + assert(!isa<ParmVarDecl>(this)); + NonParmVarDeclBits.IsConcept = IC; + } + /// Whether this variable is the implicit variable for a lambda init-capture. bool isInitCapture() const { return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsInitCapture;
Index: test/SemaCXX/cxx-concept-declaration.cpp =================================================================== --- test/SemaCXX/cxx-concept-declaration.cpp +++ test/SemaCXX/cxx-concept-declaration.cpp @@ -15,3 +15,6 @@ struct C { template<typename T> static concept bool D3 = true; // expected-error {{concept declarations may only appear in namespace scope}} }; + +template<typename T> +concept bool D6; // expected-error {{variable concept declaration must be initialized}} Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -5849,6 +5849,9 @@ if (D.getDeclSpec().isConstexprSpecified()) NewVD->setConstexpr(true); + + if (D.getDeclSpec().isConceptSpecified()) + NewVD->setConcept(true); } // Set the lexical context. If the declarator has a C++ scope specifier, the @@ -9407,6 +9410,16 @@ return; } + // C++ Concepts TS [dcl.spec.concept]p1: [...] A variable template + // definition having the concept specifier is called a variable concept. A + // concept definition refers to [...] a variable concept and its initializer. + if (Var->isConcept()) { + Diag(Var->getLocation(), + diag::err_var_concept_not_initialized); + Var->setInvalidDecl(); + return; + } + // OpenCL v1.1 s6.5.3: variables declared in the constant address space must // be initialized. if (!Var->isInvalidDecl() && Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -1970,6 +1970,8 @@ "concept declarations may only appear in namespace scope">; def err_function_concept_not_defined : Error< "function concept declaration must be a definition">; +def err_var_concept_not_initialized : Error< + "variable concept declaration must be initialized">; // 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 @@ -815,6 +815,9 @@ /// \brief Whether this variable is (C++0x) constexpr. unsigned IsConstexpr : 1; + /// \brief Whether this variable is (C++ Concepts TS) concept. + unsigned IsConcept : 1; + /// \brief Whether this variable is the implicit variable for a lambda /// init-capture. unsigned IsInitCapture : 1; @@ -1238,6 +1241,15 @@ NonParmVarDeclBits.IsConstexpr = IC; } + /// Whether this variable is (C++ Concepts TS) concept. + bool isConcept() const { + return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsConcept; + } + void setConcept(bool IC) { + assert(!isa<ParmVarDecl>(this)); + NonParmVarDeclBits.IsConcept = IC; + } + /// Whether this variable is the implicit variable for a lambda init-capture. bool isInitCapture() const { return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsInitCapture;
_______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits