Add parser support for static_assert.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66661 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index ef57737..b21ac77 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -217,6 +217,55 @@
   return 0;
 }
 
+/// ParseStaticAssertDeclaration - Parse C++0x static_assert-declaratoion.
+///
+///      static_assert-declaration:
+///        static_assert ( constant-expression  ,  string-literal  ) ;
+///
+Parser::DeclTy *Parser::ParseStaticAssertDeclaration() {
+  assert(Tok.is(tok::kw_static_assert) && "Not a static_assert declaration");
+  SourceLocation StaticAssertLoc = ConsumeToken();
+  
+  if (Tok.isNot(tok::l_paren)) {
+    Diag(Tok, diag::err_expected_lparen);
+    return 0;
+  }
+  
+  SourceLocation LParenLoc = ConsumeParen();
+  
+  OwningExprResult AssertExpr(ParseConstantExpression());
+  if (AssertExpr.isInvalid()) {
+    SkipUntil(tok::semi);
+    return 0;
+  }
+  
+  if (Tok.isNot(tok::comma)) {
+    Diag(Tok, diag::err_expected_comma);
+    SkipUntil(tok::semi);
+    return 0;
+  }
+  
+  SourceLocation CommaLoc = ConsumeToken();
+  
+  if (Tok.isNot(tok::string_literal)) {
+    Diag(Tok, diag::err_expected_string_literal);
+    SkipUntil(tok::semi);
+    return 0;
+  }
+  
+  OwningExprResult AssertMessage(ParseStringLiteralExpression());
+  if (AssertMessage.isInvalid()) 
+    return 0;
+
+  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
+  
+  ExpectAndConsume(tok::semi, diag::err_expected_semi_after_static_assert);
+
+  return Actions.ActOnStaticAssertDeclaration(LParenLoc, move(AssertExpr), 
+                                              CommaLoc, move(AssertMessage), 
+                                              RParenLoc);
+}
+
 /// ParseClassName - Parse a C++ class-name, which names a class. Note
 /// that we only check that the result names a type; semantic analysis
 /// will need to verify that the type names a class. The result is
@@ -568,7 +617,7 @@
 ///         function-definition ';'[opt]
 ///         ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO]
 ///         using-declaration                                            [TODO]
-/// [C++0x] static_assert-declaration                                    [TODO]
+/// [C++0x] static_assert-declaration
 ///         template-declaration                                         [TODO]
 /// [GNU]   '__extension__' member-declaration
 ///
@@ -588,6 +637,10 @@
 ///         '=' constant-expression
 ///
 Parser::DeclTy *Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
+  // static_assert-declaration
+  if (Tok.is(tok::kw_static_assert))
+    return ParseStaticAssertDeclaration();
+      
   // Handle:  member-declaration ::= '__extension__' member-declaration
   if (Tok.is(tok::kw___extension__)) {
     // __extension__ silences extension warnings in the subexpression.