More static_assert work. Check that the assert expr is valid and show an error if it's false. Create the declaration and add it to the current context.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66995 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 4776ce5..fd90083 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -13,6 +13,7 @@
 
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "llvm/ADT/STLExtras.h"
 using namespace clang;
@@ -339,3 +340,19 @@
                                     Used, CommonAncestor);
 }
 
+StaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC,
+                                           SourceLocation L, Expr *AssertExpr,
+                                           StringLiteral *Message) {
+  return new (C) StaticAssertDecl(DC, L, AssertExpr, Message);
+}
+
+void StaticAssertDecl::Destroy(ASTContext& C) {
+  AssertExpr->Destroy(C);
+  Message->Destroy(C);
+  this->~StaticAssertDecl();
+  C.Deallocate((void *)this);
+}
+
+StaticAssertDecl::~StaticAssertDecl() {
+}
+
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index a86aa65..54b3d19 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1554,6 +1554,11 @@
   virtual void ActOnDelayedCXXMethodParameter(Scope *S, DeclTy *Param);
   virtual void ActOnFinishDelayedCXXMethodDeclaration(Scope *S, DeclTy *Method);
 
+  virtual DeclTy *ActOnStaticAssertDeclaration(SourceLocation AssertLoc, 
+                                               ExprArg AssertExpr,
+                                               ExprArg AssertMessageExpr,
+                                               SourceLocation RParenLoc);
+  
   bool CheckConstructorDeclarator(Declarator &D, QualType &R,
                                   FunctionDecl::StorageClass& SC);
   bool CheckConstructor(CXXConstructorDecl *Constructor);
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index f5d8f6b..57a6c62 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -2234,3 +2234,30 @@
   ProcessDeclAttributes(ExDecl, D);
   return ExDecl;
 }
+
+Sema::DeclTy *Sema::ActOnStaticAssertDeclaration(SourceLocation AssertLoc, 
+                                                 ExprArg assertexpr,
+                                                 ExprArg assertmessageexpr,
+                                                 SourceLocation RParenLoc) {
+  Expr *AssertExpr = (Expr *)assertexpr.get();
+  StringLiteral *AssertMessage = 
+    cast<StringLiteral>((Expr *)assertmessageexpr.get());
+
+  llvm::APSInt Value(32);
+  if (!AssertExpr->isIntegerConstantExpr(Value, Context)) {
+    Diag(AssertLoc, diag::err_static_assert_expression_is_not_constant) <<
+      AssertExpr->getSourceRange();
+    return 0;
+  }
+
+  Decl *Decl = StaticAssertDecl::Create(Context, CurContext, AssertLoc, 
+                                        AssertExpr, AssertMessage);
+  if (Value == 0) {
+    std::string str(AssertMessage->getStrData(), 
+                    AssertMessage->getByteLength());
+    Diag(AssertLoc, diag::err_static_assert_failed) << str;
+  }
+  
+  CurContext->addDecl(Decl);
+  return Decl;
+}