[OPENMP] Initial parsing and sema analysis for clause 'capture' in 'atomic' directive.

llvm-svn: 213842
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 9c05e92..5bbed68 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -2392,7 +2392,8 @@
   SourceLocation AtomicKindLoc;
   for (auto *C : Clauses) {
     if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
-        C->getClauseKind() == OMPC_update) {
+        C->getClauseKind() == OMPC_update ||
+        C->getClauseKind() == OMPC_capture) {
       if (AtomicKind != OMPC_unknown) {
         Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses)
             << SourceRange(C->getLocStart(), C->getLocEnd());
@@ -2404,25 +2405,36 @@
       }
     }
   }
+  auto Body = CS->getCapturedStmt();
   if (AtomicKind == OMPC_read) {
-    if (!isa<Expr>(CS->getCapturedStmt())) {
-      Diag(CS->getCapturedStmt()->getLocStart(),
+    if (!isa<Expr>(Body)) {
+      Diag(Body->getLocStart(),
            diag::err_omp_atomic_read_not_expression_statement);
       return StmtError();
     }
   } else if (AtomicKind == OMPC_write) {
-    if (!isa<Expr>(CS->getCapturedStmt())) {
-      Diag(CS->getCapturedStmt()->getLocStart(),
+    if (!isa<Expr>(Body)) {
+      Diag(Body->getLocStart(),
            diag::err_omp_atomic_write_not_expression_statement);
       return StmtError();
     }
   } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
-    if (!isa<Expr>(CS->getCapturedStmt())) {
-      Diag(CS->getCapturedStmt()->getLocStart(),
+    if (!isa<Expr>(Body)) {
+      Diag(Body->getLocStart(),
            diag::err_omp_atomic_update_not_expression_statement)
           << (AtomicKind == OMPC_update);
       return StmtError();
     }
+  } else if (AtomicKind == OMPC_capture) {
+    if (isa<Expr>(Body) && !isa<BinaryOperator>(Body)) {
+      Diag(Body->getLocStart(),
+           diag::err_omp_atomic_capture_not_expression_statement);
+      return StmtError();
+    } else if (!isa<Expr>(Body) && !isa<CompoundStmt>(Body)) {
+      Diag(Body->getLocStart(),
+           diag::err_omp_atomic_capture_not_compound_statement);
+      return StmtError();
+    }
   }
 
   getCurFunction()->setHasBranchProtectedScope();
@@ -2472,6 +2484,7 @@
   case OMPC_read:
   case OMPC_write:
   case OMPC_update:
+  case OMPC_capture:
   case OMPC_unknown:
     llvm_unreachable("Clause is not allowed.");
   }
@@ -2677,6 +2690,7 @@
   case OMPC_read:
   case OMPC_write:
   case OMPC_update:
+  case OMPC_capture:
   case OMPC_unknown:
     llvm_unreachable("Clause is not allowed.");
   }
@@ -2795,6 +2809,7 @@
   case OMPC_read:
   case OMPC_write:
   case OMPC_update:
+  case OMPC_capture:
   case OMPC_unknown:
     llvm_unreachable("Clause is not allowed.");
   }
@@ -2883,6 +2898,9 @@
   case OMPC_update:
     Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
     break;
+  case OMPC_capture:
+    Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
+    break;
   case OMPC_if:
   case OMPC_final:
   case OMPC_num_threads:
@@ -2944,6 +2962,11 @@
   return new (Context) OMPUpdateClause(StartLoc, EndLoc);
 }
 
+OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
+                                          SourceLocation EndLoc) {
+  return new (Context) OMPCaptureClause(StartLoc, EndLoc);
+}
+
 OMPClause *Sema::ActOnOpenMPVarListClause(
     OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
@@ -3000,6 +3023,7 @@
   case OMPC_read:
   case OMPC_write:
   case OMPC_update:
+  case OMPC_capture:
   case OMPC_unknown:
     llvm_unreachable("Clause is not allowed.");
   }