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

Reply via email to