C1X: implement static asserts

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129555 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 03067e8..26cb8e1 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -241,6 +241,8 @@
   "unexpected ':' in nested name specifier">;
 def err_bool_redeclaration : Error<
   "redeclaration of C++ built-in type 'bool'">;
+def ext_c1x_static_assert : Extension<
+  "_Static_assert is a C1X-specific feature">;
 
 /// Objective-C parser diagnostics
 def err_expected_minus_or_plus : Error<
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index e36803e..0c32e69 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -240,6 +240,7 @@
 KEYWORD(_Complex                    , KEYALL)
 KEYWORD(_Generic                    , KEYALL)
 KEYWORD(_Imaginary                  , KEYALL)
+KEYWORD(_Static_assert              , KEYALL)
 KEYWORD(__func__                    , KEYALL)
 
 // C++ 2.11p1: Keywords.
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 5e6c51c..ee76cc7 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -653,7 +653,7 @@
 /// [C++]   namespace-definition
 /// [C++]   using-directive
 /// [C++]   using-declaration
-/// [C++0x] static_assert-declaration
+/// [C++0x/C1X] static_assert-declaration
 ///         others... [FIXME]
 ///
 Parser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts,
@@ -688,6 +688,7 @@
                                                   DeclEnd, attrs);
     break;
   case tok::kw_static_assert:
+  case tok::kw__Static_assert:
     ProhibitAttributes(attrs);
     SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
     break;
@@ -2923,6 +2924,9 @@
     // typedef-name
   case tok::annot_typename:
 
+    // static_assert-declaration
+  case tok::kw__Static_assert:
+
     // GNU typeof support.
   case tok::kw_typeof:
 
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 9c0730d..2227018 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -404,13 +404,21 @@
                                        IsTypeName, TypenameLoc);
 }
 
-/// ParseStaticAssertDeclaration - Parse C++0x static_assert-declaratoion.
+/// ParseStaticAssertDeclaration - Parse C++0x or C1X static_assert-declaration.
 ///
-///      static_assert-declaration:
-///        static_assert ( constant-expression  ,  string-literal  ) ;
+/// [C++0x] static_assert-declaration:
+///           static_assert ( constant-expression  ,  string-literal  ) ;
+///
+/// [C1X]   static_assert-declaration:
+///           _Static_assert ( constant-expression  ,  string-literal  ) ;
 ///
 Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){
-  assert(Tok.is(tok::kw_static_assert) && "Not a static_assert declaration");
+  assert((Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) &&
+         "Not a static_assert declaration");
+
+  if (Tok.is(tok::kw__Static_assert) && !getLang().C1X)
+    Diag(Tok, diag::ext_c1x_static_assert);
+
   SourceLocation StaticAssertLoc = ConsumeToken();
 
   if (Tok.isNot(tok::l_paren)) {
@@ -1426,7 +1434,7 @@
   }
 
   // static_assert-declaration
-  if (Tok.is(tok::kw_static_assert)) {
+  if (Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) {
     // FIXME: Check for templates
     SourceLocation DeclEnd;
     ParseStaticAssertDeclaration(DeclEnd);
diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp
index 775bc93..9522691 100644
--- a/lib/Parse/ParseTentative.cpp
+++ b/lib/Parse/ParseTentative.cpp
@@ -58,6 +58,7 @@
   case tok::kw_using:
     // static_assert-declaration
   case tok::kw_static_assert:
+  case tok::kw__Static_assert:
     return true;
     // simple-declaration
   default:
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index c5d5ef5..492b8f5 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -557,6 +557,7 @@
   case tok::kw_template:
   case tok::kw_export:    // As in 'export template'
   case tok::kw_static_assert:
+  case tok::kw__Static_assert:
     // A function definition cannot start with a these keywords.
     {
       SourceLocation DeclEnd;
diff --git a/test/Sema/static-assert.c b/test/Sema/static-assert.c
new file mode 100644
index 0000000..13d7070
--- /dev/null
+++ b/test/Sema/static-assert.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -std=c1x -fsyntax-only -verify %s
+
+_Static_assert("foo", "string is nonzero"); // expected-error {{static_assert expression is not an integral constant expression}}
+
+_Static_assert(1, "1 is nonzero");
+_Static_assert(0, "0 is nonzero"); // expected-error {{static_assert failed "0 is nonzero"}}
+
+void foo(void) {
+  _Static_assert(1, "1 is nonzero");
+  _Static_assert(0, "0 is nonzero"); // expected-error {{static_assert failed "0 is nonzero"}}
+}