[llvm-branch-commits] [clang] [llvm] [clang][OpenMP] Use different ids for block and s/a ORDERED directive (PR #214728)

Krzysztof Parzyszek via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Aug 7 07:02:56 PDT 2026


https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/214728

>From e554990a40dd05cf2174c7cd7b34b5aaabeb7a81 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Thu, 6 Aug 2026 13:29:52 -0500
Subject: [PATCH 1/2] [clang][OpenMP] Use different ids for block and s/a
 ORDERED directive

Use OMPD_ordered_blockassoc for the block-associated ORDERED directive,
and OMPD_ordered_standalone for the standalone variant.

This still uses a single AST class for both though. The directive
kind stored in can now take either of the two values.
---
 clang/include/clang/AST/StmtOpenMP.h          | 10 +++-
 clang/lib/AST/StmtOpenMP.cpp                  | 12 +++-
 clang/lib/Basic/OpenMPKinds.cpp               |  2 +-
 clang/lib/CodeGen/CGOpenMPRuntime.cpp         | 16 +++--
 clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp      |  6 +-
 clang/lib/CodeGen/CGStmtOpenMP.cpp            |  3 +-
 clang/lib/Parse/ParseOpenMP.cpp               | 59 +++++++++++--------
 clang/lib/Sema/SemaOpenMP.cpp                 | 53 ++++++++++-------
 clang/lib/Sema/TreeTransform.h                |  2 +-
 .../Frontend/OpenMP/DirectiveNameParser.cpp   |  6 +-
 10 files changed, 107 insertions(+), 62 deletions(-)

diff --git a/clang/include/clang/AST/StmtOpenMP.h b/clang/include/clang/AST/StmtOpenMP.h
index dbc76e7df8ecd..2d0cfb1580aeb 100644
--- a/clang/include/clang/AST/StmtOpenMP.h
+++ b/clang/include/clang/AST/StmtOpenMP.h
@@ -554,6 +554,9 @@ class OMPExecutableDirective : public Stmt {
   }
 
   OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
+  void setDirectiveKind(OpenMPDirectiveKind D) const {
+    const_cast<OMPExecutableDirective *>(this)->Kind = D;
+  }
 
   static bool classof(const Stmt *S) {
     return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
@@ -2947,14 +2950,15 @@ class OMPOrderedDirective : public OMPExecutableDirective {
   ///
   OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
       : OMPExecutableDirective(OMPOrderedDirectiveClass,
-                               llvm::omp::OMPD_ordered, StartLoc, EndLoc) {}
+                               llvm::omp::OMPD_ordered_standalone, StartLoc,
+                               EndLoc) {}
 
   /// Build an empty directive.
   ///
   explicit OMPOrderedDirective()
       : OMPExecutableDirective(OMPOrderedDirectiveClass,
-                               llvm::omp::OMPD_ordered, SourceLocation(),
-                               SourceLocation()) {}
+                               llvm::omp::OMPD_ordered_standalone,
+                               SourceLocation(), SourceLocation()) {}
 
 public:
   /// Creates directive.
diff --git a/clang/lib/AST/StmtOpenMP.cpp b/clang/lib/AST/StmtOpenMP.cpp
index 9d6b315effb41..e4144cb544a9d 100644
--- a/clang/lib/AST/StmtOpenMP.cpp
+++ b/clang/lib/AST/StmtOpenMP.cpp
@@ -1062,17 +1062,23 @@ OMPOrderedDirective *OMPOrderedDirective::Create(const ASTContext &C,
                                                  SourceLocation EndLoc,
                                                  ArrayRef<OMPClause *> Clauses,
                                                  Stmt *AssociatedStmt) {
-  return createDirective<OMPOrderedDirective>(
+  auto *D = createDirective<OMPOrderedDirective>(
       C, Clauses, cast_or_null<CapturedStmt>(AssociatedStmt),
       /*NumChildren=*/0, StartLoc, EndLoc);
+  if (AssociatedStmt)
+    D->setDirectiveKind(OMPD_ordered_blockassoc);
+  return D;
 }
 
 OMPOrderedDirective *OMPOrderedDirective::CreateEmpty(const ASTContext &C,
                                                       unsigned NumClauses,
                                                       bool IsStandalone,
                                                       EmptyShell) {
-  return createEmptyDirective<OMPOrderedDirective>(C, NumClauses,
-                                                   !IsStandalone);
+  auto *D =
+      createEmptyDirective<OMPOrderedDirective>(C, NumClauses, !IsStandalone);
+  if (!IsStandalone)
+    D->setDirectiveKind(OMPD_ordered_blockassoc);
+  return D;
 }
 
 OMPAtomicDirective *
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 1a2a963243f6c..8292a21286e7a 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -995,7 +995,7 @@ void clang::getOpenMPCaptureRegions(
     case OMPD_dispatch:
     case OMPD_distribute:
     case OMPD_for:
-    case OMPD_ordered:
+    case OMPD_ordered_blockassoc:
     case OMPD_scope:
     case OMPD_sections:
     case OMPD_simd:
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 51f1e8b22fcfc..409c222da87fc 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -2429,10 +2429,10 @@ void CGOpenMPRuntime::emitOrderedRegion(CodeGenFunction &CGF,
                               CGM.getModule(), OMPRTL___kmpc_end_ordered),
                           Args);
     OrderedOpGen.setAction(Action);
-    emitInlinedDirective(CGF, OMPD_ordered, OrderedOpGen);
+    emitInlinedDirective(CGF, OMPD_ordered_blockassoc, OrderedOpGen);
     return;
   }
-  emitInlinedDirective(CGF, OMPD_ordered, OrderedOpGen);
+  emitInlinedDirective(CGF, OMPD_ordered_blockassoc, OrderedOpGen);
 }
 
 unsigned CGOpenMPRuntime::getDefaultFlagsForBarriers(OpenMPDirectiveKind Kind) {
@@ -6545,7 +6545,8 @@ const Expr *CGOpenMPRuntime::getNumTeamsExprForTargetDirective(
   case OMPD_parallel_for_simd:
   case OMPD_cancel:
   case OMPD_cancellation_point:
-  case OMPD_ordered:
+  case OMPD_ordered_standalone:
+  case OMPD_ordered_blockassoc:
   case OMPD_threadprivate:
   case OMPD_allocate:
   case OMPD_task:
@@ -10509,7 +10510,8 @@ getNestedDistributeDirective(ASTContext &Ctx, const OMPExecutableDirective &D) {
     case OMPD_parallel_for_simd:
     case OMPD_cancel:
     case OMPD_cancellation_point:
-    case OMPD_ordered:
+    case OMPD_ordered_standalone:
+    case OMPD_ordered_blockassoc:
     case OMPD_threadprivate:
     case OMPD_allocate:
     case OMPD_task:
@@ -11274,7 +11276,8 @@ void CGOpenMPRuntime::scanForTargetRegionsFunctions(const Stmt *S,
     case OMPD_parallel_for_simd:
     case OMPD_cancel:
     case OMPD_cancellation_point:
-    case OMPD_ordered:
+    case OMPD_ordered_standalone:
+    case OMPD_ordered_blockassoc:
     case OMPD_threadprivate:
     case OMPD_allocate:
     case OMPD_task:
@@ -11849,7 +11852,8 @@ void CGOpenMPRuntime::emitTargetDataStandAloneCall(
     case OMPD_parallel_for_simd:
     case OMPD_cancel:
     case OMPD_cancellation_point:
-    case OMPD_ordered:
+    case OMPD_ordered_standalone:
+    case OMPD_ordered_blockassoc:
     case OMPD_threadprivate:
     case OMPD_allocate:
     case OMPD_task:
diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
index 8f9000660d86b..20ce5fe268880 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
@@ -562,7 +562,8 @@ static bool hasNestedSPMDDirective(ASTContext &Ctx,
     case OMPD_parallel_for_simd:
     case OMPD_cancel:
     case OMPD_cancellation_point:
-    case OMPD_ordered:
+    case OMPD_ordered_standalone:
+    case OMPD_ordered_blockassoc:
     case OMPD_threadprivate:
     case OMPD_allocate:
     case OMPD_task:
@@ -650,7 +651,8 @@ static bool supportsSPMDExecutionMode(ASTContext &Ctx,
   case OMPD_parallel_for_simd:
   case OMPD_cancel:
   case OMPD_cancellation_point:
-  case OMPD_ordered:
+  case OMPD_ordered_standalone:
+  case OMPD_ordered_blockassoc:
   case OMPD_threadprivate:
   case OMPD_allocate:
   case OMPD_task:
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 97c43b4c0b384..c7c13af972255 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -1703,7 +1703,8 @@ void CodeGenFunction::EmitOMPReductionClauseInit(
     case OMPD_flush:
     case OMPD_depobj:
     case OMPD_scan:
-    case OMPD_ordered:
+    case OMPD_ordered_standalone:
+    case OMPD_ordered_blockassoc:
     case OMPD_atomic:
     case OMPD_teams:
     case OMPD_target:
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index a6c639bf0b3aa..616bd87124210 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -63,13 +63,9 @@ static OpenMPDirectiveKind checkOpenMPDirectiveName(Parser &P,
                                                     StringRef Name) {
   unsigned Version = P.getLangOpts().OpenMP;
   auto [D, VR] = getOpenMPDirectiveKindAndVersions(Name);
-  // There are multiple kinds corresponding to "ordered", and it's
-  // unspecified which one we get, so normalize it to OMPD_ordered.
-  if (D == Directive::OMPD_ordered_blockassoc ||
-      D == Directive::OMPD_ordered_standalone)
-    D = OMPD_ordered;
-  if (Kind == Directive::OMPD_ordered_standalone)
-    Kind = OMPD_ordered;
+  // "ORDERED" is parsed as OMPD_ordered_standalone.
+  if (D == Directive::OMPD_ordered || D == Directive::OMPD_ordered_blockassoc)
+    D = Directive::OMPD_ordered_standalone;
   assert(D == Kind && "Directive kind mismatch");
   // Ignore the case Version > VR.Max: In OpenMP 6.0 all prior spellings
   // are explicitly allowed.
@@ -2301,11 +2297,9 @@ StmtResult Parser::ParseOpenMPExecutableDirective(
   bool HasAssociatedStatement = true;
   Association Assoc = getDirectiveAssociation(DKind);
 
-  // OMPD_ordered has None as association, but it comes in two variants,
-  // the second of which is associated with a block.
   // OMPD_scan and OMPD_section are both "separating", but section is treated
   // as if it was associated with a statement, while scan is not.
-  if (DKind != OMPD_ordered && DKind != OMPD_section &&
+  if (DKind != OMPD_ordered_standalone && DKind != OMPD_section &&
       (Assoc == Association::None || Assoc == Association::Separating)) {
     if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
         ParsedStmtContext()) {
@@ -2424,7 +2418,9 @@ StmtResult Parser::ParseOpenMPExecutableDirective(
   // Consume final annot_pragma_openmp_end.
   ConsumeAnnotationToken();
 
-  if (DKind == OMPD_ordered) {
+  assert(DKind != OMPD_ordered_blockassoc &&
+         "Wrong kind for ordered directive");
+  if (DKind == OMPD_ordered_standalone) {
     // If the depend or doacross clause is specified, the ordered construct
     // is a stand-alone directive.
     for (auto CK : {OMPC_depend, OMPC_doacross}) {
@@ -2438,6 +2434,9 @@ StmtResult Parser::ParseOpenMPExecutableDirective(
         HasAssociatedStatement = false;
       }
     }
+
+    if (HasAssociatedStatement)
+      DKind = OMPD_ordered_blockassoc;
   }
 
   if ((DKind == OMPD_tile || DKind == OMPD_stripe) &&
@@ -3231,14 +3230,27 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
   bool WrongDirective = false;
   unsigned OMPVersion = Actions.getLangOpts().OpenMP;
 
-  // Check if clause is allowed for the given directive.
-  if (CKind != OMPC_unknown &&
-      !isAllowedClauseForDirective(DKind, CKind, getLangOpts().OpenMP)) {
-    Diag(Tok, diag::err_omp_unexpected_clause)
-        << getOpenMPClauseName(CKind)
-        << getOpenMPDirectiveName(DKind, OMPVersion);
-    ErrorFound = true;
-    WrongDirective = true;
+  auto checkClauseValid = [&](OpenMPDirectiveKind D, OpenMPClauseKind C) {
+    if (!isAllowedClauseForDirective(D, C, OMPVersion)) {
+      Diag(Tok, diag::err_omp_unexpected_clause)
+          << getOpenMPClauseName(C) << getOpenMPDirectiveName(D, OMPVersion);
+      ErrorFound = true;
+      WrongDirective = true;
+    }
+  };
+
+  if (CKind != OMPC_unknown) {
+    // Check if clause is allowed for the given directive.
+    assert(DKind != OMPD_ordered_blockassoc &&
+           "Wrong kind for ordered directive");
+    if (DKind == OMPD_ordered_standalone) {
+      // Initially OMPD_ordered_standalone is used for ORDERED, before the
+      // actual kind can be determined.
+      if (!isAllowedClauseForDirective(DKind, CKind, OMPVersion))
+        checkClauseValid(OMPD_ordered_blockassoc, CKind);
+    } else {
+      checkClauseValid(DKind, CKind);
+    }
   }
 
   switch (CKind) {
@@ -3482,7 +3494,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
   case OMPC_affinity:
   case OMPC_doacross:
   case OMPC_enter:
-    if (getLangOpts().OpenMP >= 52 && DKind == OMPD_ordered &&
+    if (getLangOpts().OpenMP >= 52 && DKind == OMPD_ordered_standalone &&
         CKind == OMPC_depend)
       Diag(Tok, diag::warn_omp_depend_in_ordered_deprecated);
     Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
@@ -5008,7 +5020,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
     } else {
       ConsumeToken();
       // Special processing for depend(source) clause.
-      if (DKind == OMPD_ordered && Kind == OMPC_depend &&
+      if (DKind == OMPD_ordered_standalone && Kind == OMPC_depend &&
           Data.ExtraModifier == OMPC_DEPEND_source) {
         // Parse ')'.
         T.consumeClose();
@@ -5018,8 +5030,9 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
     if (Tok.is(tok::colon)) {
       Data.ColonLoc = ConsumeToken();
     } else if (Kind != OMPC_doacross || Tok.isNot(tok::r_paren)) {
-      Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
-                                      : diag::warn_pragma_expected_colon)
+      Diag(Tok, DKind == OMPD_ordered_standalone
+                    ? diag::warn_pragma_expected_colon_r_paren
+                    : diag::warn_pragma_expected_colon)
           << (Kind == OMPC_depend ? "dependency type" : "dependence-type");
     }
     if (Kind == OMPC_doacross) {
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 76bb0d38d428f..9c7be1e46298e 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -1256,6 +1256,10 @@ class DSAStackTy {
     }
     assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
   }
+  void setOrderedToBlockAssociated() {
+    assert(getCurrentDirective() == OMPD_ordered_standalone);
+    getTopOfStack().Directive = OMPD_ordered_blockassoc;
+  }
 };
 
 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
@@ -4617,6 +4621,10 @@ static void processCapturedRegions(Sema &SemaRef, OpenMPDirectiveKind DKind,
 
 void SemaOpenMP::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind,
                                         Scope *CurScope) {
+  if (DKind == OMPD_ordered_blockassoc &&
+      DSAStack->getCurrentDirective() == OMPD_ordered_standalone) {
+    DSAStack->setOrderedToBlockAssociated();
+  }
   switch (DKind) {
   case OMPD_atomic:
   case OMPD_critical:
@@ -5040,8 +5048,8 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
     return true;
   }
   if (isOpenMPSimdDirective(ParentRegion) &&
-      ((OMPVersion <= 45 && CurrentRegion != OMPD_ordered) ||
-       (OMPVersion >= 50 && CurrentRegion != OMPD_ordered &&
+      ((OMPVersion <= 45 && CurrentRegion != OMPD_ordered_blockassoc) ||
+       (OMPVersion >= 50 && CurrentRegion != OMPD_ordered_blockassoc &&
         CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
         CurrentRegion != OMPD_scan))) {
     // OpenMP [2.16, Nesting of Regions]
@@ -5165,12 +5173,13 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
     // OpenMP 5.1 [2.22, Nesting of Regions]
     // A barrier region may not be closely nested inside a worksharing, loop,
     // task, taskloop, critical, ordered, atomic, or masked region.
-    NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
-                        isOpenMPGenericLoopDirective(ParentRegion) ||
-                        isOpenMPTaskingDirective(ParentRegion) ||
-                        llvm::is_contained({OMPD_masked, OMPD_master,
-                                            OMPD_critical, OMPD_ordered},
-                                           EnclosingConstruct);
+    NestingProhibited =
+        isOpenMPWorksharingDirective(ParentRegion) ||
+        isOpenMPGenericLoopDirective(ParentRegion) ||
+        isOpenMPTaskingDirective(ParentRegion) ||
+        llvm::is_contained(
+            {OMPD_masked, OMPD_master, OMPD_critical, OMPD_ordered_blockassoc},
+            EnclosingConstruct);
   } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
              !isOpenMPParallelDirective(CurrentRegion) &&
              !isOpenMPTeamsDirective(CurrentRegion)) {
@@ -5178,14 +5187,16 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
     // A loop region that binds to a parallel region or a worksharing region
     // may not be closely nested inside a worksharing, loop, task, taskloop,
     // critical, ordered, atomic, or masked region.
-    NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
-                        isOpenMPGenericLoopDirective(ParentRegion) ||
-                        isOpenMPTaskingDirective(ParentRegion) ||
-                        llvm::is_contained({OMPD_masked, OMPD_master,
-                                            OMPD_critical, OMPD_ordered},
-                                           EnclosingConstruct);
+    NestingProhibited =
+        isOpenMPWorksharingDirective(ParentRegion) ||
+        isOpenMPGenericLoopDirective(ParentRegion) ||
+        isOpenMPTaskingDirective(ParentRegion) ||
+        llvm::is_contained(
+            {OMPD_masked, OMPD_master, OMPD_critical, OMPD_ordered_blockassoc},
+            EnclosingConstruct);
     Recommend = ShouldBeInParallelRegion;
-  } else if (CurrentRegion == OMPD_ordered) {
+  } else if (CurrentRegion == OMPD_ordered_blockassoc ||
+             CurrentRegion == OMPD_ordered_standalone) {
     // OpenMP [2.16, Nesting of Regions]
     // An ordered region may not be closely nested inside a critical,
     // atomic, or explicit task region.
@@ -6584,7 +6595,8 @@ StmtResult SemaOpenMP::ActOnOpenMPExecutableDirective(
            "No associated statement allowed for 'omp scan' directive");
     Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
     break;
-  case OMPD_ordered:
+  case OMPD_ordered_blockassoc:
+  case OMPD_ordered_standalone:
     Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
                                       EndLoc);
     break;
@@ -11744,7 +11756,8 @@ SemaOpenMP::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
         if ((DC && DependSourceClause) || (DOC && DoacrossSourceClause)) {
           unsigned OMPVersion = getLangOpts().OpenMP;
           Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
-              << getOpenMPDirectiveName(OMPD_ordered, OMPVersion)
+              << getOpenMPDirectiveName(DSAStack->getCurrentDirective(),
+                                        OMPVersion)
               << getOpenMPClauseNameForDiag(DC ? OMPC_depend : OMPC_doacross)
               << 2;
           ErrorFound = true;
@@ -22297,7 +22310,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPDependClause(
     SourceLocation EndLoc) {
   OpenMPDependClauseKind DepKind = Data.DepKind;
   SourceLocation DepLoc = Data.DepLoc;
-  if (DSAStack->getCurrentDirective() == OMPD_ordered &&
+  if (DSAStack->getCurrentDirective() == OMPD_ordered_standalone &&
       DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
         << "'source' or 'sink'" << getOpenMPClauseNameForDiag(OMPC_depend);
@@ -22308,7 +22321,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPDependClause(
     Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed);
     return nullptr;
   }
-  if ((DSAStack->getCurrentDirective() != OMPD_ordered ||
+  if ((DSAStack->getCurrentDirective() != OMPD_ordered_standalone ||
        DSAStack->getCurrentDirective() == OMPD_depobj) &&
       (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
        DepKind == OMPC_DEPEND_sink ||
@@ -26292,7 +26305,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPDoacrossClause(
     SourceLocation ColonLoc, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
     SourceLocation LParenLoc, SourceLocation EndLoc) {
 
-  if (DSAStack->getCurrentDirective() == OMPD_ordered &&
+  if (DSAStack->getCurrentDirective() == OMPD_ordered_standalone &&
       DepType != OMPC_DOACROSS_source && DepType != OMPC_DOACROSS_sink &&
       DepType != OMPC_DOACROSS_sink_omp_cur_iteration &&
       DepType != OMPC_DOACROSS_source_omp_cur_iteration) {
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 2083fcd372e81..db2d24fdbfcce 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -10284,7 +10284,7 @@ StmtResult
 TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
   DeclarationNameInfo DirName;
   getDerived().getSema().OpenMP().StartOpenMPDSABlock(
-      OMPD_ordered, DirName, nullptr, D->getBeginLoc());
+      D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
   StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
   getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
   return Res;
diff --git a/llvm/lib/Frontend/OpenMP/DirectiveNameParser.cpp b/llvm/lib/Frontend/OpenMP/DirectiveNameParser.cpp
index 62e24825111f6..3f743e27ea37f 100644
--- a/llvm/lib/Frontend/OpenMP/DirectiveNameParser.cpp
+++ b/llvm/lib/Frontend/OpenMP/DirectiveNameParser.cpp
@@ -19,10 +19,12 @@ namespace llvm::omp {
 DirectiveNameParser::DirectiveNameParser(SourceLanguage L) {
   // Take every directive, get its name in every version, break the name up
   // into whitespace-separated tokens, and insert each token.
-  for (size_t I : llvm::seq<size_t>(Directive_enumSize)) {
-    auto D = static_cast<Directive>(I);
+  for (Directive D : directives()) {
     if (D == Directive::OMPD_unknown || !(getDirectiveLanguages(D) & L))
       continue;
+    // Parse "ORDERED" as OMPD_ordered_standalone.
+    if (D == OMPD_ordered_blockassoc)
+      continue;
     for (unsigned Ver : getOpenMPVersions())
       insertName(getOpenMPDirectiveName(D, Ver), D);
   }

>From eb7cf575bf5badf622b1a81f25f3c734e70ac7af Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Fri, 7 Aug 2026 08:58:46 -0500
Subject: [PATCH 2/2] Add comment

---
 clang/include/clang/AST/StmtOpenMP.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/clang/include/clang/AST/StmtOpenMP.h b/clang/include/clang/AST/StmtOpenMP.h
index 2d0cfb1580aeb..dedf90b248bc7 100644
--- a/clang/include/clang/AST/StmtOpenMP.h
+++ b/clang/include/clang/AST/StmtOpenMP.h
@@ -554,6 +554,8 @@ class OMPExecutableDirective : public Stmt {
   }
 
   OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
+  /// Horrible temporary hack to allow OMPOrderedDirective to be used
+  /// with both OMPD_ordered_standalone and OMPD_ordered_blockassoc.
   void setDirectiveKind(OpenMPDirectiveKind D) const {
     const_cast<OMPExecutableDirective *>(this)->Kind = D;
   }



More information about the llvm-branch-commits mailing list