[OPENMP] Initial parsing and sema analysis for 'update' clause of 'atomic' directive.

llvm-svn: 213735
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 318b00c..0dbdf16 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -2389,7 +2389,8 @@
   OpenMPClauseKind AtomicKind = OMPC_unknown;
   SourceLocation AtomicKindLoc;
   for (auto *C : Clauses) {
-    if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write) {
+    if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
+        C->getClauseKind() == OMPC_update) {
       if (AtomicKind != OMPC_unknown) {
         Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses)
             << SourceRange(C->getLocStart(), C->getLocEnd());
@@ -2413,6 +2414,13 @@
            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(),
+           diag::err_omp_atomic_update_not_expression_statement)
+          << (AtomicKind == OMPC_update);
+      return StmtError();
+    }
   }
 
   getCurFunction()->setHasBranchProtectedScope();
@@ -2461,6 +2469,7 @@
   case OMPC_flush:
   case OMPC_read:
   case OMPC_write:
+  case OMPC_update:
   case OMPC_unknown:
     llvm_unreachable("Clause is not allowed.");
   }
@@ -2665,6 +2674,7 @@
   case OMPC_flush:
   case OMPC_read:
   case OMPC_write:
+  case OMPC_update:
   case OMPC_unknown:
     llvm_unreachable("Clause is not allowed.");
   }
@@ -2782,6 +2792,7 @@
   case OMPC_flush:
   case OMPC_read:
   case OMPC_write:
+  case OMPC_update:
   case OMPC_unknown:
     llvm_unreachable("Clause is not allowed.");
   }
@@ -2867,6 +2878,9 @@
   case OMPC_write:
     Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
     break;
+  case OMPC_update:
+    Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
+    break;
   case OMPC_if:
   case OMPC_final:
   case OMPC_num_threads:
@@ -2923,6 +2937,11 @@
   return new (Context) OMPWriteClause(StartLoc, EndLoc);
 }
 
+OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
+                                         SourceLocation EndLoc) {
+  return new (Context) OMPUpdateClause(StartLoc, EndLoc);
+}
+
 OMPClause *Sema::ActOnOpenMPVarListClause(
     OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
@@ -2978,6 +2997,7 @@
   case OMPC_threadprivate:
   case OMPC_read:
   case OMPC_write:
+  case OMPC_update:
   case OMPC_unknown:
     llvm_unreachable("Clause is not allowed.");
   }
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 66da412..16a424e 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -6775,6 +6775,13 @@
 
 template <typename Derived>
 OMPClause *
+TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
+  // No need to rebuild this clause, no template-dependent parameters.
+  return C;
+}
+
+template <typename Derived>
+OMPClause *
 TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
   llvm::SmallVector<Expr *, 16> Vars;
   Vars.reserve(C->varlist_size());