https://github.com/kparzysz created 
https://github.com/llvm/llvm-project/pull/212270

The UPDATE clause has the same spelling on both of these directives, but 
functionally it's two different clauses. Split them into "update", and 
"update_depend_objects" to be able to tie their properties to their enum ids.

This should make it easier to implement auto-generating of clause properties in 
the future by avoiding spelling conflicts.

>From 1ddc975092b94f8c91a9acf32428c74f82f9bfe6 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <[email protected]>
Date: Sat, 25 Jul 2026 09:36:02 -0500
Subject: [PATCH] [OpenMP] Split UPDATE clause into two: for ATOMIC and for
 DEPOBJ

The UPDATE clause has the same spelling on both of these directives,
but functionally it's two different clauses. Split them into "update",
and "update_depend_objects" to be able to tie their properties to their
enum ids.

This should make it easier to implement auto-generating of clause
properties in the future by avoiding spelling conflicts.
---
 clang/include/clang/AST/OpenMPClause.h        | 90 ++++++++++---------
 clang/include/clang/AST/RecursiveASTVisitor.h |  6 ++
 clang/include/clang/Sema/SemaOpenMP.h         | 12 +--
 clang/lib/AST/OpenMPClause.cpp                | 46 ++++------
 clang/lib/AST/StmtProfile.cpp                 |  3 +
 clang/lib/AST/TextNodeDumper.cpp              |  5 +-
 clang/lib/Basic/OpenMPKinds.cpp               |  4 +-
 clang/lib/CodeGen/CGOpenMPRuntime.cpp         |  6 +-
 clang/lib/CodeGen/CGOpenMPRuntime.h           |  2 +-
 clang/lib/CodeGen/CGStmtOpenMP.cpp            |  4 +-
 clang/lib/Parse/ParseOpenMP.cpp               | 18 +++-
 clang/lib/Sema/SemaOpenMP.cpp                 | 24 ++---
 clang/lib/Sema/TreeTransform.h                |  7 ++
 clang/lib/Serialization/ASTReader.cpp         | 18 ++--
 clang/lib/Serialization/ASTWriter.cpp         | 14 +--
 clang/tools/libclang/CIndex.cpp               |  3 +
 flang/include/flang/Lower/OpenMP/Clauses.h    |  2 +
 flang/include/flang/Parser/dump-parse-tree.h  |  2 +-
 flang/include/flang/Parser/parse-tree.h       |  4 +-
 flang/lib/Lower/OpenMP/Clauses.cpp            | 19 ++--
 flang/lib/Parser/openmp-parsers.cpp           | 11 ++-
 flang/lib/Semantics/check-omp-structure.cpp   | 12 +--
 flang/lib/Semantics/check-omp-structure.h     |  2 +-
 flang/lib/Semantics/openmp-modifiers.cpp      |  4 +-
 flang/test/Parser/OpenMP/atomic-compare.f90   | 12 +--
 flang/test/Parser/OpenMP/depobj-construct.f90 |  2 +-
 llvm/include/llvm/Frontend/OpenMP/ClauseT.h   | 15 +++-
 llvm/include/llvm/Frontend/OpenMP/OMP.td      | 11 ++-
 28 files changed, 204 insertions(+), 154 deletions(-)

diff --git a/clang/include/clang/AST/OpenMPClause.h 
b/clang/include/clang/AST/OpenMPClause.h
index 641c03bf8ff5c..9e9295e1a0c54 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -2967,7 +2967,40 @@ class OMPWriteClause : public OMPClause {
 /// #pragma omp atomic update
 /// \endcode
 /// In this example directive '#pragma omp atomic' has 'update' clause.
-/// Also, this class represents 'update' clause in  '#pragma omp depobj'
+class OMPUpdateClause : public OMPClause {
+public:
+  /// Build 'update' clause.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param EndLoc Ending location of the clause.
+  OMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPClause(llvm::omp::OMPC_update, StartLoc, EndLoc) {}
+
+  /// Build an empty clause.
+  OMPUpdateClause()
+      : OMPClause(llvm::omp::OMPC_update, SourceLocation(), SourceLocation()) 
{}
+
+  child_range children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+
+  const_child_range children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == llvm::omp::OMPC_update;
+  }
+};
+
+/// This class represents 'update' clause in '#pragma omp depobj'
 /// directive.
 ///
 /// \code
@@ -2975,38 +3008,32 @@ class OMPWriteClause : public OMPClause {
 /// \endcode
 /// In this example directive '#pragma omp depobj' has 'update' clause with 
'in'
 /// dependence kind.
-class OMPUpdateClause final
+class OMPUpdateDependObjectsClause final
     : public OMPClause,
-      private llvm::TrailingObjects<OMPUpdateClause, SourceLocation,
-                                    OpenMPDependClauseKind> {
+      private llvm::TrailingObjects<OMPUpdateDependObjectsClause,
+                                    SourceLocation, OpenMPDependClauseKind> {
   friend class OMPClauseReader;
   friend TrailingObjects;
 
-  /// true if extended version of the clause for 'depobj' directive.
-  bool IsExtended = false;
-
   /// Define the sizes of each trailing object array except the last one. This
   /// is required for TrailingObjects to work properly.
   size_t numTrailingObjects(OverloadToken<SourceLocation>) const {
     // 2 locations: for '(' and argument location.
-    return IsExtended ? 2 : 0;
+    return 2;
   }
 
   /// Sets the location of '(' in clause for 'depobj' directive.
   void setLParenLoc(SourceLocation Loc) {
-    assert(IsExtended && "Expected extended clause.");
     *getTrailingObjects<SourceLocation>() = Loc;
   }
 
   /// Sets the location of '(' in clause for 'depobj' directive.
   void setArgumentLoc(SourceLocation Loc) {
-    assert(IsExtended && "Expected extended clause.");
     *std::next(getTrailingObjects<SourceLocation>(), 1) = Loc;
   }
 
   /// Sets the dependence kind for the clause for 'depobj' directive.
   void setDependencyKind(OpenMPDependClauseKind DK) {
-    assert(IsExtended && "Expected extended clause.");
     *getTrailingObjects<OpenMPDependClauseKind>() = DK;
   }
 
@@ -3014,25 +3041,15 @@ class OMPUpdateClause final
   ///
   /// \param StartLoc Starting location of the clause.
   /// \param EndLoc Ending location of the clause.
-  OMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc,
-                  bool IsExtended)
-      : OMPClause(llvm::omp::OMPC_update, StartLoc, EndLoc),
-        IsExtended(IsExtended) {}
+  OMPUpdateDependObjectsClause(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPClause(llvm::omp::OMPC_update_depend_objects, StartLoc, EndLoc) {}
 
   /// Build an empty clause.
-  OMPUpdateClause(bool IsExtended)
-      : OMPClause(llvm::omp::OMPC_update, SourceLocation(), SourceLocation()),
-        IsExtended(IsExtended) {}
+  OMPUpdateDependObjectsClause()
+      : OMPClause(llvm::omp::OMPC_update_depend_objects, SourceLocation(),
+                  SourceLocation()) {}
 
 public:
-  /// Creates clause for 'atomic' directive.
-  ///
-  /// \param C AST context.
-  /// \param StartLoc Starting location of the clause.
-  /// \param EndLoc Ending location of the clause.
-  static OMPUpdateClause *Create(const ASTContext &C, SourceLocation StartLoc,
-                                 SourceLocation EndLoc);
-
   /// Creates clause for 'depobj' directive.
   ///
   /// \param C AST context.
@@ -3041,21 +3058,15 @@ class OMPUpdateClause final
   /// \param ArgumentLoc Location of the argument.
   /// \param DK Dependence kind.
   /// \param EndLoc Ending location of the clause.
-  static OMPUpdateClause *Create(const ASTContext &C, SourceLocation StartLoc,
-                                 SourceLocation LParenLoc,
-                                 SourceLocation ArgumentLoc,
-                                 OpenMPDependClauseKind DK,
-                                 SourceLocation EndLoc);
+  static OMPUpdateDependObjectsClause *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation 
LParenLoc,
+         SourceLocation ArgumentLoc, OpenMPDependClauseKind DK,
+         SourceLocation EndLoc);
 
   /// Creates an empty clause with the place for \a N variables.
   ///
   /// \param C AST context.
-  /// \param IsExtended true if extended clause for 'depobj' directive must be
-  /// created.
-  static OMPUpdateClause *CreateEmpty(const ASTContext &C, bool IsExtended);
-
-  /// Checks if the clause is the extended clauses for 'depobj' directive.
-  bool isExtended() const { return IsExtended; }
+  static OMPUpdateDependObjectsClause *CreateEmpty(const ASTContext &C);
 
   child_range children() {
     return child_range(child_iterator(), child_iterator());
@@ -3074,24 +3085,21 @@ class OMPUpdateClause final
 
   /// Gets the location of '(' in clause for 'depobj' directive.
   SourceLocation getLParenLoc() const {
-    assert(IsExtended && "Expected extended clause.");
     return *getTrailingObjects<SourceLocation>();
   }
 
   /// Gets the location of argument in clause for 'depobj' directive.
   SourceLocation getArgumentLoc() const {
-    assert(IsExtended && "Expected extended clause.");
     return *std::next(getTrailingObjects<SourceLocation>(), 1);
   }
 
   /// Gets the dependence kind in clause for 'depobj' directive.
   OpenMPDependClauseKind getDependencyKind() const {
-    assert(IsExtended && "Expected extended clause.");
     return *getTrailingObjects<OpenMPDependClauseKind>();
   }
 
   static bool classof(const OMPClause *T) {
-    return T->getClauseKind() == llvm::omp::OMPC_update;
+    return T->getClauseKind() == llvm::omp::OMPC_update_depend_objects;
   }
 };
 
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h 
b/clang/include/clang/AST/RecursiveASTVisitor.h
index cdf8a71d54cc9..6913e9b614315 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -3710,6 +3710,12 @@ bool 
RecursiveASTVisitor<Derived>::VisitOMPUpdateClause(OMPUpdateClause *) {
   return true;
 }
 
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPUpdateDependObjectsClause(
+    OMPUpdateDependObjectsClause *) {
+  return true;
+}
+
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPCaptureClause(OMPCaptureClause *) {
   return true;
diff --git a/clang/include/clang/Sema/SemaOpenMP.h 
b/clang/include/clang/Sema/SemaOpenMP.h
index 9ef388a744db8..361473140e236 100644
--- a/clang/include/clang/Sema/SemaOpenMP.h
+++ b/clang/include/clang/Sema/SemaOpenMP.h
@@ -1012,12 +1012,12 @@ class SemaOpenMP : public SemaBase {
                                     SourceLocation LParenLoc,
                                     SourceLocation MLoc, SourceLocation 
KindLoc,
                                     SourceLocation EndLoc);
-  /// Called on well-formed 'update' clause.
-  OMPClause *ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
-                                     SourceLocation KindLoc,
-                                     SourceLocation StartLoc,
-                                     SourceLocation LParenLoc,
-                                     SourceLocation EndLoc);
+  /// Called on well-formed 'update_depend_objects' clause.
+  OMPClause *ActOnOpenMPUpdateDependObjectsClause(OpenMPDependClauseKind Kind,
+                                                  SourceLocation KindLoc,
+                                                  SourceLocation StartLoc,
+                                                  SourceLocation LParenLoc,
+                                                  SourceLocation EndLoc);
   /// Called on well-formed 'holds' clause.
   OMPClause *ActOnOpenMPHoldsClause(Expr *E, SourceLocation StartLoc,
                                     SourceLocation LParenLoc,
diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index d451255bf5845..cac701994def8 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -409,36 +409,26 @@ const Expr *OMPOrderedClause::getLoopCounter(unsigned 
NumLoop) const {
   return getTrailingObjects()[NumberOfLoops + NumLoop];
 }
 
-OMPUpdateClause *OMPUpdateClause::Create(const ASTContext &C,
-                                         SourceLocation StartLoc,
-                                         SourceLocation EndLoc) {
-  return new (C) OMPUpdateClause(StartLoc, EndLoc, /*IsExtended=*/false);
-}
-
-OMPUpdateClause *
-OMPUpdateClause::Create(const ASTContext &C, SourceLocation StartLoc,
-                        SourceLocation LParenLoc, SourceLocation ArgumentLoc,
-                        OpenMPDependClauseKind DK, SourceLocation EndLoc) {
+OMPUpdateDependObjectsClause *OMPUpdateDependObjectsClause::Create(
+    const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+    SourceLocation ArgumentLoc, OpenMPDependClauseKind DK,
+    SourceLocation EndLoc) {
   void *Mem =
       C.Allocate(totalSizeToAlloc<SourceLocation, OpenMPDependClauseKind>(2, 
1),
-                 alignof(OMPUpdateClause));
-  auto *Clause =
-      new (Mem) OMPUpdateClause(StartLoc, EndLoc, /*IsExtended=*/true);
+                 alignof(OMPUpdateDependObjectsClause));
+  auto *Clause = new (Mem) OMPUpdateDependObjectsClause(StartLoc, EndLoc);
   Clause->setLParenLoc(LParenLoc);
   Clause->setArgumentLoc(ArgumentLoc);
   Clause->setDependencyKind(DK);
   return Clause;
 }
 
-OMPUpdateClause *OMPUpdateClause::CreateEmpty(const ASTContext &C,
-                                              bool IsExtended) {
-  if (!IsExtended)
-    return new (C) OMPUpdateClause(/*IsExtended=*/false);
+OMPUpdateDependObjectsClause *
+OMPUpdateDependObjectsClause::CreateEmpty(const ASTContext &C) {
   void *Mem =
       C.Allocate(totalSizeToAlloc<SourceLocation, OpenMPDependClauseKind>(2, 
1),
-                 alignof(OMPUpdateClause));
-  auto *Clause = new (Mem) OMPUpdateClause(/*IsExtended=*/true);
-  Clause->IsExtended = true;
+                 alignof(OMPUpdateDependObjectsClause));
+  auto *Clause = new (Mem) OMPUpdateDependObjectsClause();
   return Clause;
 }
 
@@ -2261,14 +2251,16 @@ void OMPClausePrinter::VisitOMPReadClause(OMPReadClause 
*) { OS << "read"; }
 
 void OMPClausePrinter::VisitOMPWriteClause(OMPWriteClause *) { OS << "write"; }
 
-void OMPClausePrinter::VisitOMPUpdateClause(OMPUpdateClause *Node) {
+void OMPClausePrinter::VisitOMPUpdateClause(OMPUpdateClause *) {
   OS << "update";
-  if (Node->isExtended()) {
-    OS << "(";
-    OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(),
-                                        Node->getDependencyKind());
-    OS << ")";
-  }
+}
+
+void OMPClausePrinter::VisitOMPUpdateDependObjectsClause(
+    OMPUpdateDependObjectsClause *Node) {
+  OS << "update(";
+  OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(),
+                                      Node->getDependencyKind());
+  OS << ")";
 }
 
 void OMPClausePrinter::VisitOMPCaptureClause(OMPCaptureClause *) {
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 00c132f1ed9e0..ec4493d0afa41 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -630,6 +630,9 @@ void OMPClauseProfiler::VisitOMPWriteClause(const 
OMPWriteClause *) {}
 
 void OMPClauseProfiler::VisitOMPUpdateClause(const OMPUpdateClause *) {}
 
+void OMPClauseProfiler::VisitOMPUpdateDependObjectsClause(
+    const OMPUpdateDependObjectsClause *) {}
+
 void OMPClauseProfiler::VisitOMPCaptureClause(const OMPCaptureClause *) {}
 
 void OMPClauseProfiler::VisitOMPCompareClause(const OMPCompareClause *) {}
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index 4bc7607a87d92..b2b3eda9ff2e3 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -372,7 +372,10 @@ void TextNodeDumper::Visit(const OMPClause *C) {
   }
   {
     ColorScope Color(OS, ShowColors, ASTDumpColor::Attr);
-    StringRef ClauseName(llvm::omp::getOpenMPClauseName(C->getClauseKind()));
+    OpenMPClauseKind CKind = C->getClauseKind();
+    StringRef ClauseName(CKind == llvm::omp::Clause::OMPC_update_depend_objects
+                             ? StringRef("UpdateDependObjects")
+                             : llvm::omp::getOpenMPClauseName(CKind));
     OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
        << ClauseName.drop_front() << "Clause";
   }
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 5dd2a728ee1cd..1a2a963243f6c 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -162,7 +162,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind 
Kind, StringRef Str,
   .Case(#Name, static_cast<unsigned>(OMPC_ORDER_MODIFIER_##Name))
 #include "clang/Basic/OpenMPKinds.def"
         .Default(OMPC_ORDER_unknown);
-  case OMPC_update:
+  case OMPC_update_depend_objects:
     return llvm::StringSwitch<OpenMPDependClauseKind>(Str)
 #define OPENMP_DEPEND_KIND(Name) .Case(#Name, OMPC_DEPEND_##Name)
 #include "clang/Basic/OpenMPKinds.def"
@@ -517,7 +517,7 @@ const char 
*clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
 #include "clang/Basic/OpenMPKinds.def"
     }
     llvm_unreachable("Invalid OpenMP 'order' clause type");
-  case OMPC_update:
+  case OMPC_update_depend_objects:
     switch (Type) {
     case OMPC_DEPEND_unknown:
       return "unknown";
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp 
b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index c338935950b32..9e71e82e5ee86 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -4620,9 +4620,9 @@ void CGOpenMPRuntime::emitDestroyClause(CodeGenFunction 
&CGF, LValue DepobjLVal,
                             Args);
 }
 
-void CGOpenMPRuntime::emitUpdateClause(CodeGenFunction &CGF, LValue DepobjLVal,
-                                       OpenMPDependClauseKind NewDepKind,
-                                       SourceLocation Loc) {
+void CGOpenMPRuntime::emitUpdateDependObjectsClause(
+    CodeGenFunction &CGF, LValue DepobjLVal, OpenMPDependClauseKind NewDepKind,
+    SourceLocation Loc) {
   ASTContext &C = CGM.getContext();
   QualType FlagsTy;
   getDependTypes(C, KmpDependInfoTy, FlagsTy);
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.h 
b/clang/lib/CodeGen/CGOpenMPRuntime.h
index a81d3830a8035..6b29fdb4fafb5 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.h
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.h
@@ -1702,7 +1702,7 @@ class CGOpenMPRuntime {
   /// Updates the dependency kind in the specified depobj object.
   /// \param DepobjLVal LValue for the main depobj object.
   /// \param NewDepKind New dependency kind.
-  void emitUpdateClause(CodeGenFunction &CGF, LValue DepobjLVal,
+  void emitUpdateDependObjectsClause(CodeGenFunction &CGF, LValue DepobjLVal,
                         OpenMPDependClauseKind NewDepKind, SourceLocation Loc);
 
   /// Initializes user defined allocators specified in the uses_allocators
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp 
b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 18524a7c32b7a..97c43b4c0b384 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -6002,8 +6002,8 @@ void CodeGenFunction::EmitOMPDepobjDirective(const 
OMPDepobjDirective &S) {
     CGM.getOpenMPRuntime().emitDestroyClause(*this, DOLVal, DC->getBeginLoc());
     return;
   }
-  if (const auto *UC = S.getSingleClause<OMPUpdateClause>()) {
-    CGM.getOpenMPRuntime().emitUpdateClause(
+  if (const auto *UC = S.getSingleClause<OMPUpdateDependObjectsClause>()) {
+    CGM.getOpenMPRuntime().emitUpdateDependObjectsClause(
         *this, DOLVal, UC->getDependencyKind(), UC->getBeginLoc());
     return;
   }
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 045b704f5480c..2c65651c49750 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -1597,6 +1597,8 @@ void Parser::ParseOpenMPClauses(OpenMPDirectiveKind DKind,
     OpenMPClauseKind CKind = Tok.isAnnotation()
                                  ? OMPC_unknown
                                  : getOpenMPClauseKind(PP.getSpelling(Tok));
+    if (DKind == OMPD_depobj && CKind == OMPC_update)
+      CKind = OMPC_update_depend_objects;
     Actions.OpenMP().StartOpenMPClause(CKind);
     OMPClause *Clause =
         ParseOpenMPClause(DKind, CKind, !SeenClauses[unsigned(CKind)]);
@@ -2374,6 +2376,9 @@ StmtResult Parser::ParseOpenMPExecutableDirective(
     OpenMPClauseKind CKind = Tok.isAnnotation()
                                  ? OMPC_unknown
                                  : getOpenMPClauseKind(PP.getSpelling(Tok));
+    if (DKind == OMPD_depobj && CKind == OMPC_update)
+      CKind = OMPC_update_depend_objects;
+
     if (HasImplicitClause) {
       assert(CKind == OMPC_unknown && "Must be unknown implicit clause.");
       if (DKind == OMPD_flush) {
@@ -3421,10 +3426,17 @@ OMPClause 
*Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
           << getOpenMPClauseName(CKind) << 0;
       ErrorFound = true;
     }
+    Clause = ParseOpenMPClause(CKind, WrongDirective);
+    break;
+  case OMPC_update_depend_objects:
+    if (!FirstClause) {
+      Diag(Tok, diag::err_omp_more_one_clause)
+          << getOpenMPDirectiveName(DKind, OMPVersion)
+          << getOpenMPClauseName(CKind) << 0;
+      ErrorFound = true;
+    }
 
-    Clause = (DKind == OMPD_depobj)
-                 ? ParseOpenMPSimpleClause(CKind, WrongDirective)
-                 : ParseOpenMPClause(CKind, WrongDirective);
+    Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
     break;
   case OMPC_num_teams:
   case OMPC_thread_limit:
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 5b59eacb3eea8..76bb0d38d428f 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -17674,9 +17674,10 @@ OMPClause *SemaOpenMP::ActOnOpenMPSimpleClause(
     Res = ActOnOpenMPFailClause(static_cast<OpenMPClauseKind>(Argument),
                                 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
     break;
-  case OMPC_update:
-    Res = 
ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
-                                  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
+  case OMPC_update_depend_objects:
+    Res = ActOnOpenMPUpdateDependObjectsClause(
+        static_cast<OpenMPDependClauseKind>(Argument), ArgumentLoc, StartLoc,
+        LParenLoc, EndLoc);
     break;
   case OMPC_bind:
     Res = ActOnOpenMPBindClause(static_cast<OpenMPBindClauseKind>(Argument),
@@ -17728,6 +17729,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPSimpleClause(
   case OMPC_write:
   case OMPC_capture:
   case OMPC_compare:
+  case OMPC_update:
   case OMPC_seq_cst:
   case OMPC_acq_rel:
   case OMPC_acquire:
@@ -18137,11 +18139,9 @@ OMPClause *SemaOpenMP::ActOnOpenMPOrderClause(
       Kind, KindLoc, StartLoc, LParenLoc, EndLoc, Modifier, MLoc);
 }
 
-OMPClause *SemaOpenMP::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
-                                               SourceLocation KindKwLoc,
-                                               SourceLocation StartLoc,
-                                               SourceLocation LParenLoc,
-                                               SourceLocation EndLoc) {
+OMPClause *SemaOpenMP::ActOnOpenMPUpdateDependObjectsClause(
+    OpenMPDependClauseKind Kind, SourceLocation KindKwLoc,
+    SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
   if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
       Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
     SmallVector<unsigned> Except = {
@@ -18152,11 +18152,11 @@ OMPClause 
*SemaOpenMP::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
         << getListOfPossibleValues(OMPC_depend, /*First=*/0,
                                    /*Last=*/OMPC_DEPEND_unknown, Except)
-        << getOpenMPClauseNameForDiag(OMPC_update);
+        << getOpenMPClauseNameForDiag(OMPC_update_depend_objects);
     return nullptr;
   }
-  return OMPUpdateClause::Create(getASTContext(), StartLoc, LParenLoc,
-                                 KindKwLoc, Kind, EndLoc);
+  return OMPUpdateDependObjectsClause::Create(
+      getASTContext(), StartLoc, LParenLoc, KindKwLoc, Kind, EndLoc);
 }
 
 OMPClause *SemaOpenMP::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs,
@@ -18841,7 +18841,7 @@ OMPClause 
*SemaOpenMP::ActOnOpenMPWriteClause(SourceLocation StartLoc,
 
 OMPClause *SemaOpenMP::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
                                                SourceLocation EndLoc) {
-  return OMPUpdateClause::Create(getASTContext(), StartLoc, EndLoc);
+  return new (getASTContext()) OMPUpdateClause(StartLoc, EndLoc);
 }
 
 OMPClause *SemaOpenMP::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 0f6f168d06812..6e4e8cbecca93 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -11100,6 +11100,13 @@ 
TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
   return C;
 }
 
+template <typename Derived>
+OMPClause *TreeTransform<Derived>::TransformOMPUpdateDependObjectsClause(
+    OMPUpdateDependObjectsClause *C) {
+  // No need to rebuild this clause, no template-dependent parameters.
+  return C;
+}
+
 template <typename Derived>
 OMPClause *
 TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
diff --git a/clang/lib/Serialization/ASTReader.cpp 
b/clang/lib/Serialization/ASTReader.cpp
index 8b7eaaac021eb..0cb44da23d855 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -11559,7 +11559,10 @@ OMPClause *OMPClauseReader::readClause() {
     C = new (Context) OMPWriteClause();
     break;
   case llvm::omp::OMPC_update:
-    C = OMPUpdateClause::CreateEmpty(Context, Record.readInt());
+    C = new (Context) OMPUpdateClause();
+    break;
+  case llvm::omp::OMPC_update_depend_objects:
+    C = OMPUpdateDependObjectsClause::CreateEmpty(Context);
     break;
   case llvm::omp::OMPC_capture:
     C = new (Context) OMPCaptureClause();
@@ -12037,12 +12040,13 @@ void 
OMPClauseReader::VisitOMPReadClause(OMPReadClause *) {}
 
 void OMPClauseReader::VisitOMPWriteClause(OMPWriteClause *) {}
 
-void OMPClauseReader::VisitOMPUpdateClause(OMPUpdateClause *C) {
-  if (C->isExtended()) {
-    C->setLParenLoc(Record.readSourceLocation());
-    C->setArgumentLoc(Record.readSourceLocation());
-    C->setDependencyKind(Record.readEnum<OpenMPDependClauseKind>());
-  }
+void OMPClauseReader::VisitOMPUpdateClause(OMPUpdateClause *) {}
+
+void OMPClauseReader::VisitOMPUpdateDependObjectsClause(
+    OMPUpdateDependObjectsClause *C) {
+  C->setLParenLoc(Record.readSourceLocation());
+  C->setArgumentLoc(Record.readSourceLocation());
+  C->setDependencyKind(Record.readEnum<OpenMPDependClauseKind>());
 }
 
 void OMPClauseReader::VisitOMPCaptureClause(OMPCaptureClause *) {}
diff --git a/clang/lib/Serialization/ASTWriter.cpp 
b/clang/lib/Serialization/ASTWriter.cpp
index fc53aee000ef2..f34b2ff182bc8 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -8207,13 +8207,13 @@ void OMPClauseWriter::VisitOMPReadClause(OMPReadClause 
*) {}
 
 void OMPClauseWriter::VisitOMPWriteClause(OMPWriteClause *) {}
 
-void OMPClauseWriter::VisitOMPUpdateClause(OMPUpdateClause *C) {
-  Record.push_back(C->isExtended() ? 1 : 0);
-  if (C->isExtended()) {
-    Record.AddSourceLocation(C->getLParenLoc());
-    Record.AddSourceLocation(C->getArgumentLoc());
-    Record.writeEnum(C->getDependencyKind());
-  }
+void OMPClauseWriter::VisitOMPUpdateClause(OMPUpdateClause *) {}
+
+void OMPClauseWriter::VisitOMPUpdateDependObjectsClause(
+    OMPUpdateDependObjectsClause *C) {
+  Record.AddSourceLocation(C->getLParenLoc());
+  Record.AddSourceLocation(C->getArgumentLoc());
+  Record.writeEnum(C->getDependencyKind());
 }
 
 void OMPClauseWriter::VisitOMPCaptureClause(OMPCaptureClause *) {}
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 7c9da867909f5..7eeeba9c7948d 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -2421,6 +2421,9 @@ void OMPClauseEnqueue::VisitOMPWriteClause(const 
OMPWriteClause *) {}
 
 void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
 
+void OMPClauseEnqueue::VisitOMPUpdateDependObjectsClause(
+    const OMPUpdateDependObjectsClause *) {}
+
 void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
 
 void OMPClauseEnqueue::VisitOMPCompareClause(const OMPCompareClause *) {}
diff --git a/flang/include/flang/Lower/OpenMP/Clauses.h 
b/flang/include/flang/Lower/OpenMP/Clauses.h
index f334374280c73..f2ce74301a238 100644
--- a/flang/include/flang/Lower/OpenMP/Clauses.h
+++ b/flang/include/flang/Lower/OpenMP/Clauses.h
@@ -322,6 +322,8 @@ using Uniform = tomp::clause::UniformT<TypeTy, IdTy, 
ExprTy>;
 using Unknown = tomp::clause::UnknownT<TypeTy, IdTy, ExprTy>;
 using Untied = tomp::clause::UntiedT<TypeTy, IdTy, ExprTy>;
 using Update = tomp::clause::UpdateT<TypeTy, IdTy, ExprTy>;
+using UpdateDependObjects =
+    tomp::clause::UpdateDependObjectsT<TypeTy, IdTy, ExprTy>;
 using Use = tomp::clause::UseT<TypeTy, IdTy, ExprTy>;
 using UseDeviceAddr = tomp::clause::UseDeviceAddrT<TypeTy, IdTy, ExprTy>;
 using UseDevicePtr = tomp::clause::UseDevicePtrT<TypeTy, IdTy, ExprTy>;
diff --git a/flang/include/flang/Parser/dump-parse-tree.h 
b/flang/include/flang/Parser/dump-parse-tree.h
index 6750127945b51..729bcbc9b7cab 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -776,7 +776,7 @@ class ParseTreeDumper {
   NODE(parser, OmpTypeNameList)
   NODE(parser, OmpUnifiedAddressClause)
   NODE(parser, OmpUnifiedSharedMemoryClause)
-  NODE(parser, OmpUpdateClause)
+  NODE(parser, OmpUpdateDependObjectsClause)
   NODE(parser, OmpUseClause)
   NODE(parser, OmpUtilityDirective)
   NODE(parser, OmpVariableCategory)
diff --git a/flang/include/flang/Parser/parse-tree.h 
b/flang/include/flang/Parser/parse-tree.h
index 0862800601c29..f9b7ec51c87e0 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -5113,8 +5113,8 @@ struct OmpUnifiedSharedMemoryClause {
 //    UPDATE(dependence-type)                       // since 5.0, until 5.1
 // update-clause ->
 //    UPDATE(task-dependence-type)                  // since 5.2
-struct OmpUpdateClause {
-  UNION_CLASS_BOILERPLATE(OmpUpdateClause);
+struct OmpUpdateDependObjectsClause {
+  UNION_CLASS_BOILERPLATE(OmpUpdateDependObjectsClause);
   // The dependence type is an argument here, not a modifier.
   std::variant<OmpDependenceType, OmpTaskDependenceType> u;
 };
diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp 
b/flang/lib/Lower/OpenMP/Clauses.cpp
index f8cbbd17a55b9..9db79110df9e5 100644
--- a/flang/lib/Lower/OpenMP/Clauses.cpp
+++ b/flang/lib/Lower/OpenMP/Clauses.cpp
@@ -294,6 +294,7 @@ MAKE_EMPTY_CLASS(Simd, Simd);
 MAKE_EMPTY_CLASS(Threads, Threads);
 MAKE_EMPTY_CLASS(Unknown, Unknown);
 MAKE_EMPTY_CLASS(Untied, Untied);
+MAKE_EMPTY_CLASS(Update, Update);
 MAKE_EMPTY_CLASS(Weak, Weak);
 MAKE_EMPTY_CLASS(Write, Write);
 
@@ -1755,16 +1756,14 @@ Uniform make(const parser::OmpClause::Uniform &inp,
 // Unknown: empty
 // Untied: empty
 
-Update make(const parser::OmpClause::Update &inp,
-            semantics::SemanticsContext &semaCtx) {
-  // inp.v -> parser::OmpUpdateClause
-  if (inp.v) {
-    return common::visit(
-        [](auto &&s) { return Update{/*DependenceType=*/makeDepType(s)}; },
-        inp.v->u);
-  } else {
-    return Update{/*DependenceType=*/std::nullopt};
-  }
+UpdateDependObjects make(const parser::OmpClause::UpdateDependObjects &inp,
+                         semantics::SemanticsContext &semaCtx) {
+  // inp.v -> parser::OmpUpdateDependObjectsClause
+  return common::visit(
+      [](auto &&s) {
+        return UpdateDependObjects{/*DependenceType=*/makeDepType(s)};
+      },
+      inp.v.u);
 }
 
 Use make(const parser::OmpClause::Use &inp,
diff --git a/flang/lib/Parser/openmp-parsers.cpp 
b/flang/lib/Parser/openmp-parsers.cpp
index 11d0aa9e1359b..6cf57040cecd2 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1416,8 +1416,10 @@ 
TYPE_PARSER(construct<OmpAlignedClause>(Parser<OmpObjectList>{},
     maybe(":" >> nonemptyList(Parser<OmpAlignedClause::Modifier>{}))))
 
 TYPE_PARSER( //
-    construct<OmpUpdateClause>(parenthesized(Parser<OmpDependenceType>{})) ||
-    construct<OmpUpdateClause>(parenthesized(Parser<OmpTaskDependenceType>{})))
+    construct<OmpUpdateDependObjectsClause>(
+        parenthesized(Parser<OmpDependenceType>{})) ||
+    construct<OmpUpdateDependObjectsClause>(
+        parenthesized(Parser<OmpTaskDependenceType>{})))
 
 TYPE_PARSER(construct<OmpOrderClause>(
     maybe(nonemptyList(Parser<OmpOrderClause::Modifier>{}) / ":"),
@@ -1708,8 +1710,9 @@ TYPE_PARSER( //
     "UNIFORM" >> construct<OmpClause>(construct<OmpClause::Uniform>(
                      parenthesized(nonemptyList(name)))) ||
     "UNTIED" >> construct<OmpClause>(construct<OmpClause::Untied>()) ||
-    "UPDATE" >> construct<OmpClause>(construct<OmpClause::Update>(
-                    maybe(Parser<OmpUpdateClause>{}))) ||
+    "UPDATE" >> 
(construct<OmpClause>(construct<OmpClause::UpdateDependObjects>(
+                     Parser<OmpUpdateDependObjectsClause>{})) ||
+                    construct<OmpClause>(construct<OmpClause::Update>())) ||
     "WEAK" >> construct<OmpClause>(construct<OmpClause::Weak>()) ||
     "WHEN" >> construct<OmpClause>(construct<OmpClause::When>(
                   parenthesized(Parser<OmpWhenClause>{}))) ||
diff --git a/flang/lib/Semantics/check-omp-structure.cpp 
b/flang/lib/Semantics/check-omp-structure.cpp
index f77382c9045fc..dcb01eb967c72 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -5286,17 +5286,13 @@ void OmpStructureChecker::CheckStructureComponent(
   }
 }
 
-void OmpStructureChecker::Enter(const parser::OmpClause::Update &x) {
+void OmpStructureChecker::Enter(
+    const parser::OmpClause::UpdateDependObjects &x) {
   llvm::omp::Directive dir{GetContext().directive};
   unsigned version{context_.langOptions().OpenMPVersion};
 
-  const parser::OmpDependenceType *depType{nullptr};
-  const parser::OmpTaskDependenceType *taskType{nullptr};
-  if (auto &maybeUpdate{x.v}) {
-    depType = std::get_if<parser::OmpDependenceType>(&maybeUpdate->u);
-    taskType = std::get_if<parser::OmpTaskDependenceType>(&maybeUpdate->u);
-  }
-
+  auto *depType = std::get_if<parser::OmpDependenceType>(&x.v.u);
+  auto *taskType = std::get_if<parser::OmpTaskDependenceType>(&x.v.u);
   if (!depType && !taskType) {
     assert(dir == llvm::omp::Directive::OMPD_atomic &&
         "Unexpected alternative in update clause");
diff --git a/flang/lib/Semantics/check-omp-structure.h 
b/flang/lib/Semantics/check-omp-structure.h
index f8aa47043a614..4acec2ad05ba1 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -238,7 +238,7 @@ class OmpStructureChecker : public OmpStructureCheckerBase {
   void Enter(const parser::OmpClause::To &x);
   void Enter(const parser::OmpClause::UnifiedAddress &x);
   void Enter(const parser::OmpClause::UnifiedSharedMemory &x);
-  void Enter(const parser::OmpClause::Update &x);
+  void Enter(const parser::OmpClause::UpdateDependObjects &x);
   void Enter(const parser::OmpClause::UseDeviceAddr &x);
   void Enter(const parser::OmpClause::UseDevicePtr &x);
   void Enter(const parser::OmpClause::When &x);
diff --git a/flang/lib/Semantics/openmp-modifiers.cpp 
b/flang/lib/Semantics/openmp-modifiers.cpp
index fe8e087cd5a94..f3ee8917356fa 100644
--- a/flang/lib/Semantics/openmp-modifiers.cpp
+++ b/flang/lib/Semantics/openmp-modifiers.cpp
@@ -281,7 +281,7 @@ const OmpModifierDescriptor 
&OmpGetDescriptor<parser::OmpDependenceType>() {
       /*clauses=*/
       {
           {45, {Clause::OMPC_depend}},
-          {51, {Clause::OMPC_depend, Clause::OMPC_update}},
+          {51, {Clause::OMPC_depend, Clause::OMPC_update_depend_objects}},
           {52, {Clause::OMPC_doacross}},
       },
   };
@@ -731,7 +731,7 @@ const OmpModifierDescriptor 
&OmpGetDescriptor<parser::OmpTaskDependenceType>() {
       /*clauses=*/
       {
           {45, {Clause::OMPC_depend}},
-          {51, {Clause::OMPC_depend, Clause::OMPC_update}},
+          {51, {Clause::OMPC_depend, Clause::OMPC_update_depend_objects}},
       },
   };
   return desc;
diff --git a/flang/test/Parser/OpenMP/atomic-compare.f90 
b/flang/test/Parser/OpenMP/atomic-compare.f90
index 7e80b9c8505e5..6707a66e751a0 100644
--- a/flang/test/Parser/OpenMP/atomic-compare.f90
+++ b/flang/test/Parser/OpenMP/atomic-compare.f90
@@ -18,7 +18,7 @@ subroutine f00(a, b)
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct 
-> OpenMPAtomicConstruct
 !PARSE-TREE: | OmpBeginDirective
 !PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = atomic
-!PARSE-TREE: | | OmpClauseList -> OmpClause -> Update ->
+!PARSE-TREE: | | OmpClauseList -> OmpClause -> Update
 !PARSE-TREE: | | OmpClause -> Compare
 !PARSE-TREE: | | Flags = {}
 !PARSE-TREE: | Block
@@ -56,7 +56,7 @@ subroutine f01(a, b)
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct 
-> OpenMPAtomicConstruct
 !PARSE-TREE: | OmpBeginDirective
 !PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = atomic
-!PARSE-TREE: | | OmpClauseList -> OmpClause -> Update ->
+!PARSE-TREE: | | OmpClauseList -> OmpClause -> Update
 !PARSE-TREE: | | OmpClause -> Compare
 !PARSE-TREE: | | Flags = {}
 !PARSE-TREE: | Block
@@ -110,7 +110,7 @@ subroutine f02(a, b)
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct 
-> OpenMPAtomicConstruct
 !PARSE-TREE: | OmpBeginDirective
 !PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = atomic
-!PARSE-TREE: | | OmpClauseList -> OmpClause -> Update ->
+!PARSE-TREE: | | OmpClauseList -> OmpClause -> Update
 !PARSE-TREE: | | OmpClause -> Compare
 !PARSE-TREE: | | Flags = {}
 !PARSE-TREE: | Block
@@ -147,7 +147,7 @@ subroutine g00(a, b)
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct 
-> OpenMPAtomicConstruct
 !PARSE-TREE: | OmpBeginDirective
 !PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = atomic
-!PARSE-TREE: | | OmpClauseList -> OmpClause -> Update ->
+!PARSE-TREE: | | OmpClauseList -> OmpClause -> Update
 !PARSE-TREE: | | OmpClause -> Capture
 !PARSE-TREE: | | OmpClause -> Compare
 !PARSE-TREE: | | Flags = {}
@@ -199,7 +199,7 @@ subroutine g01(a, b)
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct 
-> OpenMPAtomicConstruct
 !PARSE-TREE: | OmpBeginDirective
 !PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = atomic
-!PARSE-TREE: | | OmpClauseList -> OmpClause -> Update ->
+!PARSE-TREE: | | OmpClauseList -> OmpClause -> Update
 !PARSE-TREE: | | OmpClause -> Capture
 !PARSE-TREE: | | OmpClause -> Compare
 !PARSE-TREE: | | Flags = {}
@@ -256,7 +256,7 @@ subroutine g02(a, b)
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct 
-> OpenMPAtomicConstruct
 !PARSE-TREE: | OmpBeginDirective
 !PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = atomic
-!PARSE-TREE: | | OmpClauseList -> OmpClause -> Update ->
+!PARSE-TREE: | | OmpClauseList -> OmpClause -> Update
 !PARSE-TREE: | | OmpClause -> Capture
 !PARSE-TREE: | | OmpClause -> Compare
 !PARSE-TREE: | | Flags = {}
diff --git a/flang/test/Parser/OpenMP/depobj-construct.f90 
b/flang/test/Parser/OpenMP/depobj-construct.f90
index 9a49976cfd4b0..37fa0ce8fa5e4 100644
--- a/flang/test/Parser/OpenMP/depobj-construct.f90
+++ b/flang/test/Parser/OpenMP/depobj-construct.f90
@@ -31,7 +31,7 @@ subroutine f01
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct 
-> OpenMPStandaloneConstruct -> OpenMPDepobjConstruct -> 
OmpDirectiveSpecification
 !PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = depobj
 !PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpObject -> Designator -> 
DataRef -> Name = 'x'
-!PARSE-TREE: | OmpClauseList -> OmpClause -> Update -> OmpUpdateClause -> 
OmpTaskDependenceType -> OmpDependenceKind = Out
+!PARSE-TREE: | OmpClauseList -> OmpClause -> UpdateDependObjects -> 
OmpUpdateDependObjectsClause -> OmpTaskDependenceType -> OmpDependenceKind = Out
 
 subroutine f02
   integer :: x
diff --git a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h 
b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
index b2f809e9b51ee..0c5b0d5566258 100644
--- a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
+++ b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
@@ -1322,9 +1322,14 @@ struct UntiedT {
 // V5.2: [15.9.3] `update` clause
 template <typename T, typename I, typename E> //
 struct UpdateT {
+  using EmptyTrait = std::true_type;
+};
+
+template <typename T, typename I, typename E> //
+struct UpdateDependObjectsT {
   using DependenceType = tomp::type::DependenceType;
   using WrapperTrait = std::true_type;
-  OPT(DependenceType) v;
+  DependenceType v;
 };
 
 // V5.2: [14.1.3] `use` clause
@@ -1399,7 +1404,8 @@ using EmptyClausesT = std::variant<
     NoOpenmpT<T, I, E>, NoParallelismT<T, I, E>, NotinbranchT<T, I, E>,
     NowaitT<T, I, E>, ReadT<T, I, E>, RelaxedT<T, I, E>, ReleaseT<T, I, E>,
     SeqCstT<T, I, E>, SimdT<T, I, E>, ThreadsT<T, I, E>, UnknownT<T, I, E>,
-    UntiedT<T, I, E>, UseT<T, I, E>, WeakT<T, I, E>, WriteT<T, I, E>>;
+    UntiedT<T, I, E>, UpdateT<T, I, E>, UseT<T, I, E>, WeakT<T, I, E>,
+    WriteT<T, I, E>>;
 
 template <typename T, typename I, typename E>
 using IncompleteClausesT =
@@ -1444,8 +1450,9 @@ using WrapperClausesT = std::variant<
     SelfMapsT<T, I, E>, SeverityT<T, I, E>, SharedT<T, I, E>, SimdlenT<T, I, 
E>,
     SizesT<T, I, E>, PermutationT<T, I, E>, ThreadLimitT<T, I, E>,
     ThreadsetT<T, I, E>, UnifiedAddressT<T, I, E>,
-    UnifiedSharedMemoryT<T, I, E>, UniformT<T, I, E>, UpdateT<T, I, E>,
-    UseDeviceAddrT<T, I, E>, UseDevicePtrT<T, I, E>, UsesAllocatorsT<T, I, E>>;
+    UnifiedSharedMemoryT<T, I, E>, UniformT<T, I, E>,
+    UpdateDependObjectsT<T, I, E>, UseDeviceAddrT<T, I, E>,
+    UseDevicePtrT<T, I, E>, UsesAllocatorsT<T, I, E>>;
 
 template <typename T, typename I, typename E>
 using UnionOfAllClausesT = typename type::Union< //
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td 
b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index dc2af1e62cfa4..a119dff67c30e 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -618,9 +618,14 @@ def OMPC_Untied : Clause<[Spelling<"untied">]> {
   let clangClass = "OMPUntiedClause";
 }
 def OMPC_Update : Clause<[Spelling<"update">]> {
+  // This is the "update" clause for "atomic" construct.
+  // For "depobj" use OMPC_UpdateDependObjects.
   let clangClass = "OMPUpdateClause";
-  let flangClass = "OmpUpdateClause";
-  let isValueOptional = true;
+}
+def OMPC_UpdateDependObjects : Clause<[Spelling<"update">]> {
+  let name = "update_depend_objects";
+  let clangClass = "OMPUpdateDependObjectsClause";
+  let flangClass = "OmpUpdateDependObjectsClause";
 }
 def OMPC_Use : Clause<[Spelling<"use">]> {
   let clangClass = "OMPUseClause";
@@ -873,7 +878,7 @@ def OMP_Depobj : Directive<[Spelling<"depobj">]> {
     VersionedClause<OMPC_Init, 60>,
   ];
   let allowedOnceClauses = [
-    VersionedClause<OMPC_Update, 50>,
+    VersionedClause<OMPC_UpdateDependObjects, 50>,
   ];
   let association = AS_None;
   let category = CA_Executable;

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to