forked from OSchip/llvm-project
[CONCEPTS] Add concept to VarDecl and diagnostic for uninitialized variable concept
Summary: 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. Reviewers: fraggamuffin, hubert.reinterpretcast, faisalv, aaron.ballman, rsmith Subscribers: aemerson, cfe-commits Differential Revision: http://reviews.llvm.org/D11600 llvm-svn: 243876
This commit is contained in:
parent
1becccb10f
commit
8567a000b9
|
@ -815,6 +815,9 @@ protected:
|
|||
/// \brief Whether this variable is (C++0x) constexpr.
|
||||
unsigned IsConstexpr : 1;
|
||||
|
||||
/// \brief Whether this variable is a (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 @@ public:
|
|||
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;
|
||||
|
|
|
@ -1971,6 +1971,8 @@ 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">;
|
||||
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<
|
||||
|
|
|
@ -5855,6 +5855,9 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
|
|||
|
||||
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,15 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl,
|
|||
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() &&
|
||||
|
|
|
@ -19,3 +19,7 @@ struct C {
|
|||
concept bool D4() { return true; } // expected-error {{'concept' can only appear on the definition of a function template or variable template}}
|
||||
|
||||
concept bool D5 = true; // expected-error {{'concept' can only appear on the definition of a function template or variable template}}
|
||||
|
||||
template<typename T>
|
||||
concept bool D6; // expected-error {{variable concept declaration must be initialized}}
|
||||
|
||||
|
|
Loading…
Reference in New Issue