Skip to content

Commit

Permalink
[CONCEPTS] Add concept to VarDecl and diagnostic for uninitialized va…
Browse files Browse the repository at this point in the history
…riable 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
  • Loading branch information
Wilson-N committed Aug 3, 2015
1 parent 1becccb commit 8567a00
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 0 deletions.
12 changes: 12 additions & 0 deletions clang/include/clang/AST/Decl.h
Expand Up @@ -815,6 +815,9 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
/// \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;
Expand Down Expand Up @@ -1238,6 +1241,15 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
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;
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Expand Up @@ -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<
Expand Down
12 changes: 12 additions & 0 deletions clang/lib/Sema/SemaDecl.cpp
Expand Up @@ -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
Expand Down Expand Up @@ -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() &&
Expand Down
4 changes: 4 additions & 0 deletions clang/test/SemaCXX/cxx-concept-declaration.cpp
Expand Up @@ -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}}

0 comments on commit 8567a00

Please sign in to comment.