Handle static_asserts when instantiating structs.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67031 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index f534f42..ec91d71 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -252,13 +252,12 @@
   if (AssertMessage.isInvalid()) 
     return 0;
 
-  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
+  MatchRHSPunctuation(tok::r_paren, LParenLoc);
   
   ExpectAndConsume(tok::semi, diag::err_expected_semi_after_static_assert);
 
   return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, move(AssertExpr), 
-                                              move(AssertMessage), 
-                                              RParenLoc);
+                                              move(AssertMessage));
 }
 
 /// ParseClassName - Parse a C++ class-name, which names a class. Note
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index a357ae7..29d0796 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1562,8 +1562,7 @@
 
   virtual DeclTy *ActOnStaticAssertDeclaration(SourceLocation AssertLoc, 
                                                ExprArg AssertExpr,
-                                               ExprArg AssertMessageExpr,
-                                               SourceLocation RParenLoc);
+                                               ExprArg AssertMessageExpr);
   
   bool CheckConstructorDeclarator(Declarator &D, QualType &R,
                                   FunctionDecl::StorageClass& SC);
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 177eee2..fa84c7d 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -2238,8 +2238,7 @@
 
 Sema::DeclTy *Sema::ActOnStaticAssertDeclaration(SourceLocation AssertLoc, 
                                                  ExprArg assertexpr,
-                                                 ExprArg assertmessageexpr,
-                                                 SourceLocation RParenLoc) {
+                                                 ExprArg assertmessageexpr) {
   Expr *AssertExpr = (Expr *)assertexpr.get();
   StringLiteral *AssertMessage = 
     cast<StringLiteral>((Expr *)assertmessageexpr.get());
@@ -2255,7 +2254,8 @@
     if (Value == 0) {
       std::string str(AssertMessage->getStrData(), 
                       AssertMessage->getByteLength());
-      Diag(AssertLoc, diag::err_static_assert_failed) << str;
+      Diag(AssertLoc, diag::err_static_assert_failed) 
+        << str << AssertExpr->getSourceRange();
     }
   }
   
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 7b2d24b..b7f0bbc 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1071,6 +1071,25 @@
         if (New->isInvalidDecl())
           Invalid = true;
       }
+    } else if (StaticAssertDecl *SA = dyn_cast<StaticAssertDecl>(*Member)) {
+      Expr *AssertExpr = SA->getAssertExpr();
+      
+      OwningExprResult InstantiatedAssertExpr
+        = InstantiateExpr(AssertExpr, 
+                          ClassTemplateSpec->getTemplateArgs(),
+                          ClassTemplateSpec->getNumTemplateArgs());
+      if (!InstantiatedAssertExpr.isInvalid()) {
+        OwningExprResult Message = Clone(SA->getMessage());
+
+        Decl *New = 
+          (Decl *)ActOnStaticAssertDeclaration(SA->getLocation(), 
+                                               move(InstantiatedAssertExpr),
+                                               move(Message));
+        if (New->isInvalidDecl())
+          Invalid = true;
+          
+      } else
+        Invalid = true;
     }
   }