[flang-commits] [flang] 2ddba30 - [flang][openmp] Use common Directive and Clause enum from llvm/Frontend

via flang-commits flang-commits at lists.llvm.org
Wed Jul 1 17:58:24 PDT 2020


Author: Valentin Clement
Date: 2020-07-01T20:58:11-04:00
New Revision: 2ddba3082ca79080b14f372ebe4b5bdbc5f694ed

URL: https://github.com/llvm/llvm-project/commit/2ddba3082ca79080b14f372ebe4b5bdbc5f694ed
DIFF: https://github.com/llvm/llvm-project/commit/2ddba3082ca79080b14f372ebe4b5bdbc5f694ed.diff

LOG: [flang][openmp] Use common Directive and Clause enum from llvm/Frontend

Summary:
This patch is removing the custom enumeration for OpenMP Directives and Clauses and replace them
with the newly tablegen generated one from llvm/Frontend. This is a first patch and some will follow to share the same
infrastructure where possible. The next patch should use the clauses allowance defined in the tablegen file.

Reviewers: jdoerfert, DavidTruby, sscalpone, kiranchandramohan, ichoyjx

Reviewed By: DavidTruby, ichoyjx

Subscribers: jholewinski, cfe-commits, dblaikie, MaskRay, ymandel, ichoyjx, mgorny, yaxunl, guansong, jfb, sstefan1, aaron.ballman, llvm-commits

Tags: #llvm, #flang, #clang

Differential Revision: https://reviews.llvm.org/D82906

Added: 
    

Modified: 
    clang/include/clang/AST/OpenMPClause.h
    clang/include/clang/AST/RecursiveASTVisitor.h
    clang/lib/AST/ASTTypeTraits.cpp
    clang/lib/AST/OpenMPClause.cpp
    clang/lib/Basic/OpenMPKinds.cpp
    clang/lib/CodeGen/CGOpenMPRuntime.cpp
    clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
    clang/lib/CodeGen/CGStmtOpenMP.cpp
    clang/lib/Parse/ParseOpenMP.cpp
    clang/lib/Sema/SemaOpenMP.cpp
    clang/lib/Serialization/ASTReader.cpp
    flang/include/flang/Common/enum-set.h
    flang/include/flang/Parser/dump-parse-tree.h
    flang/include/flang/Parser/parse-tree.h
    flang/lib/Evaluate/CMakeLists.txt
    flang/lib/Parser/CMakeLists.txt
    flang/lib/Parser/openmp-parsers.cpp
    flang/lib/Parser/unparse.cpp
    flang/lib/Semantics/CMakeLists.txt
    flang/lib/Semantics/check-omp-structure.cpp
    flang/lib/Semantics/check-omp-structure.h
    flang/lib/Semantics/resolve-names.cpp
    flang/tools/f18-parse-demo/CMakeLists.txt
    llvm/include/llvm/Frontend/OpenMP/OMP.td

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h
index 6c2ca1cb1008..6de7b6deb514 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -7556,6 +7556,8 @@ class OMPClauseVisitorBase {
   case llvm::omp::Clause::Enum:                                                \
     break;
 #include "llvm/Frontend/OpenMP/OMPKinds.def"
+    default:
+      break;
     }
   }
   // Base case, ignore it. :)

diff  --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 3c2f561abcbf..b16c1ae1e483 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -3000,6 +3000,8 @@ bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
   case llvm::omp::Clause::Enum:                                                \
     break;
 #include "llvm/Frontend/OpenMP/OMPKinds.def"
+  default:
+    break;
   }
   return true;
 }

diff  --git a/clang/lib/AST/ASTTypeTraits.cpp b/clang/lib/AST/ASTTypeTraits.cpp
index 37e81e5813ec..ccfc11565885 100644
--- a/clang/lib/AST/ASTTypeTraits.cpp
+++ b/clang/lib/AST/ASTTypeTraits.cpp
@@ -118,6 +118,8 @@ ASTNodeKind ASTNodeKind::getFromNode(const OMPClause &C) {
 #define OMP_CLAUSE_NO_CLASS(Enum, Str)                                         \
   case llvm::omp::Clause::Enum:                                                \
     llvm_unreachable("unexpected OpenMP clause kind");
+  default:
+    break;
 #include "llvm/Frontend/OpenMP/OMPKinds.def"
   }
   llvm_unreachable("invalid stmt kind");

diff  --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index 6a8b3ce231f2..a0b0dca55390 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -51,6 +51,8 @@ OMPClause::child_range OMPClause::used_children() {
   case OMPC_match:
   case OMPC_unknown:
     break;
+  default:
+    break;
   }
   llvm_unreachable("unknown OMPClause");
 }
@@ -154,6 +156,8 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
   case OMPC_uses_allocators:
   case OMPC_affinity:
     break;
+  default:
+    break;
   }
 
   return nullptr;
@@ -246,6 +250,8 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
   case OMPC_uses_allocators:
   case OMPC_affinity:
     break;
+  default:
+    break;
   }
 
   return nullptr;

diff  --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 87d2c4b5a056..cae61ad4f2e3 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -178,6 +178,8 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
   case OMPC_uses_allocators:
   case OMPC_affinity:
     break;
+  default:
+    break;
   }
   llvm_unreachable("Invalid OpenMP simple clause kind");
 }
@@ -427,6 +429,8 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
   case OMPC_uses_allocators:
   case OMPC_affinity:
     break;
+  default:
+    break;
   }
   llvm_unreachable("Invalid OpenMP simple clause kind");
 }
@@ -681,6 +685,7 @@ void clang::getOpenMPCaptureRegions(
   case OMPD_end_declare_variant:
     llvm_unreachable("OpenMP Directive is not allowed");
   case OMPD_unknown:
+  default:
     llvm_unreachable("Unknown OpenMP directive");
   }
 }

diff  --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 1ff62fd5894a..858dbbf81f20 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -6680,6 +6680,8 @@ emitNumTeamsForTargetDirective(CodeGenFunction &CGF,
   case OMPD_requires:
   case OMPD_unknown:
     break;
+  default:
+    break;
   }
   llvm_unreachable("Unexpected directive kind.");
 }
@@ -6995,6 +6997,8 @@ emitNumThreadsForTargetDirective(CodeGenFunction &CGF,
   case OMPD_requires:
   case OMPD_unknown:
     break;
+  default:
+    break;
   }
   llvm_unreachable("Unsupported directive kind.");
 }
@@ -8914,6 +8918,7 @@ getNestedDistributeDirective(ASTContext &Ctx, const OMPExecutableDirective &D) {
     case OMPD_parallel_master_taskloop_simd:
     case OMPD_requires:
     case OMPD_unknown:
+    default:
       llvm_unreachable("Unexpected directive.");
     }
   }
@@ -9704,6 +9709,7 @@ void CGOpenMPRuntime::scanForTargetRegionsFunctions(const Stmt *S,
     case OMPD_parallel_master_taskloop_simd:
     case OMPD_requires:
     case OMPD_unknown:
+    default:
       llvm_unreachable("Unknown target directive for OpenMP device codegen.");
     }
     return;
@@ -10362,6 +10368,7 @@ void CGOpenMPRuntime::emitTargetDataStandAloneCall(
     case OMPD_target_parallel_for_simd:
     case OMPD_requires:
     case OMPD_unknown:
+    default:
       llvm_unreachable("Unexpected standalone target data directive.");
       break;
     }

diff  --git a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
index 744342f606a2..cabd06bd76e8 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
@@ -819,6 +819,7 @@ static bool hasNestedSPMDDirective(ASTContext &Ctx,
     case OMPD_parallel_master_taskloop_simd:
     case OMPD_requires:
     case OMPD_unknown:
+    default:
       llvm_unreachable("Unexpected directive.");
     }
   }
@@ -899,6 +900,7 @@ static bool supportsSPMDExecutionMode(ASTContext &Ctx,
   case OMPD_parallel_master_taskloop_simd:
   case OMPD_requires:
   case OMPD_unknown:
+  default:
     break;
   }
   llvm_unreachable(
@@ -1072,6 +1074,7 @@ static bool hasNestedLightweightDirective(ASTContext &Ctx,
     case OMPD_parallel_master_taskloop_simd:
     case OMPD_requires:
     case OMPD_unknown:
+    default:
       llvm_unreachable("Unexpected directive.");
     }
   }
@@ -1158,6 +1161,7 @@ static bool supportsLightweightRuntime(ASTContext &Ctx,
   case OMPD_parallel_master_taskloop_simd:
   case OMPD_requires:
   case OMPD_unknown:
+  default:
     break;
   }
   llvm_unreachable(

diff  --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 2639b9d9bf99..4141acfcd1fb 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -1377,6 +1377,7 @@ void CodeGenFunction::EmitOMPReductionClauseInit(
     case OMPD_begin_declare_variant:
     case OMPD_end_declare_variant:
     case OMPD_unknown:
+    default:
       llvm_unreachable("Enexpected directive with task reductions.");
     }
 
@@ -5302,6 +5303,7 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
   case OMPC_exclusive:
   case OMPC_uses_allocators:
   case OMPC_affinity:
+  default:
     llvm_unreachable("Clause is not allowed in 'omp atomic'.");
   }
 }

diff  --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 9fa57d8c9791..dc1283070c43 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -2009,6 +2009,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
     Diag(Tok, diag::err_omp_unexpected_directive)
         << 1 << getOpenMPDirectiveName(DKind);
     break;
+  default:
+    break;
   }
   while (Tok.isNot(tok::annot_pragma_openmp_end))
     ConsumeAnyToken();
@@ -2358,6 +2360,7 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
     SkipUntil(tok::annot_pragma_openmp_end);
     break;
   case OMPD_unknown:
+  default:
     Diag(Tok, diag::err_omp_unknown_directive);
     SkipUntil(tok::annot_pragma_openmp_end);
     break;
@@ -2681,6 +2684,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
           << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
     SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
     break;
+  default:
+    break;
   }
   return ErrorFound ? nullptr : Clause;
 }

diff  --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index e221a4d9ea57..3aa74c87a1b0 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -4050,6 +4050,7 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
   case OMPD_end_declare_variant:
     llvm_unreachable("OpenMP Directive is not allowed");
   case OMPD_unknown:
+  default:
     llvm_unreachable("Unknown OpenMP directive");
   }
 }
@@ -5335,6 +5336,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
   case OMPD_end_declare_variant:
     llvm_unreachable("OpenMP Directive is not allowed");
   case OMPD_unknown:
+  default:
     llvm_unreachable("Unknown OpenMP directive");
   }
 
@@ -5437,6 +5439,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
       case OMPC_atomic_default_mem_order:
       case OMPC_device_type:
       case OMPC_match:
+      default:
         llvm_unreachable("Unexpected clause");
       }
       for (Stmt *CC : C->children()) {
@@ -11683,6 +11686,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
   case OMPC_exclusive:
   case OMPC_uses_allocators:
   case OMPC_affinity:
+  default:
     llvm_unreachable("Clause is not allowed.");
   }
   return Res;
@@ -11837,6 +11841,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
     case OMPD_requires:
       llvm_unreachable("Unexpected OpenMP directive with if-clause");
     case OMPD_unknown:
+    default:
       llvm_unreachable("Unknown OpenMP directive");
     }
     break;
@@ -11915,6 +11920,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
     case OMPD_requires:
       llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
     case OMPD_unknown:
+    default:
       llvm_unreachable("Unknown OpenMP directive");
     }
     break;
@@ -11991,6 +11997,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
     case OMPD_requires:
       llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
     case OMPD_unknown:
+    default:
       llvm_unreachable("Unknown OpenMP directive");
     }
     break;
@@ -12067,6 +12074,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
     case OMPD_requires:
       llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
     case OMPD_unknown:
+    default:
       llvm_unreachable("Unknown OpenMP directive");
     }
     break;
@@ -12143,6 +12151,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
     case OMPD_requires:
       llvm_unreachable("Unexpected OpenMP directive with schedule clause");
     case OMPD_unknown:
+    default:
       llvm_unreachable("Unknown OpenMP directive");
     }
     break;
@@ -12219,6 +12228,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
     case OMPD_requires:
       llvm_unreachable("Unexpected OpenMP directive with schedule clause");
     case OMPD_unknown:
+    default:
       llvm_unreachable("Unknown OpenMP directive");
     }
     break;
@@ -12295,6 +12305,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
     case OMPD_requires:
       llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
     case OMPD_unknown:
+    default:
       llvm_unreachable("Unknown OpenMP directive");
     }
     break;
@@ -12373,6 +12384,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
     case OMPD_requires:
       llvm_unreachable("Unexpected OpenMP directive with grainsize-clause");
     case OMPD_unknown:
+    default:
       llvm_unreachable("Unknown OpenMP directive");
     }
     break;
@@ -12439,6 +12451,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
   case OMPC_exclusive:
   case OMPC_uses_allocators:
   case OMPC_affinity:
+  default:
     llvm_unreachable("Unexpected OpenMP clause.");
   }
   return CaptureRegion;
@@ -12880,6 +12893,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
   case OMPC_exclusive:
   case OMPC_uses_allocators:
   case OMPC_affinity:
+  default:
     llvm_unreachable("Clause is not allowed.");
   }
   return Res;
@@ -13108,6 +13122,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
   case OMPC_exclusive:
   case OMPC_uses_allocators:
   case OMPC_affinity:
+  default:
     llvm_unreachable("Clause is not allowed.");
   }
   return Res;
@@ -13345,6 +13360,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
   case OMPC_exclusive:
   case OMPC_uses_allocators:
   case OMPC_affinity:
+  default:
     llvm_unreachable("Clause is not allowed.");
   }
   return Res;
@@ -13618,6 +13634,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
   case OMPC_destroy:
   case OMPC_detach:
   case OMPC_uses_allocators:
+  default:
     llvm_unreachable("Clause is not allowed.");
   }
   return Res;

diff  --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index ac45d1ec2632..74aaf0f9c56e 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -11994,6 +11994,8 @@ OMPClause *OMPClauseReader::readClause() {
   case llvm::omp::Enum:                                                        \
     break;
 #include "llvm/Frontend/OpenMP/OMPKinds.def"
+  default:
+    break;
   }
   assert(C && "Unknown OMPClause type");
 

diff  --git a/flang/include/flang/Common/enum-set.h b/flang/include/flang/Common/enum-set.h
index 5346cceaadfa..4d2bc1e7433c 100644
--- a/flang/include/flang/Common/enum-set.h
+++ b/flang/include/flang/Common/enum-set.h
@@ -190,7 +190,7 @@ template <typename ENUM, std::size_t BITS> class EnumSet {
       // std::bitset: just iterate
       for (std::size_t j{0}; j < BITS; ++j) {
         auto enumerator{static_cast<enumerationType>(j)};
-        if (bitset_.test(enumerator)) {
+        if (bitset_.test(j)) {
           return {enumerator};
         }
       }

diff  --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index ad93fcd25795..80a1411db5dd 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -409,7 +409,11 @@ class ParseTreeDumper {
   NODE(parser, OmpBeginLoopDirective)
   NODE(parser, OmpBeginSectionsDirective)
   NODE(parser, OmpBlockDirective)
-  NODE_ENUM(OmpBlockDirective, Directive)
+  static std::string GetNodeName(const llvm::omp::Directive &x) {
+    return llvm::Twine(
+        "llvm::omp::Directive = ", llvm::omp::getOpenMPDirectiveName(x))
+        .str();
+  }
   NODE(parser, OmpCancelType)
   NODE_ENUM(OmpCancelType, Type)
   NODE(parser, OmpClause)
@@ -477,7 +481,6 @@ class ParseTreeDumper {
   NODE(parser, OmpLinearModifier)
   NODE_ENUM(OmpLinearModifier, Type)
   NODE(parser, OmpLoopDirective)
-  NODE_ENUM(OmpLoopDirective, Directive)
   NODE(parser, OmpMapClause)
   NODE(parser, OmpMapType)
   NODE(OmpMapType, Always)
@@ -505,9 +508,7 @@ class ParseTreeDumper {
   NODE_ENUM(OmpScheduleModifierType, ModType)
   NODE(parser, OmpSectionBlocks)
   NODE(parser, OmpSectionsDirective)
-  NODE_ENUM(OmpSectionsDirective, Directive)
   NODE(parser, OmpSimpleStandaloneDirective)
-  NODE_ENUM(OmpSimpleStandaloneDirective, Directive)
   NODE(parser, Only)
   NODE(parser, OpenMPAtomicConstruct)
   NODE(parser, OpenMPBlockConstruct)

diff  --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 933638d039d3..1ca3b4967240 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -25,6 +25,7 @@
 #include "flang/Common/Fortran.h"
 #include "flang/Common/idioms.h"
 #include "flang/Common/indirection.h"
+#include "llvm/Frontend/OpenMP/OMPConstants.h"
 #include <cinttypes>
 #include <list>
 #include <memory>
@@ -3495,8 +3496,7 @@ struct OmpClauseList {
 // 2.7.2 SECTIONS
 // 2.11.2 PARALLEL SECTIONS
 struct OmpSectionsDirective {
-  ENUM_CLASS(Directive, Sections, ParallelSections);
-  WRAPPER_CLASS_BOILERPLATE(OmpSectionsDirective, Directive);
+  WRAPPER_CLASS_BOILERPLATE(OmpSectionsDirective, llvm::omp::Directive);
   CharBlock source;
 };
 
@@ -3527,10 +3527,7 @@ struct OpenMPSectionsConstruct {
 
 // OpenMP directive beginning or ending a block
 struct OmpBlockDirective {
-  ENUM_CLASS(Directive, Master, Ordered, Parallel, ParallelWorkshare, Single,
-      Target, TargetData, TargetParallel, TargetTeams, Task, Taskgroup, Teams,
-      Workshare);
-  WRAPPER_CLASS_BOILERPLATE(OmpBlockDirective, Directive);
+  WRAPPER_CLASS_BOILERPLATE(OmpBlockDirective, llvm::omp::Directive);
   CharBlock source;
 };
 
@@ -3684,15 +3681,7 @@ struct OpenMPAtomicConstruct {
 
 // OpenMP directives that associate with loop(s)
 struct OmpLoopDirective {
-  ENUM_CLASS(Directive, Distribute, DistributeParallelDo,
-      DistributeParallelDoSimd, DistributeSimd, ParallelDo, ParallelDoSimd, Do,
-      DoSimd, Simd, TargetParallelDo, TargetParallelDoSimd,
-      TargetTeamsDistribute, TargetTeamsDistributeParallelDo,
-      TargetTeamsDistributeParallelDoSimd, TargetTeamsDistributeSimd,
-      TargetSimd, Taskloop, TaskloopSimd, TeamsDistribute,
-      TeamsDistributeParallelDo, TeamsDistributeParallelDoSimd,
-      TeamsDistributeSimd)
-  WRAPPER_CLASS_BOILERPLATE(OmpLoopDirective, Directive);
+  WRAPPER_CLASS_BOILERPLATE(OmpLoopDirective, llvm::omp::Directive);
   CharBlock source;
 };
 
@@ -3726,9 +3715,7 @@ struct OpenMPFlushConstruct {
 };
 
 struct OmpSimpleStandaloneDirective {
-  ENUM_CLASS(Directive, Barrier, Taskwait, Taskyield, TargetEnterData,
-      TargetExitData, TargetUpdate, Ordered)
-  WRAPPER_CLASS_BOILERPLATE(OmpSimpleStandaloneDirective, Directive);
+  WRAPPER_CLASS_BOILERPLATE(OmpSimpleStandaloneDirective, llvm::omp::Directive);
   CharBlock source;
 };
 

diff  --git a/flang/lib/Evaluate/CMakeLists.txt b/flang/lib/Evaluate/CMakeLists.txt
index ddcdc8018658..e94f07adf814 100644
--- a/flang/lib/Evaluate/CMakeLists.txt
+++ b/flang/lib/Evaluate/CMakeLists.txt
@@ -33,6 +33,9 @@ add_flang_library(FortranEvaluate
   FortranDecimal
   FortranSemantics
   FortranParser
+
+  DEPENDS
+  omp_gen
 )
 
 if (LIBPGMATH_DIR)

diff  --git a/flang/lib/Parser/CMakeLists.txt b/flang/lib/Parser/CMakeLists.txt
index cc691de35b48..eb5126e1b937 100644
--- a/flang/lib/Parser/CMakeLists.txt
+++ b/flang/lib/Parser/CMakeLists.txt
@@ -29,4 +29,7 @@ add_flang_library(FortranParser
 
   LINK_COMPONENTS
   Support
+
+  DEPENDS
+  omp_gen
 )

diff  --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 2d81f5a8197b..b845d6573c65 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -240,45 +240,38 @@ TYPE_PARSER(construct<OmpObjectList>(nonemptyList(Parser<OmpObject>{})))
 // Omp directives enclosing do loop
 TYPE_PARSER(sourced(construct<OmpLoopDirective>(first(
     "DISTRIBUTE PARALLEL DO SIMD" >>
-        pure(OmpLoopDirective::Directive::DistributeParallelDoSimd),
+        pure(llvm::omp::Directive::OMPD_distribute_parallel_do_simd),
     "DISTRIBUTE PARALLEL DO" >>
-        pure(OmpLoopDirective::Directive::DistributeParallelDo),
-
-    "DISTRIBUTE SIMD" >> pure(OmpLoopDirective::Directive::DistributeSimd),
-
-    "DISTRIBUTE" >> pure(OmpLoopDirective::Directive::Distribute),
-
-    "DO SIMD" >> pure(OmpLoopDirective::Directive::DoSimd),
-    "DO" >> pure(OmpLoopDirective::Directive::Do),
-    "PARALLEL DO SIMD" >> pure(OmpLoopDirective::Directive::ParallelDoSimd),
-
-    "PARALLEL DO" >> pure(OmpLoopDirective::Directive::ParallelDo),
-
-    "SIMD" >> pure(OmpLoopDirective::Directive::Simd),
+        pure(llvm::omp::Directive::OMPD_distribute_parallel_do),
+    "DISTRIBUTE SIMD" >> pure(llvm::omp::Directive::OMPD_distribute_simd),
+    "DISTRIBUTE" >> pure(llvm::omp::Directive::OMPD_distribute),
+    "DO SIMD" >> pure(llvm::omp::Directive::OMPD_do_simd),
+    "DO" >> pure(llvm::omp::Directive::OMPD_do),
+    "PARALLEL DO SIMD" >> pure(llvm::omp::Directive::OMPD_parallel_do_simd),
+    "PARALLEL DO" >> pure(llvm::omp::Directive::OMPD_parallel_do),
+    "SIMD" >> pure(llvm::omp::Directive::OMPD_simd),
     "TARGET PARALLEL DO SIMD" >>
-        pure(OmpLoopDirective::Directive::TargetParallelDoSimd),
-    "TARGET PARALLEL DO" >> pure(OmpLoopDirective::Directive::TargetParallelDo),
-
-    "TARGET SIMD" >> pure(OmpLoopDirective::Directive::TargetSimd),
+        pure(llvm::omp::Directive::OMPD_target_parallel_do_simd),
+    "TARGET PARALLEL DO" >> pure(llvm::omp::Directive::OMPD_target_parallel_do),
+    "TARGET SIMD" >> pure(llvm::omp::Directive::OMPD_target_simd),
     "TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD" >>
-        pure(OmpLoopDirective::Directive::TargetTeamsDistributeParallelDoSimd),
+        pure(llvm::omp::Directive::
+                OMPD_target_teams_distribute_parallel_do_simd),
     "TARGET TEAMS DISTRIBUTE PARALLEL DO" >>
-        pure(OmpLoopDirective::Directive::TargetTeamsDistributeParallelDo),
+        pure(llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do),
     "TARGET TEAMS DISTRIBUTE SIMD" >>
-        pure(OmpLoopDirective::Directive::TargetTeamsDistributeSimd),
+        pure(llvm::omp::Directive::OMPD_target_teams_distribute_simd),
     "TARGET TEAMS DISTRIBUTE" >>
-        pure(OmpLoopDirective::Directive::TargetTeamsDistribute),
-
-    "TASKLOOP SIMD" >> pure(OmpLoopDirective::Directive::TaskloopSimd),
-
-    "TASKLOOP" >> pure(OmpLoopDirective::Directive::Taskloop),
+        pure(llvm::omp::Directive::OMPD_target_teams_distribute),
+    "TASKLOOP SIMD" >> pure(llvm::omp::Directive::OMPD_taskloop_simd),
+    "TASKLOOP" >> pure(llvm::omp::Directive::OMPD_taskloop),
     "TEAMS DISTRIBUTE PARALLEL DO SIMD" >>
-        pure(OmpLoopDirective::Directive::TeamsDistributeParallelDoSimd),
+        pure(llvm::omp::Directive::OMPD_teams_distribute_parallel_do_simd),
     "TEAMS DISTRIBUTE PARALLEL DO" >>
-        pure(OmpLoopDirective::Directive::TeamsDistributeParallelDo),
+        pure(llvm::omp::Directive::OMPD_teams_distribute_parallel_do),
     "TEAMS DISTRIBUTE SIMD" >>
-        pure(OmpLoopDirective::Directive::TeamsDistributeSimd),
-    "TEAMS DISTRIBUTE" >> pure(OmpLoopDirective::Directive::TeamsDistribute)))))
+        pure(llvm::omp::Directive::OMPD_teams_distribute_simd),
+    "TEAMS DISTRIBUTE" >> pure(llvm::omp::Directive::OMPD_teams_distribute)))))
 
 TYPE_PARSER(sourced(construct<OmpBeginLoopDirective>(
     sourced(Parser<OmpLoopDirective>{}), Parser<OmpClauseList>{})))
@@ -304,16 +297,13 @@ TYPE_PARSER(sourced(construct<OpenMPFlushConstruct>(
 
 // Simple Standalone Directives
 TYPE_PARSER(sourced(construct<OmpSimpleStandaloneDirective>(first(
-    "BARRIER" >> pure(OmpSimpleStandaloneDirective::Directive::Barrier),
-    "ORDERED" >> pure(OmpSimpleStandaloneDirective::Directive::Ordered),
-    "TARGET ENTER DATA" >>
-        pure(OmpSimpleStandaloneDirective::Directive::TargetEnterData),
-    "TARGET EXIT DATA" >>
-        pure(OmpSimpleStandaloneDirective::Directive::TargetExitData),
-    "TARGET UPDATE" >>
-        pure(OmpSimpleStandaloneDirective::Directive::TargetUpdate),
-    "TASKWAIT" >> pure(OmpSimpleStandaloneDirective::Directive::Taskwait),
-    "TASKYIELD" >> pure(OmpSimpleStandaloneDirective::Directive::Taskyield)))))
+    "BARRIER" >> pure(llvm::omp::Directive::OMPD_barrier),
+    "ORDERED" >> pure(llvm::omp::Directive::OMPD_ordered),
+    "TARGET ENTER DATA" >> pure(llvm::omp::Directive::OMPD_target_enter_data),
+    "TARGET EXIT DATA" >> pure(llvm::omp::Directive::OMPD_target_exit_data),
+    "TARGET UPDATE" >> pure(llvm::omp::Directive::OMPD_target_update),
+    "TASKWAIT" >> pure(llvm::omp::Directive::OMPD_taskwait),
+    "TASKYIELD" >> pure(llvm::omp::Directive::OMPD_taskyield)))))
 
 TYPE_PARSER(sourced(construct<OpenMPSimpleStandaloneConstruct>(
     Parser<OmpSimpleStandaloneDirective>{}, Parser<OmpClauseList>{})))
@@ -329,21 +319,20 @@ TYPE_PARSER(
     endOfLine)
 
 // Directives enclosing structured-block
-TYPE_PARSER(construct<OmpBlockDirective>(
-    first("MASTER" >> pure(OmpBlockDirective::Directive::Master),
-        "ORDERED" >> pure(OmpBlockDirective::Directive::Ordered),
-        "PARALLEL WORKSHARE" >>
-            pure(OmpBlockDirective::Directive::ParallelWorkshare),
-        "PARALLEL" >> pure(OmpBlockDirective::Directive::Parallel),
-        "SINGLE" >> pure(OmpBlockDirective::Directive::Single),
-        "TARGET DATA" >> pure(OmpBlockDirective::Directive::TargetData),
-        "TARGET PARALLEL" >> pure(OmpBlockDirective::Directive::TargetParallel),
-        "TARGET TEAMS" >> pure(OmpBlockDirective::Directive::TargetTeams),
-        "TARGET" >> pure(OmpBlockDirective::Directive::Target),
-        "TASK"_id >> pure(OmpBlockDirective::Directive::Task),
-        "TASKGROUP" >> pure(OmpBlockDirective::Directive::Taskgroup),
-        "TEAMS" >> pure(OmpBlockDirective::Directive::Teams),
-        "WORKSHARE" >> pure(OmpBlockDirective::Directive::Workshare))))
+TYPE_PARSER(construct<OmpBlockDirective>(first(
+    "MASTER" >> pure(llvm::omp::Directive::OMPD_master),
+    "ORDERED" >> pure(llvm::omp::Directive::OMPD_ordered),
+    "PARALLEL WORKSHARE" >> pure(llvm::omp::Directive::OMPD_parallel_workshare),
+    "PARALLEL" >> pure(llvm::omp::Directive::OMPD_parallel),
+    "SINGLE" >> pure(llvm::omp::Directive::OMPD_single),
+    "TARGET DATA" >> pure(llvm::omp::Directive::OMPD_target_data),
+    "TARGET PARALLEL" >> pure(llvm::omp::Directive::OMPD_target_parallel),
+    "TARGET TEAMS" >> pure(llvm::omp::Directive::OMPD_target_teams),
+    "TARGET" >> pure(llvm::omp::Directive::OMPD_target),
+    "TASK"_id >> pure(llvm::omp::Directive::OMPD_task),
+    "TASKGROUP" >> pure(llvm::omp::Directive::OMPD_taskgroup),
+    "TEAMS" >> pure(llvm::omp::Directive::OMPD_teams),
+    "WORKSHARE" >> pure(llvm::omp::Directive::OMPD_workshare))))
 
 TYPE_PARSER(sourced(construct<OmpBeginBlockDirective>(
     sourced(Parser<OmpBlockDirective>{}), Parser<OmpClauseList>{})))
@@ -476,10 +465,9 @@ TYPE_PARSER(construct<OpenMPBlockConstruct>(
     Parser<OmpEndBlockDirective>{} / endOmpLine))
 
 // OMP SECTIONS Directive
-TYPE_PARSER(construct<OmpSectionsDirective>(
-    first("SECTIONS" >> pure(OmpSectionsDirective::Directive::Sections),
-        "PARALLEL SECTIONS" >>
-            pure(OmpSectionsDirective::Directive::ParallelSections))))
+TYPE_PARSER(construct<OmpSectionsDirective>(first(
+    "SECTIONS" >> pure(llvm::omp::Directive::OMPD_sections),
+    "PARALLEL SECTIONS" >> pure(llvm::omp::Directive::OMPD_parallel_sections))))
 
 // OMP BEGIN and END SECTIONS Directive
 TYPE_PARSER(sourced(construct<OmpBeginSectionsDirective>(

diff  --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index c2b5c28767da..19c5ba6d589a 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2017,141 +2017,149 @@ class UnparseVisitor {
   }
   void Unparse(const OmpLoopDirective &x) {
     switch (x.v) {
-    case OmpLoopDirective::Directive::Distribute:
+    case llvm::omp::Directive::OMPD_distribute:
       Word("DISTRIBUTE ");
       break;
-    case OmpLoopDirective::Directive::DistributeParallelDo:
+    case llvm::omp::Directive::OMPD_distribute_parallel_do:
       Word("DISTRIBUTE PARALLEL DO ");
       break;
-    case OmpLoopDirective::Directive::DistributeParallelDoSimd:
+    case llvm::omp::Directive::OMPD_distribute_parallel_do_simd:
       Word("DISTRIBUTE PARALLEL DO SIMD ");
       break;
-    case OmpLoopDirective::Directive::DistributeSimd:
+    case llvm::omp::Directive::OMPD_distribute_simd:
       Word("DISTRIBUTE SIMD ");
       break;
-    case OmpLoopDirective::Directive::Do:
+    case llvm::omp::Directive::OMPD_do:
       Word("DO ");
       break;
-    case OmpLoopDirective::Directive::DoSimd:
-      Word("Do SIMD ");
+    case llvm::omp::Directive::OMPD_do_simd:
+      Word("DO SIMD ");
       break;
-    case OmpLoopDirective::Directive::ParallelDo:
+    case llvm::omp::Directive::OMPD_parallel_do:
       Word("PARALLEL DO ");
       break;
-    case OmpLoopDirective::Directive::ParallelDoSimd:
+    case llvm::omp::Directive::OMPD_parallel_do_simd:
       Word("PARALLEL DO SIMD ");
       break;
-    case OmpLoopDirective::Directive::Simd:
+    case llvm::omp::Directive::OMPD_simd:
       Word("SIMD ");
       break;
-    case OmpLoopDirective::Directive::TargetParallelDo:
+    case llvm::omp::Directive::OMPD_target_parallel_do:
       Word("TARGET PARALLEL DO ");
       break;
-    case OmpLoopDirective::Directive::TargetParallelDoSimd:
+    case llvm::omp::Directive::OMPD_target_parallel_do_simd:
       Word("TARGET PARALLEL DO SIMD ");
       break;
-    case OmpLoopDirective::Directive::TargetTeamsDistribute:
+    case llvm::omp::Directive::OMPD_target_teams_distribute:
       Word("TARGET TEAMS DISTRIBUTE ");
       break;
-    case OmpLoopDirective::Directive::TargetTeamsDistributeParallelDo:
+    case llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do:
       Word("TARGET TEAMS DISTRIBUTE PARALLEL DO ");
       break;
-    case OmpLoopDirective::Directive::TargetTeamsDistributeParallelDoSimd:
+    case llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do_simd:
       Word("TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD ");
       break;
-    case OmpLoopDirective::Directive::TargetTeamsDistributeSimd:
+    case llvm::omp::Directive::OMPD_target_teams_distribute_simd:
       Word("TARGET TEAMS DISTRIBUTE SIMD ");
       break;
-    case OmpLoopDirective::Directive::TargetSimd:
+    case llvm::omp::Directive::OMPD_target_simd:
       Word("TARGET SIMD ");
       break;
-    case OmpLoopDirective::Directive::Taskloop:
+    case llvm::omp::Directive::OMPD_taskloop:
       Word("TASKLOOP ");
       break;
-    case OmpLoopDirective::Directive::TaskloopSimd:
+    case llvm::omp::Directive::OMPD_taskloop_simd:
       Word("TASKLOOP SIMD ");
       break;
-    case OmpLoopDirective::Directive::TeamsDistribute:
+    case llvm::omp::Directive::OMPD_teams_distribute:
       Word("TEAMS DISTRIBUTE ");
       break;
-    case OmpLoopDirective::Directive::TeamsDistributeParallelDo:
+    case llvm::omp::Directive::OMPD_teams_distribute_parallel_do:
       Word("TEAMS DISTRIBUTE PARALLEL DO ");
       break;
-    case OmpLoopDirective::Directive::TeamsDistributeParallelDoSimd:
+    case llvm::omp::Directive::OMPD_teams_distribute_parallel_do_simd:
       Word("TEAMS DISTRIBUTE PARALLEL DO SIMD ");
       break;
-    case OmpLoopDirective::Directive::TeamsDistributeSimd:
+    case llvm::omp::Directive::OMPD_teams_distribute_simd:
       Word("TEAMS DISTRIBUTE SIMD ");
       break;
+    default:
+      break;
     }
   }
   void Unparse(const OmpObjectList &x) { Walk(x.v, ","); }
   void Unparse(const OmpSimpleStandaloneDirective &x) {
     switch (x.v) {
-    case OmpSimpleStandaloneDirective::Directive::Barrier:
+    case llvm::omp::Directive::OMPD_barrier:
       Word("BARRIER ");
       break;
-    case OmpSimpleStandaloneDirective::Directive::Taskwait:
+    case llvm::omp::Directive::OMPD_taskwait:
       Word("TASKWAIT ");
       break;
-    case OmpSimpleStandaloneDirective::Directive::Taskyield:
+    case llvm::omp::Directive::OMPD_taskyield:
       Word("TASKYIELD ");
       break;
-    case OmpSimpleStandaloneDirective::Directive::TargetEnterData:
+    case llvm::omp::Directive::OMPD_target_enter_data:
       Word("TARGET ENTER DATA ");
       break;
-    case OmpSimpleStandaloneDirective::Directive::TargetExitData:
+    case llvm::omp::Directive::OMPD_target_exit_data:
       Word("TARGET EXIT DATA ");
       break;
-    case OmpSimpleStandaloneDirective::Directive::TargetUpdate:
+    case llvm::omp::Directive::OMPD_target_update:
       Word("TARGET UPDATE ");
       break;
-    case OmpSimpleStandaloneDirective::Directive::Ordered:
+    case llvm::omp::Directive::OMPD_ordered:
       Word("ORDERED ");
       break;
+    default:
+      // Nothing to be done
+      break;
     }
   }
   void Unparse(const OmpBlockDirective &x) {
     switch (x.v) {
-    case OmpBlockDirective::Directive::Master:
+    case llvm::omp::Directive::OMPD_master:
       Word("MASTER");
       break;
-    case OmpBlockDirective::Directive::Ordered:
+    case llvm::omp::Directive::OMPD_ordered:
       Word("ORDERED ");
       break;
-    case OmpBlockDirective::Directive::ParallelWorkshare:
+    case llvm::omp::Directive::OMPD_parallel_workshare:
       Word("PARALLEL WORKSHARE ");
       break;
-    case OmpBlockDirective::Directive::Parallel:
+    case llvm::omp::Directive::OMPD_parallel:
       Word("PARALLEL ");
       break;
-    case OmpBlockDirective::Directive::Single:
+    case llvm::omp::Directive::OMPD_single:
       Word("SINGLE ");
       break;
-    case OmpBlockDirective::Directive::TargetData:
+    case llvm::omp::Directive::OMPD_target_data:
       Word("TARGET DATA ");
       break;
-    case OmpBlockDirective::Directive::TargetParallel:
+    case llvm::omp::Directive::OMPD_target_parallel:
       Word("TARGET PARALLEL ");
       break;
-    case OmpBlockDirective::Directive::TargetTeams:
+    case llvm::omp::Directive::OMPD_target_teams:
       Word("TARGET TEAMS ");
       break;
-    case OmpBlockDirective::Directive::Target:
+    case llvm::omp::Directive::OMPD_target:
       Word("TARGET ");
       break;
-    case OmpBlockDirective::Directive::Taskgroup:
+    case llvm::omp::Directive::OMPD_taskgroup:
       Word("TASKGROUP ");
       break;
-    case OmpBlockDirective::Directive::Task:
+    case llvm::omp::Directive::OMPD_task:
       Word("TASK ");
       break;
-    case OmpBlockDirective::Directive::Teams:
+    case llvm::omp::Directive::OMPD_teams:
       Word("TEAMS ");
       break;
-    case OmpBlockDirective::Directive::Workshare:
+    case llvm::omp::Directive::OMPD_workshare:
       Word("WORKSHARE ");
       break;
+    default:
+      // Nothing to be done
+      break;
     }
   }
   void Unparse(const OmpMemoryClause &x) {
@@ -2314,12 +2322,14 @@ class UnparseVisitor {
   }
   void Unparse(const OmpSectionsDirective &x) {
     switch (x.v) {
-    case OmpSectionsDirective::Directive::Sections:
+    case llvm::omp::Directive::OMPD_sections:
       Word("SECTIONS ");
       break;
-    case OmpSectionsDirective::Directive::ParallelSections:
+    case llvm::omp::Directive::OMPD_parallel_sections:
       Word("PARALLEL SECTIONS ");
       break;
+    default:
+      break;
     }
   }
   void Unparse(const OmpSectionBlocks &x) {

diff  --git a/flang/lib/Semantics/CMakeLists.txt b/flang/lib/Semantics/CMakeLists.txt
index 4fd75bc60f00..b0e40bd3251d 100644
--- a/flang/lib/Semantics/CMakeLists.txt
+++ b/flang/lib/Semantics/CMakeLists.txt
@@ -39,10 +39,14 @@ add_flang_library(FortranSemantics
   type.cpp
   unparse-with-symbols.cpp
 
+  DEPENDS
+  omp_gen
+
   LINK_LIBS
   FortranCommon
   FortranEvaluate
 
   LINK_COMPONENTS
   Support
+  FrontendOpenMP
 )

diff  --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 77312733cd2e..b4e86faffe19 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -13,55 +13,62 @@
 
 namespace Fortran::semantics {
 
-static constexpr inline OmpClauseSet doAllowedClauses{OmpClause::PRIVATE,
-    OmpClause::FIRSTPRIVATE, OmpClause::LASTPRIVATE, OmpClause::LINEAR,
-    OmpClause::REDUCTION};
-static constexpr inline OmpClauseSet doAllowedOnceClauses{
-    OmpClause::SCHEDULE, OmpClause::COLLAPSE, OmpClause::ORDERED};
-
-static constexpr inline OmpClauseSet simdAllowedClauses{OmpClause::LINEAR,
-    OmpClause::ALIGNED, OmpClause::PRIVATE, OmpClause::LASTPRIVATE,
-    OmpClause::REDUCTION};
-static constexpr inline OmpClauseSet simdAllowedOnceClauses{
-    OmpClause::COLLAPSE, OmpClause::SAFELEN, OmpClause::SIMDLEN};
-
-static constexpr inline OmpClauseSet parallelAllowedClauses{OmpClause::DEFAULT,
-    OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE, OmpClause::SHARED,
-    OmpClause::COPYIN, OmpClause::REDUCTION};
-static constexpr inline OmpClauseSet parallelAllowedOnceClauses{
-    OmpClause::IF, OmpClause::NUM_THREADS, OmpClause::PROC_BIND};
-
-static constexpr inline OmpClauseSet taskloopAllowedClauses{OmpClause::SHARED,
-    OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE, OmpClause::LASTPRIVATE,
-    OmpClause::DEFAULT, OmpClause::UNTIED, OmpClause::MERGEABLE,
-    OmpClause::NOGROUP};
-static constexpr inline OmpClauseSet taskloopAllowedOnceClauses{
-    OmpClause::COLLAPSE, OmpClause::IF, OmpClause::FINAL, OmpClause::PRIORITY};
-static constexpr inline OmpClauseSet taskloopAllowedExclusiveClauses{
-    OmpClause::GRAINSIZE, OmpClause::NUM_TASKS};
-
-static constexpr inline OmpClauseSet distributeAllowedClauses{
-    OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE, OmpClause::LASTPRIVATE};
-static constexpr inline OmpClauseSet distributeAllowedOnceClauses{
-    OmpClause::COLLAPSE, OmpClause::DIST_SCHEDULE};
-
-static constexpr inline OmpClauseSet targetAllowedClauses{OmpClause::IF,
-    OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE, OmpClause::MAP,
-    OmpClause::IS_DEVICE_PTR, OmpClause::DEPEND};
-static constexpr inline OmpClauseSet targetAllowedOnceClauses{
-    OmpClause::DEVICE, OmpClause::DEFAULTMAP, OmpClause::NOWAIT};
-
-static constexpr inline OmpClauseSet teamsAllowedClauses{OmpClause::PRIVATE,
-    OmpClause::FIRSTPRIVATE, OmpClause::SHARED, OmpClause::REDUCTION};
-static constexpr inline OmpClauseSet teamsAllowedOnceClauses{
-    OmpClause::NUM_TEAMS, OmpClause::THREAD_LIMIT, OmpClause::DEFAULT};
-
-static constexpr inline OmpClauseSet sectionsAllowedClauses{OmpClause::PRIVATE,
-    OmpClause::FIRSTPRIVATE, OmpClause::LASTPRIVATE, OmpClause::REDUCTION};
+static OmpClauseSet doAllowedClauses{llvm::omp::Clause::OMPC_private,
+    llvm::omp::Clause::OMPC_firstprivate, llvm::omp::Clause::OMPC_lastprivate,
+    llvm::omp::Clause::OMPC_linear, llvm::omp::Clause::OMPC_reduction};
+static OmpClauseSet doAllowedOnceClauses{llvm::omp::Clause::OMPC_schedule,
+    llvm::omp::Clause::OMPC_collapse, llvm::omp::Clause::OMPC_ordered};
+
+static OmpClauseSet simdAllowedClauses{llvm::omp::Clause::OMPC_linear,
+    llvm::omp::Clause::OMPC_aligned, llvm::omp::Clause::OMPC_private,
+    llvm::omp::Clause::OMPC_lastprivate, llvm::omp::Clause::OMPC_reduction};
+static OmpClauseSet simdAllowedOnceClauses{llvm::omp::Clause::OMPC_collapse,
+    llvm::omp::Clause::OMPC_safelen, llvm::omp::Clause::OMPC_simdlen};
+
+static OmpClauseSet parallelAllowedClauses{llvm::omp::Clause::OMPC_default,
+    llvm::omp::Clause::OMPC_private, llvm::omp::Clause::OMPC_firstprivate,
+    llvm::omp::Clause::OMPC_shared, llvm::omp::Clause::OMPC_copyin,
+    llvm::omp::Clause::OMPC_reduction};
+static OmpClauseSet parallelAllowedOnceClauses{llvm::omp::Clause::OMPC_if,
+    llvm::omp::Clause::OMPC_num_threads, llvm::omp::Clause::OMPC_proc_bind};
+
+static OmpClauseSet taskloopAllowedClauses{llvm::omp::Clause::OMPC_shared,
+    llvm::omp::Clause::OMPC_private, llvm::omp::Clause::OMPC_firstprivate,
+    llvm::omp::Clause::OMPC_lastprivate, llvm::omp::Clause::OMPC_default,
+    llvm::omp::Clause::OMPC_untied, llvm::omp::Clause::OMPC_mergeable,
+    llvm::omp::Clause::OMPC_nogroup};
+static OmpClauseSet taskloopAllowedOnceClauses{llvm::omp::Clause::OMPC_collapse,
+    llvm::omp::Clause::OMPC_if, llvm::omp::Clause::OMPC_final,
+    llvm::omp::Clause::OMPC_priority};
+static OmpClauseSet taskloopAllowedExclusiveClauses{
+    llvm::omp::Clause::OMPC_grainsize, llvm::omp::Clause::OMPC_num_tasks};
+
+static OmpClauseSet distributeAllowedClauses{llvm::omp::Clause::OMPC_private,
+    llvm::omp::Clause::OMPC_firstprivate, llvm::omp::Clause::OMPC_lastprivate};
+static OmpClauseSet distributeAllowedOnceClauses{
+    llvm::omp::Clause::OMPC_collapse, llvm::omp::Clause::OMPC_dist_schedule};
+
+static OmpClauseSet targetAllowedClauses{llvm::omp::Clause::OMPC_if,
+    llvm::omp::Clause::OMPC_private, llvm::omp::Clause::OMPC_firstprivate,
+    llvm::omp::Clause::OMPC_map, llvm::omp::Clause::OMPC_is_device_ptr,
+    llvm::omp::Clause::OMPC_depend};
+static OmpClauseSet targetAllowedOnceClauses{llvm::omp::Clause::OMPC_device,
+    llvm::omp::Clause::OMPC_defaultmap, llvm::omp::Clause::OMPC_nowait};
+
+static OmpClauseSet teamsAllowedClauses{llvm::omp::Clause::OMPC_private,
+    llvm::omp::Clause::OMPC_firstprivate, llvm::omp::Clause::OMPC_shared,
+    llvm::omp::Clause::OMPC_reduction};
+static OmpClauseSet teamsAllowedOnceClauses{llvm::omp::Clause::OMPC_num_teams,
+    llvm::omp::Clause::OMPC_thread_limit, llvm::omp::Clause::OMPC_default};
+
+static OmpClauseSet sectionsAllowedClauses{llvm::omp::Clause::OMPC_private,
+    llvm::omp::Clause::OMPC_firstprivate, llvm::omp::Clause::OMPC_lastprivate,
+    llvm::omp::Clause::OMPC_reduction};
 
 std::string OmpStructureChecker::ContextDirectiveAsFortran() {
-  auto dir{EnumToString(GetContext().directive)};
-  std::replace(dir.begin(), dir.end(), '_', ' ');
+  auto dir = llvm::omp::getOpenMPDirectiveName(GetContext().directive).str();
+  std::transform(dir.begin(), dir.end(), dir.begin(),
+      [](unsigned char c) { return std::toupper(c); });
   return dir;
 }
 
@@ -87,13 +94,13 @@ bool OmpStructureChecker::HasInvalidWorksharingNesting(
   return false;
 }
 
-void OmpStructureChecker::CheckAllowed(OmpClause type) {
+void OmpStructureChecker::CheckAllowed(llvm::omp::Clause type) {
   if (!GetContext().allowedClauses.test(type) &&
       !GetContext().allowedOnceClauses.test(type) &&
       !GetContext().allowedExclusiveClauses.test(type)) {
     context_.Say(GetContext().clauseSource,
         "%s clause is not allowed on the %s directive"_err_en_US,
-        EnumToString(type),
+        parser::ToUpperCaseLetters(llvm::omp::getOpenMPClauseName(type).str()),
         parser::ToUpperCaseLetters(GetContext().directiveSource.ToString()));
     return;
   }
@@ -102,22 +109,25 @@ void OmpStructureChecker::CheckAllowed(OmpClause type) {
       FindClause(type)) {
     context_.Say(GetContext().clauseSource,
         "At most one %s clause can appear on the %s directive"_err_en_US,
-        EnumToString(type),
+        parser::ToUpperCaseLetters(llvm::omp::getOpenMPClauseName(type).str()),
         parser::ToUpperCaseLetters(GetContext().directiveSource.ToString()));
     return;
   }
   if (GetContext().allowedExclusiveClauses.test(type)) {
-    std::vector<OmpClause> others;
-    GetContext().allowedExclusiveClauses.IterateOverMembers([&](OmpClause o) {
-      if (FindClause(o)) {
-        others.emplace_back(o);
-      }
-    });
+    std::vector<llvm::omp::Clause> others;
+    GetContext().allowedExclusiveClauses.IterateOverMembers(
+        [&](llvm::omp::Clause o) {
+          if (FindClause(o)) {
+            others.emplace_back(o);
+          }
+        });
     for (const auto &e : others) {
       context_.Say(GetContext().clauseSource,
           "%s and %s are mutually exclusive and may not appear on the "
           "same %s directive"_err_en_US,
-          EnumToString(type), EnumToString(e),
+          parser::ToUpperCaseLetters(
+              llvm::omp::getOpenMPClauseName(type).str()),
+          parser::ToUpperCaseLetters(llvm::omp::getOpenMPClauseName(e).str()),
           parser::ToUpperCaseLetters(GetContext().directiveSource.ToString()));
     }
     if (!others.empty()) {
@@ -127,34 +137,37 @@ void OmpStructureChecker::CheckAllowed(OmpClause type) {
   SetContextClauseInfo(type);
 }
 
-void OmpStructureChecker::CheckRequired(OmpClause c) {
+void OmpStructureChecker::CheckRequired(llvm::omp::Clause c) {
   if (!FindClause(c)) {
     context_.Say(GetContext().directiveSource,
         "At least one %s clause must appear on the %s directive"_err_en_US,
-        EnumToString(c), ContextDirectiveAsFortran());
+        parser::ToUpperCaseLetters(llvm::omp::getOpenMPClauseName(c).str()),
+        ContextDirectiveAsFortran());
   }
 }
 
 void OmpStructureChecker::RequiresConstantPositiveParameter(
-    const OmpClause &clause, const parser::ScalarIntConstantExpr &i) {
+    const llvm::omp::Clause &clause, const parser::ScalarIntConstantExpr &i) {
   if (const auto v{GetIntValue(i)}) {
     if (*v <= 0) {
       context_.Say(GetContext().clauseSource,
           "The parameter of the %s clause must be "
           "a constant positive integer expression"_err_en_US,
-          EnumToString(clause));
+          parser::ToUpperCaseLetters(
+              llvm::omp::getOpenMPClauseName(clause).str()));
     }
   }
 }
 
 void OmpStructureChecker::RequiresPositiveParameter(
-    const OmpClause &clause, const parser::ScalarIntExpr &i) {
+    const llvm::omp::Clause &clause, const parser::ScalarIntExpr &i) {
   if (const auto v{GetIntValue(i)}) {
     if (*v <= 0) {
       context_.Say(GetContext().clauseSource,
           "The parameter of the %s clause must be "
           "a positive integer expression"_err_en_US,
-          EnumToString(clause));
+          parser::ToUpperCaseLetters(
+              llvm::omp::getOpenMPClauseName(clause).str()));
     }
   }
 }
@@ -173,6 +186,9 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
     CheckMatching<parser::OmpLoopDirective>(beginLoopDir, *endLoopDir);
   }
 
+  if (beginDir.v != llvm::omp::Directive::OMPD_do)
+    PushContext(beginDir.source, beginDir.v);
+
   switch (beginDir.v) {
   // 2.7.1 do-clause -> private-clause |
   //                    firstprivate-clause |
@@ -182,23 +198,26 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
   //                    schedule-clause |
   //                    collapse-clause |
   //                    ordered-clause
-  case parser::OmpLoopDirective::Directive::Do: {
+  case llvm::omp::Directive::OMPD_do: {
     // nesting check
     HasInvalidWorksharingNesting(beginDir.source,
-        {OmpDirective::DO, OmpDirective::SECTIONS, OmpDirective::SINGLE,
-            OmpDirective::WORKSHARE, OmpDirective::TASK, OmpDirective::TASKLOOP,
-            OmpDirective::CRITICAL, OmpDirective::ORDERED, OmpDirective::ATOMIC,
-            OmpDirective::MASTER});
-
-    PushContext(beginDir.source, OmpDirective::DO);
+        {llvm::omp::Directive::OMPD_do, llvm::omp::Directive::OMPD_sections,
+            llvm::omp::Directive::OMPD_single,
+            llvm::omp::Directive::OMPD_workshare,
+            llvm::omp::Directive::OMPD_task,
+            llvm::omp::Directive::OMPD_taskloop,
+            llvm::omp::Directive::OMPD_critical,
+            llvm::omp::Directive::OMPD_ordered,
+            llvm::omp::Directive::OMPD_atomic,
+            llvm::omp::Directive::OMPD_master});
+    PushContext(beginDir.source, llvm::omp::Directive::OMPD_do);
     SetContextAllowed(doAllowedClauses);
     SetContextAllowedOnce(doAllowedOnceClauses);
   } break;
 
   // 2.11.1 parallel-do-clause -> parallel-clause |
   //                              do-clause
-  case parser::OmpLoopDirective::Directive::ParallelDo: {
-    PushContext(beginDir.source, OmpDirective::PARALLEL_DO);
+  case llvm::omp::Directive::OMPD_parallel_do: {
     SetContextAllowed(parallelAllowedClauses | doAllowedClauses);
     SetContextAllowedOnce(parallelAllowedOnceClauses | doAllowedOnceClauses);
   } break;
@@ -211,24 +230,21 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
   //                      lastprivate-clause |
   //                      reduction-clause |
   //                      collapse-clause
-  case parser::OmpLoopDirective::Directive::Simd: {
-    PushContext(beginDir.source, OmpDirective::SIMD);
+  case llvm::omp::Directive::OMPD_simd: {
     SetContextAllowed(simdAllowedClauses);
     SetContextAllowedOnce(simdAllowedOnceClauses);
   } break;
 
   // 2.8.3 do-simd-clause -> do-clause |
   //                         simd-clause
-  case parser::OmpLoopDirective::Directive::DoSimd: {
-    PushContext(beginDir.source, OmpDirective::DO_SIMD);
+  case llvm::omp::Directive::OMPD_do_simd: {
     SetContextAllowed(doAllowedClauses | simdAllowedClauses);
     SetContextAllowedOnce(doAllowedOnceClauses | simdAllowedOnceClauses);
   } break;
 
   // 2.11.4 parallel-do-simd-clause -> parallel-clause |
   //                                   do-simd-clause
-  case parser::OmpLoopDirective::Directive::ParallelDoSimd: {
-    PushContext(beginDir.source, OmpDirective::PARALLEL_DO_SIMD);
+  case llvm::omp::Directive::OMPD_parallel_do_simd: {
     SetContextAllowed(
         parallelAllowedClauses | doAllowedClauses | simdAllowedClauses);
     SetContextAllowedOnce(parallelAllowedOnceClauses | doAllowedOnceClauses |
@@ -249,8 +265,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
   //                          untied-clause |
   //                          mergeable-clause |
   //                          nogroup-clause
-  case parser::OmpLoopDirective::Directive::Taskloop: {
-    PushContext(beginDir.source, OmpDirective::TASKLOOP);
+  case llvm::omp::Directive::OMPD_taskloop: {
     SetContextAllowed(taskloopAllowedClauses);
     SetContextAllowedOnce(taskloopAllowedOnceClauses);
     SetContextAllowedExclusive(taskloopAllowedExclusiveClauses);
@@ -258,10 +273,9 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
 
   // 2.9.3 taskloop-simd-clause -> taskloop-clause |
   //                               simd-clause
-  case parser::OmpLoopDirective::Directive::TaskloopSimd: {
-    PushContext(beginDir.source, OmpDirective::TASKLOOP_SIMD);
-    SetContextAllowed(
-        (taskloopAllowedClauses | simdAllowedClauses) - OmpClause::REDUCTION);
+  case llvm::omp::Directive::OMPD_taskloop_simd: {
+    SetContextAllowed((taskloopAllowedClauses | simdAllowedClauses) -
+        llvm::omp::Clause::OMPC_reduction);
     SetContextAllowedOnce(taskloopAllowedOnceClauses | simdAllowedOnceClauses);
     SetContextAllowedExclusive(taskloopAllowedExclusiveClauses);
   } break;
@@ -271,116 +285,104 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
   //                             lastprivate-clause |
   //                             collapse-clause |
   //                             dist-schedule-clause
-  case parser::OmpLoopDirective::Directive::Distribute: {
-    PushContext(beginDir.source, OmpDirective::DISTRIBUTE);
+  case llvm::omp::Directive::OMPD_distribute: {
     SetContextAllowed(distributeAllowedClauses);
     SetContextAllowedOnce(distributeAllowedOnceClauses);
   } break;
 
-    // 2.10.9 distribute-simd-clause -> distribute-clause |
-    //                                  simd-clause
-  case parser::OmpLoopDirective::Directive::DistributeSimd: {
-    PushContext(beginDir.source, OmpDirective::DISTRIBUTE_SIMD);
+  // 2.10.9 distribute-simd-clause -> distribute-clause |
+  //                                  simd-clause
+  case llvm::omp::Directive::OMPD_distribute_simd: {
     SetContextAllowed(distributeAllowedClauses | simdAllowedClauses);
     SetContextAllowedOnce(
         distributeAllowedOnceClauses | simdAllowedOnceClauses);
   } break;
 
-    // 2.10.10 distribute-parallel-do-clause -> distribute-clause |
-    //                                          parallel-do-clause
-  case parser::OmpLoopDirective::Directive::DistributeParallelDo: {
-    PushContext(beginDir.source, OmpDirective::DISTRIBUTE_PARALLEL_DO);
+  // 2.10.10 distribute-parallel-do-clause -> distribute-clause |
+  //                                          parallel-do-clause
+  case llvm::omp::Directive::OMPD_distribute_parallel_do: {
     SetContextAllowed(
         distributeAllowedClauses | parallelAllowedClauses | doAllowedClauses);
     SetContextAllowedOnce(distributeAllowedOnceClauses |
         parallelAllowedOnceClauses | doAllowedOnceClauses);
   } break;
 
-    // 2.10.11 distribute-parallel-do-simd-clause -> distribute-clause |
-    //                                               parallel-do-simd-clause
-  case parser::OmpLoopDirective::Directive::DistributeParallelDoSimd: {
-    PushContext(beginDir.source, OmpDirective::DISTRIBUTE_PARALLEL_DO_SIMD);
+  // 2.10.11 distribute-parallel-do-simd-clause -> distribute-clause |
+  //                                               parallel-do-simd-clause
+  case llvm::omp::Directive::OMPD_distribute_parallel_do_simd: {
     SetContextAllowed(distributeAllowedClauses | parallelAllowedClauses |
         doAllowedClauses | simdAllowedClauses);
     SetContextAllowedOnce(distributeAllowedOnceClauses |
         parallelAllowedOnceClauses | doAllowedOnceClauses | simdAllowedClauses);
   } break;
 
-    // 2.11.6 target-parallel-do-clause -> target-clause |
-    //                                     parallel-do-clause
-  case parser::OmpLoopDirective::Directive::TargetParallelDo: {
-    PushContext(beginDir.source, OmpDirective::TARGET_PARALLEL_DO);
+  // 2.11.6 target-parallel-do-clause -> target-clause |
+  //                                     parallel-do-clause
+  case llvm::omp::Directive::OMPD_target_parallel_do: {
     SetContextAllowed(
         targetAllowedClauses | parallelAllowedClauses | doAllowedClauses);
     SetContextAllowedOnce(
         (targetAllowedOnceClauses | parallelAllowedOnceClauses |
             doAllowedOnceClauses) -
-        OmpClause::NOWAIT);
+        llvm::omp::Clause::OMPC_nowait);
   } break;
 
-    // 2.11.7 target-parallel-do-simd-clause -> target-clause |
-    //                                          parallel-do-simd-clause
-  case parser::OmpLoopDirective::Directive::TargetParallelDoSimd: {
-    PushContext(beginDir.source, OmpDirective::TARGET_PARALLEL_DO_SIMD);
+  // 2.11.7 target-parallel-do-simd-clause -> target-clause |
+  //                                          parallel-do-simd-clause
+  case llvm::omp::Directive::OMPD_target_parallel_do_simd: {
     SetContextAllowed(targetAllowedClauses | parallelAllowedClauses |
         doAllowedClauses | simdAllowedClauses);
     SetContextAllowedOnce(
         (targetAllowedOnceClauses | parallelAllowedOnceClauses |
             doAllowedOnceClauses | simdAllowedOnceClauses) -
-        OmpClause::NOWAIT);
+        llvm::omp::Clause::OMPC_nowait);
   } break;
 
-    // 2.11.8 target-simd-clause -> target-clause |
-    //                              simd-clause
-  case parser::OmpLoopDirective::Directive::TargetSimd: {
-    PushContext(beginDir.source, OmpDirective::TARGET_SIMD);
+  // 2.11.8 target-simd-clause -> target-clause |
+  //                              simd-clause
+  case llvm::omp::Directive::OMPD_target_simd: {
     SetContextAllowed(targetAllowedClauses | simdAllowedClauses);
     SetContextAllowedOnce(targetAllowedOnceClauses | simdAllowedOnceClauses);
   } break;
 
-    // 2.11.10 teams-distribute-clause -> teams-clause |
-    //                                    distribute-clause
-  case parser::OmpLoopDirective::Directive::TeamsDistribute: {
-    PushContext(beginDir.source, OmpDirective::TEAMS_DISTRIBUTE);
+  // 2.11.10 teams-distribute-clause -> teams-clause |
+  //                                    distribute-clause
+  case llvm::omp::Directive::OMPD_teams_distribute: {
     SetContextAllowed(teamsAllowedClauses | distributeAllowedClauses);
     SetContextAllowedOnce(
         teamsAllowedOnceClauses | distributeAllowedOnceClauses);
   } break;
 
-    // 2.11.11 teams-distribute-simd-clause -> teams-clause |
-    //                                         distribute-simd-clause
-  case parser::OmpLoopDirective::Directive::TeamsDistributeSimd: {
-    PushContext(beginDir.source, OmpDirective::TEAMS_DISTRIBUTE_SIMD);
+  // 2.11.11 teams-distribute-simd-clause -> teams-clause |
+  //                                         distribute-simd-clause
+  case llvm::omp::Directive::OMPD_teams_distribute_simd: {
     SetContextAllowed(
         teamsAllowedClauses | distributeAllowedClauses | simdAllowedClauses);
     SetContextAllowedOnce(teamsAllowedOnceClauses |
         distributeAllowedOnceClauses | simdAllowedOnceClauses);
   } break;
 
-    // 2.11.12 target-teams-distribute-clause -> target-clause |
-    //                                           teams-distribute-clause
-  case parser::OmpLoopDirective::Directive::TargetTeamsDistribute: {
-    PushContext(beginDir.source, OmpDirective::TARGET_TEAMS_DISTRIBUTE);
+  // 2.11.12 target-teams-distribute-clause -> target-clause |
+  //                                           teams-distribute-clause
+  case llvm::omp::Directive::OMPD_target_teams_distribute: {
     SetContextAllowed(
         targetAllowedClauses | teamsAllowedClauses | distributeAllowedClauses);
     SetContextAllowedOnce(targetAllowedOnceClauses | teamsAllowedOnceClauses |
         distributeAllowedOnceClauses);
   } break;
 
-    // 2.11.13 target-teams-distribute-simd-clause -> target-clause |
-    //                                                teams-distribute-simd-clause
-  case parser::OmpLoopDirective::Directive::TargetTeamsDistributeSimd: {
-    PushContext(beginDir.source, OmpDirective::TARGET_TEAMS_DISTRIBUTE_SIMD);
+  // 2.11.13 target-teams-distribute-simd-clause -> target-clause |
+  //                                                teams-distribute-simd-clause
+  case llvm::omp::Directive::OMPD_target_teams_distribute_simd: {
     SetContextAllowed(targetAllowedClauses | teamsAllowedClauses |
         distributeAllowedClauses | simdAllowedClauses);
     SetContextAllowed(targetAllowedOnceClauses | teamsAllowedOnceClauses |
         distributeAllowedOnceClauses | simdAllowedOnceClauses);
   } break;
 
-    // 2.11.14 teams-distribute-parallel-do-clause -> teams-clause |
-    //                                                distribute-parallel-do-clause
-  case parser::OmpLoopDirective::Directive::TeamsDistributeParallelDo: {
-    PushContext(beginDir.source, OmpDirective::TEAMS_DISTRIBUTE_PARALLEL_DO);
+  // 2.11.14 teams-distribute-parallel-do-clause -> teams-clause |
+  //                                                distribute-parallel-do-clause
+  case llvm::omp::Directive::OMPD_teams_distribute_parallel_do: {
     SetContextAllowed(teamsAllowedClauses | distributeAllowedClauses |
         parallelAllowedClauses | doAllowedClauses);
     SetContextAllowedOnce(teamsAllowedOnceClauses |
@@ -388,11 +390,9 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
         doAllowedOnceClauses);
   } break;
 
-    // 2.11.15 target-teams-distribute-parallel-do-clause -> target-clause |
-    //                                                       teams-distribute-parallel-do-clause
-  case parser::OmpLoopDirective::Directive::TargetTeamsDistributeParallelDo: {
-    PushContext(
-        beginDir.source, OmpDirective::TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO);
+  // 2.11.15 target-teams-distribute-parallel-do-clause -> target-clause |
+  //                                                       teams-distribute-parallel-do-clause
+  case llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do: {
     SetContextAllowed(targetAllowedClauses | teamsAllowedClauses |
         distributeAllowedClauses | parallelAllowedClauses | doAllowedClauses);
     SetContextAllowedOnce(targetAllowedOnceClauses | teamsAllowedOnceClauses |
@@ -400,11 +400,9 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
         doAllowedOnceClauses);
   } break;
 
-    // 2.11.16 teams-distribute-parallel-do-clause -> teams-clause |
-    //                                                distribute-parallel-do-simd-clause
-  case parser::OmpLoopDirective::Directive::TeamsDistributeParallelDoSimd: {
-    PushContext(
-        beginDir.source, OmpDirective::TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD);
+  // 2.11.16 teams-distribute-parallel-do-clause -> teams-clause |
+  //                                                distribute-parallel-do-simd-clause
+  case llvm::omp::Directive::OMPD_teams_distribute_parallel_do_simd: {
     SetContextAllowed(teamsAllowedClauses | distributeAllowedClauses |
         parallelAllowedClauses | doAllowedClauses | simdAllowedClauses);
     SetContextAllowedOnce(teamsAllowedOnceClauses |
@@ -412,20 +410,18 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
         doAllowedOnceClauses | simdAllowedOnceClauses);
   } break;
 
-  case parser::OmpLoopDirective::Directive::
-      TargetTeamsDistributeParallelDoSimd: {
-    PushContext(beginDir.source,
-        OmpDirective::TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD);
+  case llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do_simd: {
     SetContextAllowed(targetAllowedClauses | teamsAllowedClauses |
         distributeAllowedClauses | parallelAllowedClauses | doAllowedClauses |
         simdAllowedClauses);
     SetContextAllowedOnce(targetAllowedOnceClauses | teamsAllowedOnceClauses |
         distributeAllowedOnceClauses | parallelAllowedOnceClauses |
         doAllowedOnceClauses | simdAllowedOnceClauses);
-  }
+  } break;
 
-  // TODO others
-  break;
+  default:
+    // TODO others
+    break;
   }
 }
 
@@ -439,13 +435,13 @@ void OmpStructureChecker::Enter(const parser::OmpEndLoopDirective &x) {
   switch (dir.v) {
   // 2.7.1 end-do -> END DO [nowait-clause]
   // 2.8.3 end-do-simd -> END DO SIMD [nowait-clause]
-  case parser::OmpLoopDirective::Directive::Do:
-    SetContextDirectiveEnum(OmpDirective::END_DO);
-    SetContextAllowed(OmpClauseSet{OmpClause::NOWAIT});
+  case llvm::omp::Directive::OMPD_do:
+    SetContextDirectiveEnum(llvm::omp::Directive::OMPD_end_do);
+    SetContextAllowed(OmpClauseSet{llvm::omp::Clause::OMPC_nowait});
     break;
-  case parser::OmpLoopDirective::Directive::DoSimd:
-    SetContextDirectiveEnum(OmpDirective::END_DO_SIMD);
-    SetContextAllowed(OmpClauseSet{OmpClause::NOWAIT});
+  case llvm::omp::Directive::OMPD_do_simd:
+    SetContextDirectiveEnum(llvm::omp::Directive::OMPD_end_do_simd);
+    SetContextAllowed(OmpClauseSet{llvm::omp::Clause::OMPC_nowait});
     break;
   default:
     // no clauses are allowed
@@ -459,6 +455,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
   const auto &beginDir{
       CheckMatching<parser::OmpBlockDirective>(beginBlockDir, endBlockDir)};
 
+  PushContext(beginDir.source, beginDir.v);
   switch (beginDir.v) {
   // 2.5 parallel-clause -> if-clause |
   //                        num-threads-clause |
@@ -469,25 +466,22 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
   //                        copyin-clause |
   //                        reduction-clause |
   //                        proc-bind-clause
-  case parser::OmpBlockDirective::Directive::Parallel: {
+  case llvm::omp::Directive::OMPD_parallel: {
     // reserve for nesting check
-    PushContext(beginDir.source, OmpDirective::PARALLEL);
     SetContextAllowed(parallelAllowedClauses);
     SetContextAllowedOnce(parallelAllowedOnceClauses);
   } break;
   // 2.7.3 single-clause -> private-clause |
   //                        firstprivate-clause
-  case parser::OmpBlockDirective::Directive::Single:
-    PushContext(beginDir.source, OmpDirective::SINGLE);
-    SetContextAllowed({OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE});
+  case llvm::omp::Directive::OMPD_single:
+    SetContextAllowed({llvm::omp::Clause::OMPC_private,
+        llvm::omp::Clause::OMPC_firstprivate});
     break;
   // 2.7.4 workshare (no clauses are allowed)
-  case parser::OmpBlockDirective::Directive::Workshare:
-    PushContext(beginDir.source, OmpDirective::WORKSHARE);
+  case llvm::omp::Directive::OMPD_workshare:
     break;
   // 2.11.3 parallel-workshare-clause -> parallel-clause
-  case parser::OmpBlockDirective::Directive::ParallelWorkshare: {
-    PushContext(beginDir.source, OmpDirective::PARALLEL_WORKSHARE);
+  case llvm::omp::Directive::OMPD_parallel_workshare: {
     SetContextAllowed(parallelAllowedClauses);
     SetContextAllowedOnce(parallelAllowedOnceClauses);
   } break;
@@ -501,14 +495,14 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
     //                      shared-clause |
     //                      depend-clause |
     //                      priority-clause
-  case parser::OmpBlockDirective::Directive::Task: {
-    PushContext(beginDir.source, OmpDirective::TASK);
-    OmpClauseSet allowed{OmpClause::UNTIED, OmpClause::DEFAULT,
-        OmpClause::MERGEABLE, OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE,
-        OmpClause::SHARED, OmpClause::DEPEND};
+  case llvm::omp::Directive::OMPD_task: {
+    OmpClauseSet allowed{llvm::omp::Clause::OMPC_untied,
+        llvm::omp::Clause::OMPC_default, llvm::omp::Clause::OMPC_mergeable,
+        llvm::omp::Clause::OMPC_private, llvm::omp::Clause::OMPC_firstprivate,
+        llvm::omp::Clause::OMPC_shared, llvm::omp::Clause::OMPC_depend};
     SetContextAllowed(allowed);
-    OmpClauseSet allowedOnce{
-        OmpClause::IF, OmpClause::FINAL, OmpClause::PRIORITY};
+    OmpClauseSet allowedOnce{llvm::omp::Clause::OMPC_if,
+        llvm::omp::Clause::OMPC_final, llvm::omp::Clause::OMPC_priority};
     SetContextAllowedOnce(allowedOnce);
   } break;
   // 2.10.4 target-clause -> if-clause |
@@ -520,8 +514,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
   //                         defaultmap-clause |
   //                         nowait-clause |
   //                         depend-clause
-  case parser::OmpBlockDirective::Directive::Target: {
-    PushContext(beginDir.source, OmpDirective::TARGET);
+  case llvm::omp::Directive::OMPD_target: {
     SetContextAllowed(targetAllowedClauses);
     SetContextAllowedOnce(targetAllowedOnceClauses);
   } break;
@@ -532,40 +525,35 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
   //                        firstprivate-clause |
   //                        shared-clause |
   //                        reduction-clause
-  case parser::OmpBlockDirective::Directive::Teams: {
-    PushContext(beginDir.source, OmpDirective::TEAMS);
+  case llvm::omp::Directive::OMPD_teams: {
     SetContextAllowed(teamsAllowedClauses);
     SetContextAllowedOnce(teamsAllowedOnceClauses);
   } break;
-    // 2.11.9 target-teams -> target-clause |
-    //                        teams-clause
-  case parser::OmpBlockDirective::Directive::TargetTeams: {
-    PushContext(beginDir.source, OmpDirective::TARGET_TEAMS);
+  // 2.11.9 target-teams -> target-clause |
+  //                        teams-clause
+  case llvm::omp::Directive::OMPD_target_teams: {
     SetContextAllowed(targetAllowedClauses | teamsAllowedClauses);
     SetContextAllowedOnce(targetAllowedOnceClauses | teamsAllowedOnceClauses);
   } break;
-    // 2.10.1 target-data-clause -> if-clause |
-    //                              device-clause |
-    //                              map-clause |
-    //                              use-device-ptr-clause
-  case parser::OmpBlockDirective::Directive::TargetData: {
-    PushContext(beginDir.source, OmpDirective::TARGET_DATA);
-    OmpClauseSet allowed{
-        OmpClause::IF, OmpClause::MAP, OmpClause::USE_DEVICE_PTR};
+  // 2.10.1 target-data-clause -> if-clause |
+  //                              device-clause |
+  //                              map-clause |
+  //                              use-device-ptr-clause
+  case llvm::omp::Directive::OMPD_target_data: {
+    OmpClauseSet allowed{llvm::omp::Clause::OMPC_if,
+        llvm::omp::Clause::OMPC_map, llvm::omp::Clause::OMPC_use_device_ptr};
     SetContextAllowed(allowed);
-    SetContextAllowedOnce({OmpClause::DEVICE});
-    SetContextRequired({OmpClause::MAP});
+    SetContextAllowedOnce({llvm::omp::Clause::OMPC_device});
+    SetContextRequired({llvm::omp::Clause::OMPC_map});
   } break;
-    // 2.13.1 master (no clauses are allowed)
-  case parser::OmpBlockDirective::Directive::Master:
-    PushContext(beginDir.source, OmpDirective::MASTER);
+  // 2.13.1 master (no clauses are allowed)
+  case llvm::omp::Directive::OMPD_master:
     break;
-    // 2.11.5 target-parallel-clause -> target-clause |
-    //                                  parallel-clause
-  case parser::OmpBlockDirective::Directive::TargetParallel: {
-    PushContext(beginDir.source, OmpDirective::TARGET_PARALLEL);
-    SetContextAllowed(
-        (targetAllowedClauses | parallelAllowedClauses) - OmpClause::COPYIN);
+  // 2.11.5 target-parallel-clause -> target-clause |
+  //                                  parallel-clause
+  case llvm::omp::Directive::OMPD_target_parallel: {
+    SetContextAllowed((targetAllowedClauses | parallelAllowedClauses) -
+        llvm::omp::Clause::OMPC_copyin);
     SetContextAllowedOnce(
         targetAllowedOnceClauses | parallelAllowedOnceClauses);
   } break;
@@ -586,22 +574,24 @@ void OmpStructureChecker::Enter(const parser::OpenMPSectionsConstruct &x) {
   const auto &beginDir{CheckMatching<parser::OmpSectionsDirective>(
       beginSectionsDir, endSectionsDir)};
 
+  PushContext(beginDir.source, beginDir.v);
   switch (beginDir.v) {
   // 2.7.2 sections-clause -> private-clause |
   //                          firstprivate-clause |
   //                          lastprivate-clause |
   //                          reduction-clause
-  case parser::OmpSectionsDirective::Directive::Sections: {
-    PushContext(beginDir.source, OmpDirective::SECTIONS);
+  case llvm::omp::Directive::OMPD_sections: {
     SetContextAllowed(sectionsAllowedClauses);
   } break;
     // 2.11.2 -> parallel-sections-clause -> parallel-clause |
     //                                       sections-clause
-  case parser::OmpSectionsDirective::Directive::ParallelSections: {
-    PushContext(beginDir.source, OmpDirective::PARALLEL_SECTIONS);
+  case llvm::omp::Directive::OMPD_parallel_sections: {
     SetContextAllowed(parallelAllowedClauses | sectionsAllowedClauses);
     SetContextAllowedOnce(parallelAllowedOnceClauses);
   } break;
+  default:
+    // TODO others
+    break;
   }
 }
 
@@ -614,9 +604,9 @@ void OmpStructureChecker::Enter(const parser::OmpEndSectionsDirective &x) {
   ResetPartialContext(dir.source);
   switch (dir.v) {
     // 2.7.2 end-sections -> END SECTIONS [nowait-clause]
-  case parser::OmpSectionsDirective::Directive::Sections:
-    SetContextDirectiveEnum(OmpDirective::END_SECTIONS);
-    SetContextAllowed(OmpClauseSet{OmpClause::NOWAIT});
+  case llvm::omp::Directive::OMPD_sections:
+    SetContextDirectiveEnum(llvm::omp::Directive::OMPD_end_sections);
+    SetContextAllowed(OmpClauseSet{llvm::omp::Clause::OMPC_nowait});
     break;
   default:
     // no clauses are allowed
@@ -626,18 +616,19 @@ void OmpStructureChecker::Enter(const parser::OmpEndSectionsDirective &x) {
 
 void OmpStructureChecker::Enter(const parser::OpenMPDeclareSimdConstruct &x) {
   const auto &dir{std::get<parser::Verbatim>(x.t)};
-  PushContext(dir.source, OmpDirective::DECLARE_SIMD);
+  PushContext(dir.source, llvm::omp::Directive::OMPD_declare_simd);
   // 2.8.2 declare-simd-clause -> simdlen-clause |
   //                              linear-clause |
   //                              aligned-clause |
   //                              uniform-clause |
   //                              inbranch-clause |
   //                              notinbranch-clause
-  OmpClauseSet allowed{
-      OmpClause::LINEAR, OmpClause::ALIGNED, OmpClause::UNIFORM};
+  OmpClauseSet allowed{llvm::omp::Clause::OMPC_linear,
+      llvm::omp::Clause::OMPC_aligned, llvm::omp::Clause::OMPC_uniform};
   SetContextAllowed(allowed);
-  SetContextAllowedOnce({OmpClause::SIMDLEN});
-  SetContextAllowedExclusive({OmpClause::INBRANCH, OmpClause::NOTINBRANCH});
+  SetContextAllowedOnce({llvm::omp::Clause::OMPC_simdlen});
+  SetContextAllowedExclusive(
+      {llvm::omp::Clause::OMPC_inbranch, llvm::omp::Clause::OMPC_notinbranch});
 }
 
 void OmpStructureChecker::Leave(const parser::OpenMPDeclareSimdConstruct &) {
@@ -646,10 +637,11 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareSimdConstruct &) {
 
 void OmpStructureChecker::Enter(const parser::OpenMPDeclareTargetConstruct &x) {
   const auto &dir{std::get<parser::Verbatim>(x.t)};
-  PushContext(dir.source, OmpDirective::DECLARE_TARGET);
+  PushContext(dir.source, llvm::omp::Directive::OMPD_declare_target);
   const auto &spec{std::get<parser::OmpDeclareTargetSpecifier>(x.t)};
   if (std::holds_alternative<parser::OmpDeclareTargetWithClause>(spec.u)) {
-    SetContextAllowed(OmpClauseSet{OmpClause::TO, OmpClause::LINK});
+    SetContextAllowed(
+        OmpClauseSet{llvm::omp::Clause::OMPC_to, llvm::omp::Clause::OMPC_link});
   }
 }
 
@@ -660,55 +652,56 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &) {
 void OmpStructureChecker::Enter(
     const parser::OpenMPSimpleStandaloneConstruct &x) {
   const auto &dir{std::get<parser::OmpSimpleStandaloneDirective>(x.t)};
+  PushContext(dir.source, dir.v);
   switch (dir.v) {
-  case parser::OmpSimpleStandaloneDirective::Directive::Barrier: {
+  case llvm::omp::Directive::OMPD_barrier: {
     // 2.13.3 barrier
-    PushContext(dir.source, OmpDirective::BARRIER);
   } break;
-  case parser::OmpSimpleStandaloneDirective::Directive::Taskwait: {
+  case llvm::omp::Directive::OMPD_taskwait: {
     // 2.13.4 taskwait
-    PushContext(dir.source, OmpDirective::TASKWAIT);
   } break;
-  case parser::OmpSimpleStandaloneDirective::Directive::Taskyield: {
+  case llvm::omp::Directive::OMPD_taskyield: {
     // 2.9.4 taskyield
-    PushContext(dir.source, OmpDirective::TASKYIELD);
   } break;
-  case parser::OmpSimpleStandaloneDirective::Directive::TargetEnterData: {
+  case llvm::omp::Directive::OMPD_target_enter_data: {
     // 2.10.2 target-enter-data-clause -> if-clause |
     //                                    device-clause |
     //                                    map-clause |
     //                                    depend-clause |
     //                                    nowait-clause
-    PushContext(dir.source, OmpDirective::TARGET_ENTER_DATA);
-    OmpClauseSet allowed{OmpClause::MAP, OmpClause::DEPEND, OmpClause::NOWAIT};
+    OmpClauseSet allowed{llvm::omp::Clause::OMPC_map,
+        llvm::omp::Clause::OMPC_depend, llvm::omp::Clause::OMPC_nowait};
     SetContextAllowed(allowed);
-    OmpClauseSet allowedOnce{OmpClause::DEVICE, OmpClause::IF};
+    OmpClauseSet allowedOnce{
+        llvm::omp::Clause::OMPC_device, llvm::omp::Clause::OMPC_if};
     SetContextAllowedOnce(allowedOnce);
-    SetContextRequired({OmpClause::MAP});
+    SetContextRequired({llvm::omp::Clause::OMPC_map});
   } break;
-  case parser::OmpSimpleStandaloneDirective::Directive::TargetExitData: {
+  case llvm::omp::Directive::OMPD_target_exit_data: {
     // 2.10.3  target-enter-data-clause -> if-clause |
     //                                     device-clause |
     //                                     map-clause |
     //                                     depend-clause |
     //                                     nowait-clause
-    PushContext(dir.source, OmpDirective::TARGET_EXIT_DATA);
-    OmpClauseSet allowed{OmpClause::MAP, OmpClause::DEPEND, OmpClause::NOWAIT};
+    OmpClauseSet allowed{llvm::omp::Clause::OMPC_map,
+        llvm::omp::Clause::OMPC_depend, llvm::omp::Clause::OMPC_nowait};
     SetContextAllowed(allowed);
-    OmpClauseSet allowedOnce{OmpClause::DEVICE, OmpClause::IF};
+    OmpClauseSet allowedOnce{
+        llvm::omp::Clause::OMPC_device, llvm::omp::Clause::OMPC_if};
     SetContextAllowedOnce(allowedOnce);
-    SetContextRequired({OmpClause::MAP});
+    SetContextRequired({llvm::omp::Clause::OMPC_map});
   } break;
-  case parser::OmpSimpleStandaloneDirective::Directive::TargetUpdate: {
+  case llvm::omp::Directive::OMPD_target_update: {
     // 2.10.5 target-update
-    PushContext(dir.source, OmpDirective::TARGET_UPDATE);
   } break;
-  case parser::OmpSimpleStandaloneDirective::Directive::Ordered: {
+  case llvm::omp::Directive::OMPD_ordered: {
     // 2.13.8 ordered-construct-clause -> depend-clause
-    PushContext(dir.source, OmpDirective::ORDERED);
-    OmpClauseSet allowed{OmpClause::DEPEND};
+    OmpClauseSet allowed{llvm::omp::Clause::OMPC_depend};
     SetContextAllowed(allowed);
   } break;
+  default:
+    // TODO others
+    break;
   }
 }
 
@@ -719,7 +712,7 @@ void OmpStructureChecker::Leave(
 
 void OmpStructureChecker::Enter(const parser::OpenMPFlushConstruct &x) {
   const auto &dir{std::get<parser::Verbatim>(x.t)};
-  PushContext(dir.source, OmpDirective::FLUSH);
+  PushContext(dir.source, llvm::omp::Directive::OMPD_flush);
 }
 
 void OmpStructureChecker::Leave(const parser::OpenMPFlushConstruct &) {
@@ -728,7 +721,7 @@ void OmpStructureChecker::Leave(const parser::OpenMPFlushConstruct &) {
 
 void OmpStructureChecker::Enter(const parser::OpenMPCancelConstruct &x) {
   const auto &dir{std::get<parser::Verbatim>(x.t)};
-  PushContext(dir.source, OmpDirective::CANCEL);
+  PushContext(dir.source, llvm::omp::Directive::OMPD_cancel);
 }
 
 void OmpStructureChecker::Leave(const parser::OpenMPCancelConstruct &) {
@@ -738,7 +731,7 @@ void OmpStructureChecker::Leave(const parser::OpenMPCancelConstruct &) {
 void OmpStructureChecker::Enter(
     const parser::OpenMPCancellationPointConstruct &x) {
   const auto &dir{std::get<parser::Verbatim>(x.t)};
-  PushContext(dir.source, OmpDirective::CANCELLATION_POINT);
+  PushContext(dir.source, llvm::omp::Directive::OMPD_cancellation_point);
 }
 
 void OmpStructureChecker::Leave(
@@ -752,17 +745,17 @@ void OmpStructureChecker::Enter(const parser::OmpEndBlockDirective &x) {
   switch (dir.v) {
   // 2.7.3 end-single-clause -> copyprivate-clause |
   //                            nowait-clause
-  case parser::OmpBlockDirective::Directive::Single: {
-    SetContextDirectiveEnum(OmpDirective::END_SINGLE);
-    OmpClauseSet allowed{OmpClause::COPYPRIVATE};
+  case llvm::omp::Directive::OMPD_single: {
+    SetContextDirectiveEnum(llvm::omp::Directive::OMPD_end_single);
+    OmpClauseSet allowed{llvm::omp::Clause::OMPC_copyprivate};
     SetContextAllowed(allowed);
-    OmpClauseSet allowedOnce{OmpClause::NOWAIT};
+    OmpClauseSet allowedOnce{llvm::omp::Clause::OMPC_nowait};
     SetContextAllowedOnce(allowedOnce);
   } break;
   // 2.7.4 end-workshare -> END WORKSHARE [nowait-clause]
-  case parser::OmpBlockDirective::Directive::Workshare:
-    SetContextDirectiveEnum(OmpDirective::END_WORKSHARE);
-    SetContextAllowed(OmpClauseSet{OmpClause::NOWAIT});
+  case llvm::omp::Directive::OMPD_workshare:
+    SetContextDirectiveEnum(llvm::omp::Directive::OMPD_end_workshare);
+    SetContextAllowed(OmpClauseSet{llvm::omp::Clause::OMPC_nowait});
     break;
   default:
     // no clauses are allowed
@@ -772,13 +765,13 @@ void OmpStructureChecker::Enter(const parser::OmpEndBlockDirective &x) {
 
 void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
   // 2.7 Loop Construct Restriction
-  if (doSet.test(GetContext().directive)) {
-    if (auto *clause{FindClause(OmpClause::SCHEDULE)}) {
+  if (llvm::omp::doSet.test(GetContext().directive)) {
+    if (auto *clause{FindClause(llvm::omp::Clause::OMPC_schedule)}) {
       // only one schedule clause is allowed
       const auto &schedClause{std::get<parser::OmpScheduleClause>(clause->u)};
       if (ScheduleModifierHasType(schedClause,
               parser::OmpScheduleModifierType::ModType::Nonmonotonic)) {
-        if (FindClause(OmpClause::ORDERED)) {
+        if (FindClause(llvm::omp::Clause::OMPC_ordered)) {
           context_.Say(clause->source,
               "The NONMONOTONIC modifier cannot be specified "
               "if an ORDERED clause is specified"_err_en_US);
@@ -792,19 +785,19 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
       }
     }
 
-    if (auto *clause{FindClause(OmpClause::ORDERED)}) {
+    if (auto *clause{FindClause(llvm::omp::Clause::OMPC_ordered)}) {
       // only one ordered clause is allowed
       const auto &orderedClause{
           std::get<parser::OmpClause::Ordered>(clause->u)};
 
       if (orderedClause.v) {
-        if (FindClause(OmpClause::LINEAR)) {
+        if (FindClause(llvm::omp::Clause::OMPC_linear)) {
           context_.Say(clause->source,
               "A loop directive may not have both a LINEAR clause and "
               "an ORDERED clause with a parameter"_err_en_US);
         }
 
-        if (auto *clause2{FindClause(OmpClause::COLLAPSE)}) {
+        if (auto *clause2{FindClause(llvm::omp::Clause::OMPC_collapse)}) {
           const auto &collapseClause{
               std::get<parser::OmpClause::Collapse>(clause2->u)};
           // ordered and collapse both have parameters
@@ -826,9 +819,9 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
   } // doSet
 
   // 2.8.1 Simd Construct Restriction
-  if (simdSet.test(GetContext().directive)) {
-    if (auto *clause{FindClause(OmpClause::SIMDLEN)}) {
-      if (auto *clause2{FindClause(OmpClause::SAFELEN)}) {
+  if (llvm::omp::simdSet.test(GetContext().directive)) {
+    if (auto *clause{FindClause(llvm::omp::Clause::OMPC_simdlen)}) {
+      if (auto *clause2{FindClause(llvm::omp::Clause::OMPC_safelen)}) {
         const auto &simdlenClause{
             std::get<parser::OmpClause::Simdlen>(clause->u)};
         const auto &safelenClause{
@@ -850,9 +843,9 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
   } // SIMD
 
   // 2.7.3 Single Construct Restriction
-  if (GetContext().directive == OmpDirective::END_SINGLE) {
-    if (auto *clause{FindClause(OmpClause::COPYPRIVATE)}) {
-      if (FindClause(OmpClause::NOWAIT)) {
+  if (GetContext().directive == llvm::omp::Directive::OMPD_end_single) {
+    if (auto *clause{FindClause(llvm::omp::Clause::OMPC_copyprivate)}) {
+      if (FindClause(llvm::omp::Clause::OMPC_nowait)) {
         context_.Say(clause->source,
             "The COPYPRIVATE clause must not be used with "
             "the NOWAIT clause"_err_en_US);
@@ -861,7 +854,7 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
   }
 
   GetContext().requiredClauses.IterateOverMembers(
-      [this](OmpClause c) { CheckRequired(c); });
+      [this](llvm::omp::Clause c) { CheckRequired(c); });
 }
 
 void OmpStructureChecker::Enter(const parser::OmpClause &x) {
@@ -869,80 +862,80 @@ void OmpStructureChecker::Enter(const parser::OmpClause &x) {
 }
 
 void OmpStructureChecker::Enter(const parser::OmpNowait &) {
-  CheckAllowed(OmpClause::NOWAIT);
+  CheckAllowed(llvm::omp::Clause::OMPC_nowait);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::Inbranch &) {
-  CheckAllowed(OmpClause::INBRANCH);
+  CheckAllowed(llvm::omp::Clause::OMPC_inbranch);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::Mergeable &) {
-  CheckAllowed(OmpClause::MERGEABLE);
+  CheckAllowed(llvm::omp::Clause::OMPC_mergeable);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::Nogroup &) {
-  CheckAllowed(OmpClause::NOGROUP);
+  CheckAllowed(llvm::omp::Clause::OMPC_nogroup);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::Notinbranch &) {
-  CheckAllowed(OmpClause::NOTINBRANCH);
+  CheckAllowed(llvm::omp::Clause::OMPC_notinbranch);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::Untied &) {
-  CheckAllowed(OmpClause::UNTIED);
+  CheckAllowed(llvm::omp::Clause::OMPC_untied);
 }
 
 void OmpStructureChecker::Enter(const parser::OmpClause::Collapse &x) {
-  CheckAllowed(OmpClause::COLLAPSE);
+  CheckAllowed(llvm::omp::Clause::OMPC_collapse);
   // collapse clause must have a parameter
-  RequiresConstantPositiveParameter(OmpClause::COLLAPSE, x.v);
+  RequiresConstantPositiveParameter(llvm::omp::Clause::OMPC_collapse, x.v);
 }
 
 void OmpStructureChecker::Enter(const parser::OmpClause::Copyin &) {
-  CheckAllowed(OmpClause::COPYIN);
+  CheckAllowed(llvm::omp::Clause::OMPC_copyin);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::Copyprivate &) {
-  CheckAllowed(OmpClause::COPYPRIVATE);
+  CheckAllowed(llvm::omp::Clause::OMPC_copyprivate);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::Device &) {
-  CheckAllowed(OmpClause::DEVICE);
+  CheckAllowed(llvm::omp::Clause::OMPC_device);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::DistSchedule &) {
-  CheckAllowed(OmpClause::DIST_SCHEDULE);
+  CheckAllowed(llvm::omp::Clause::OMPC_dist_schedule);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::Final &) {
-  CheckAllowed(OmpClause::FINAL);
+  CheckAllowed(llvm::omp::Clause::OMPC_final);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::Firstprivate &) {
-  CheckAllowed(OmpClause::FIRSTPRIVATE);
+  CheckAllowed(llvm::omp::Clause::OMPC_firstprivate);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::From &) {
-  CheckAllowed(OmpClause::FROM);
+  CheckAllowed(llvm::omp::Clause::OMPC_from);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::Grainsize &x) {
-  CheckAllowed(OmpClause::GRAINSIZE);
-  RequiresPositiveParameter(OmpClause::GRAINSIZE, x.v);
+  CheckAllowed(llvm::omp::Clause::OMPC_grainsize);
+  RequiresPositiveParameter(llvm::omp::Clause::OMPC_grainsize, x.v);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::Lastprivate &) {
-  CheckAllowed(OmpClause::LASTPRIVATE);
+  CheckAllowed(llvm::omp::Clause::OMPC_lastprivate);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::NumTasks &x) {
-  CheckAllowed(OmpClause::NUM_TASKS);
-  RequiresPositiveParameter(OmpClause::NUM_TASKS, x.v);
+  CheckAllowed(llvm::omp::Clause::OMPC_num_tasks);
+  RequiresPositiveParameter(llvm::omp::Clause::OMPC_num_tasks, x.v);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::NumTeams &x) {
-  CheckAllowed(OmpClause::NUM_TEAMS);
-  RequiresPositiveParameter(OmpClause::NUM_TEAMS, x.v);
+  CheckAllowed(llvm::omp::Clause::OMPC_num_teams);
+  RequiresPositiveParameter(llvm::omp::Clause::OMPC_num_teams, x.v);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::NumThreads &x) {
-  CheckAllowed(OmpClause::NUM_THREADS);
-  RequiresPositiveParameter(OmpClause::NUM_THREADS, x.v);
+  CheckAllowed(llvm::omp::Clause::OMPC_num_threads);
+  RequiresPositiveParameter(llvm::omp::Clause::OMPC_num_threads, x.v);
   // if parameter is variable, defer to Expression Analysis
 }
 
 void OmpStructureChecker::Enter(const parser::OmpClause::Ordered &x) {
-  CheckAllowed(OmpClause::ORDERED);
+  CheckAllowed(llvm::omp::Clause::OMPC_ordered);
   // the parameter of ordered clause is optional
   if (const auto &expr{x.v}) {
-    RequiresConstantPositiveParameter(OmpClause::ORDERED, *expr);
+    RequiresConstantPositiveParameter(llvm::omp::Clause::OMPC_ordered, *expr);
 
     // 2.8.3 Loop SIMD Construct Restriction
-    if (doSimdSet.test(GetContext().directive)) {
+    if (llvm::omp::doSimdSet.test(GetContext().directive)) {
       context_.Say(GetContext().clauseSource,
           "No ORDERED clause with a parameter can be specified "
           "on the %s directive"_err_en_US,
@@ -951,45 +944,45 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Ordered &x) {
   }
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::Priority &x) {
-  CheckAllowed(OmpClause::PRIORITY);
-  RequiresPositiveParameter(OmpClause::PRIORITY, x.v);
+  CheckAllowed(llvm::omp::Clause::OMPC_priority);
+  RequiresPositiveParameter(llvm::omp::Clause::OMPC_priority, x.v);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::Private &) {
-  CheckAllowed(OmpClause::PRIVATE);
+  CheckAllowed(llvm::omp::Clause::OMPC_private);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::Safelen &x) {
-  CheckAllowed(OmpClause::SAFELEN);
-  RequiresConstantPositiveParameter(OmpClause::SAFELEN, x.v);
+  CheckAllowed(llvm::omp::Clause::OMPC_safelen);
+  RequiresConstantPositiveParameter(llvm::omp::Clause::OMPC_safelen, x.v);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::Shared &) {
-  CheckAllowed(OmpClause::SHARED);
+  CheckAllowed(llvm::omp::Clause::OMPC_shared);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::Simdlen &x) {
-  CheckAllowed(OmpClause::SIMDLEN);
-  RequiresConstantPositiveParameter(OmpClause::SIMDLEN, x.v);
+  CheckAllowed(llvm::omp::Clause::OMPC_simdlen);
+  RequiresConstantPositiveParameter(llvm::omp::Clause::OMPC_simdlen, x.v);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::ThreadLimit &x) {
-  CheckAllowed(OmpClause::THREAD_LIMIT);
-  RequiresPositiveParameter(OmpClause::THREAD_LIMIT, x.v);
+  CheckAllowed(llvm::omp::Clause::OMPC_thread_limit);
+  RequiresPositiveParameter(llvm::omp::Clause::OMPC_thread_limit, x.v);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::To &) {
-  CheckAllowed(OmpClause::TO);
+  CheckAllowed(llvm::omp::Clause::OMPC_to);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::Link &) {
-  CheckAllowed(OmpClause::LINK);
+  CheckAllowed(llvm::omp::Clause::OMPC_link);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::Uniform &) {
-  CheckAllowed(OmpClause::UNIFORM);
+  CheckAllowed(llvm::omp::Clause::OMPC_uniform);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::UseDevicePtr &) {
-  CheckAllowed(OmpClause::USE_DEVICE_PTR);
+  CheckAllowed(llvm::omp::Clause::OMPC_use_device_ptr);
 }
 void OmpStructureChecker::Enter(const parser::OmpClause::IsDevicePtr &) {
-  CheckAllowed(OmpClause::IS_DEVICE_PTR);
+  CheckAllowed(llvm::omp::Clause::OMPC_is_device_ptr);
 }
 
 void OmpStructureChecker::Enter(const parser::OmpAlignedClause &x) {
-  CheckAllowed(OmpClause::ALIGNED);
+  CheckAllowed(llvm::omp::Clause::OMPC_aligned);
 
   if (const auto &expr{
           std::get<std::optional<parser::ScalarIntConstantExpr>>(x.t)}) {
@@ -1004,10 +997,10 @@ void OmpStructureChecker::Enter(const parser::OmpAlignedClause &x) {
   // 2.8.1 TODO: list-item attribute check
 }
 void OmpStructureChecker::Enter(const parser::OmpDefaultClause &) {
-  CheckAllowed(OmpClause::DEFAULT);
+  CheckAllowed(llvm::omp::Clause::OMPC_default);
 }
 void OmpStructureChecker::Enter(const parser::OmpDefaultmapClause &x) {
-  CheckAllowed(OmpClause::DEFAULTMAP);
+  CheckAllowed(llvm::omp::Clause::OMPC_defaultmap);
   using VariableCategory = parser::OmpDefaultmapClause::VariableCategory;
   if (!std::get<std::optional<VariableCategory>>(x.t)) {
     context_.Say(GetContext().clauseSource,
@@ -1016,22 +1009,26 @@ void OmpStructureChecker::Enter(const parser::OmpDefaultmapClause &x) {
   }
 }
 void OmpStructureChecker::Enter(const parser::OmpDependClause &) {
-  CheckAllowed(OmpClause::DEPEND);
+  CheckAllowed(llvm::omp::Clause::OMPC_depend);
 }
 
 void OmpStructureChecker::Enter(const parser::OmpIfClause &x) {
-  CheckAllowed(OmpClause::IF);
+  CheckAllowed(llvm::omp::Clause::OMPC_if);
 
   using dirNameModifier = parser::OmpIfClause::DirectiveNameModifier;
   static std::unordered_map<dirNameModifier, OmpDirectiveSet>
-      dirNameModifierMap{{dirNameModifier::Parallel, parallelSet},
-          {dirNameModifier::Target, targetSet},
-          {dirNameModifier::TargetEnterData, {OmpDirective::TARGET_ENTER_DATA}},
-          {dirNameModifier::TargetExitData, {OmpDirective::TARGET_EXIT_DATA}},
-          {dirNameModifier::TargetData, {OmpDirective::TARGET_DATA}},
-          {dirNameModifier::TargetUpdate, {OmpDirective::TARGET_UPDATE}},
-          {dirNameModifier::Task, {OmpDirective::TASK}},
-          {dirNameModifier::Taskloop, taskloopSet}};
+      dirNameModifierMap{{dirNameModifier::Parallel, llvm::omp::parallelSet},
+          {dirNameModifier::Target, llvm::omp::targetSet},
+          {dirNameModifier::TargetEnterData,
+              {llvm::omp::Directive::OMPD_target_enter_data}},
+          {dirNameModifier::TargetExitData,
+              {llvm::omp::Directive::OMPD_target_exit_data}},
+          {dirNameModifier::TargetData,
+              {llvm::omp::Directive::OMPD_target_data}},
+          {dirNameModifier::TargetUpdate,
+              {llvm::omp::Directive::OMPD_target_update}},
+          {dirNameModifier::Task, {llvm::omp::Directive::OMPD_task}},
+          {dirNameModifier::Taskloop, llvm::omp::taskloopSet}};
   if (const auto &directiveName{
           std::get<std::optional<dirNameModifier>>(x.t)}) {
     auto search{dirNameModifierMap.find(*directiveName)};
@@ -1049,10 +1046,10 @@ void OmpStructureChecker::Enter(const parser::OmpIfClause &x) {
 }
 
 void OmpStructureChecker::Enter(const parser::OmpLinearClause &x) {
-  CheckAllowed(OmpClause::LINEAR);
+  CheckAllowed(llvm::omp::Clause::OMPC_linear);
 
   // 2.7 Loop Construct Restriction
-  if ((doSet | simdSet).test(GetContext().directive)) {
+  if ((llvm::omp::doSet | llvm::omp::simdSet).test(GetContext().directive)) {
     if (std::holds_alternative<parser::OmpLinearClause::WithModifier>(x.u)) {
       context_.Say(GetContext().clauseSource,
           "A modifier may not be specified in a LINEAR clause "
@@ -1062,18 +1059,18 @@ void OmpStructureChecker::Enter(const parser::OmpLinearClause &x) {
   }
 }
 void OmpStructureChecker::Enter(const parser::OmpMapClause &x) {
-  CheckAllowed(OmpClause::MAP);
+  CheckAllowed(llvm::omp::Clause::OMPC_map);
   if (const auto &maptype{std::get<std::optional<parser::OmpMapType>>(x.t)}) {
     using Type = parser::OmpMapType::Type;
     const Type &type{std::get<Type>(maptype->t)};
     switch (GetContext().directive) {
-    case OmpDirective::TARGET:
-    case OmpDirective::TARGET_TEAMS:
-    case OmpDirective::TARGET_TEAMS_DISTRIBUTE:
-    case OmpDirective::TARGET_TEAMS_DISTRIBUTE_SIMD:
-    case OmpDirective::TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
-    case OmpDirective::TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
-    case OmpDirective::TARGET_DATA: {
+    case llvm::omp::Directive::OMPD_target:
+    case llvm::omp::Directive::OMPD_target_teams:
+    case llvm::omp::Directive::OMPD_target_teams_distribute:
+    case llvm::omp::Directive::OMPD_target_teams_distribute_simd:
+    case llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do:
+    case llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do_simd:
+    case llvm::omp::Directive::OMPD_target_data: {
       if (type != Type::To && type != Type::From && type != Type::Tofrom &&
           type != Type::Alloc) {
         context_.Say(GetContext().clauseSource,
@@ -1082,7 +1079,7 @@ void OmpStructureChecker::Enter(const parser::OmpMapClause &x) {
             ContextDirectiveAsFortran());
       }
     } break;
-    case OmpDirective::TARGET_ENTER_DATA: {
+    case llvm::omp::Directive::OMPD_target_enter_data: {
       if (type != Type::To && type != Type::Alloc) {
         context_.Say(GetContext().clauseSource,
             "Only the TO or ALLOC map types are permitted "
@@ -1090,7 +1087,7 @@ void OmpStructureChecker::Enter(const parser::OmpMapClause &x) {
             ContextDirectiveAsFortran());
       }
     } break;
-    case OmpDirective::TARGET_EXIT_DATA: {
+    case llvm::omp::Directive::OMPD_target_exit_data: {
       if (type != Type::Delete && type != Type::Release && type != Type::From) {
         context_.Say(GetContext().clauseSource,
             "Only the FROM, RELEASE, or DELETE map types are permitted "
@@ -1104,10 +1101,10 @@ void OmpStructureChecker::Enter(const parser::OmpMapClause &x) {
   }
 }
 void OmpStructureChecker::Enter(const parser::OmpProcBindClause &) {
-  CheckAllowed(OmpClause::PROC_BIND);
+  CheckAllowed(llvm::omp::Clause::OMPC_proc_bind);
 }
 void OmpStructureChecker::Enter(const parser::OmpReductionClause &) {
-  CheckAllowed(OmpClause::REDUCTION);
+  CheckAllowed(llvm::omp::Clause::OMPC_reduction);
 }
 
 bool OmpStructureChecker::ScheduleModifierHasType(
@@ -1128,10 +1125,10 @@ bool OmpStructureChecker::ScheduleModifierHasType(
   return false;
 }
 void OmpStructureChecker::Enter(const parser::OmpScheduleClause &x) {
-  CheckAllowed(OmpClause::SCHEDULE);
+  CheckAllowed(llvm::omp::Clause::OMPC_schedule);
 
   // 2.7 Loop Construct Restriction
-  if (doSet.test(GetContext().directive)) {
+  if (llvm::omp::doSet.test(GetContext().directive)) {
     const auto &kind{std::get<1>(x.t)};
     const auto &chunk{std::get<2>(x.t)};
     if (chunk) {

diff  --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index e952b3531f84..1585b0c861ad 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -17,80 +17,63 @@
 #include "flang/Common/enum-set.h"
 #include "flang/Parser/parse-tree.h"
 #include "flang/Semantics/semantics.h"
+#include "llvm/Frontend/OpenMP/OMPConstants.h"
+
+using OmpDirectiveSet = Fortran::common::EnumSet<llvm::omp::Directive,
+    llvm::omp::Directive_enumSize>;
+
+using OmpClauseSet =
+    Fortran::common::EnumSet<llvm::omp::Clause, llvm::omp::Clause_enumSize>;
+
+namespace llvm {
+namespace omp {
+static OmpDirectiveSet parallelSet{Directive::OMPD_distribute_parallel_do,
+    Directive::OMPD_distribute_parallel_do_simd, Directive::OMPD_parallel,
+    Directive::OMPD_parallel_do, Directive::OMPD_parallel_do_simd,
+    Directive::OMPD_parallel_sections, Directive::OMPD_parallel_workshare,
+    Directive::OMPD_target_parallel, Directive::OMPD_target_parallel_do,
+    Directive::OMPD_target_parallel_do_simd,
+    Directive::OMPD_target_teams_distribute_parallel_do,
+    Directive::OMPD_target_teams_distribute_parallel_do_simd,
+    Directive::OMPD_teams_distribute_parallel_do,
+    Directive::OMPD_teams_distribute_parallel_do_simd};
+static OmpDirectiveSet doSet{Directive::OMPD_distribute_parallel_do,
+    Directive::OMPD_distribute_parallel_do_simd, Directive::OMPD_parallel,
+    Directive::OMPD_parallel_do, Directive::OMPD_parallel_do_simd,
+    Directive::OMPD_do, Directive::OMPD_do_simd,
+    Directive::OMPD_target_parallel_do, Directive::OMPD_target_parallel_do_simd,
+    Directive::OMPD_target_teams_distribute_parallel_do,
+    Directive::OMPD_target_teams_distribute_parallel_do_simd,
+    Directive::OMPD_teams_distribute_parallel_do,
+    Directive::OMPD_teams_distribute_parallel_do_simd};
+static OmpDirectiveSet doSimdSet{Directive::OMPD_distribute_parallel_do_simd,
+    Directive::OMPD_parallel_do_simd, Directive::OMPD_do_simd,
+    Directive::OMPD_target_parallel_do_simd,
+    Directive::OMPD_target_teams_distribute_parallel_do_simd,
+    Directive::OMPD_teams_distribute_parallel_do_simd};
+static OmpDirectiveSet taskloopSet{
+    Directive::OMPD_taskloop, Directive::OMPD_taskloop_simd};
+static OmpDirectiveSet targetSet{Directive::OMPD_target,
+    Directive::OMPD_target_parallel, Directive::OMPD_target_parallel_do,
+    Directive::OMPD_target_parallel_do_simd, Directive::OMPD_target_simd,
+    Directive::OMPD_target_teams, Directive::OMPD_target_teams_distribute,
+    Directive::OMPD_target_teams_distribute_simd};
+static OmpDirectiveSet simdSet{Directive::OMPD_distribute_parallel_do_simd,
+    Directive::OMPD_distribute_simd, Directive::OMPD_parallel_do_simd,
+    Directive::OMPD_do_simd, Directive::OMPD_simd,
+    Directive::OMPD_target_parallel_do_simd,
+    Directive::OMPD_target_teams_distribute_parallel_do_simd,
+    Directive::OMPD_target_teams_distribute_simd, Directive::OMPD_target_simd,
+    Directive::OMPD_taskloop_simd,
+    Directive::OMPD_teams_distribute_parallel_do_simd,
+    Directive::OMPD_teams_distribute_simd};
+static OmpDirectiveSet taskGeneratingSet{
+    OmpDirectiveSet{Directive::OMPD_task} | taskloopSet};
+} // namespace omp
+} // namespace llvm
 
 namespace Fortran::semantics {
 
-ENUM_CLASS(OmpDirective, ATOMIC, BARRIER, CANCEL, CANCELLATION_POINT, CRITICAL,
-    DECLARE_REDUCTION, DECLARE_SIMD, DECLARE_TARGET, DISTRIBUTE,
-    DISTRIBUTE_PARALLEL_DO, DISTRIBUTE_PARALLEL_DO_SIMD, DISTRIBUTE_SIMD, DO,
-    DO_SIMD, END_CRITICAL, END_DO, END_DO_SIMD, END_SECTIONS, END_SINGLE,
-    END_WORKSHARE, FLUSH, MASTER, ORDERED, PARALLEL, PARALLEL_DO,
-    PARALLEL_DO_SIMD, PARALLEL_SECTIONS, PARALLEL_WORKSHARE, SECTION, SECTIONS,
-    SIMD, SINGLE, TARGET, TARGET_DATA, TARGET_ENTER_DATA, TARGET_EXIT_DATA,
-    TARGET_PARALLEL, TARGET_PARALLEL_DO, TARGET_PARALLEL_DO_SIMD, TARGET_SIMD,
-    TARGET_TEAMS, TARGET_TEAMS_DISTRIBUTE, TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO,
-    TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD, TARGET_TEAMS_DISTRIBUTE_SIMD,
-    TARGET_UPDATE, TASK, TASKGROUP, TASKLOOP, TASKLOOP_SIMD, TASKWAIT,
-    TASKYIELD, TEAMS, TEAMS_DISTRIBUTE, TEAMS_DISTRIBUTE_PARALLEL_DO,
-    TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD, TEAMS_DISTRIBUTE_SIMD, THREADPRIVATE,
-    WORKSHARE)
-
-using OmpDirectiveSet = common::EnumSet<OmpDirective, OmpDirective_enumSize>;
-
-ENUM_CLASS(OmpClause, ALIGNED, COLLAPSE, COPYIN, COPYPRIVATE, DEFAULT,
-    DEFAULTMAP, DEPEND, DEVICE, DIST_SCHEDULE, FINAL, FIRSTPRIVATE, FROM,
-    GRAINSIZE, IF, INBRANCH, IS_DEVICE_PTR, LASTPRIVATE, LINEAR, LINK, MAP,
-    MERGEABLE, NOGROUP, NOTINBRANCH, NOWAIT, NUM_TASKS, NUM_TEAMS, NUM_THREADS,
-    ORDERED, PRIORITY, PRIVATE, PROC_BIND, REDUCTION, SAFELEN, SCHEDULE, SHARED,
-    SIMD, SIMDLEN, THREAD_LIMIT, THREADS, TO, UNIFORM, UNTIED, USE_DEVICE_PTR)
-
-using OmpClauseSet = common::EnumSet<OmpClause, OmpClause_enumSize>;
-
-static constexpr OmpDirectiveSet parallelSet{
-    OmpDirective::DISTRIBUTE_PARALLEL_DO,
-    OmpDirective::DISTRIBUTE_PARALLEL_DO_SIMD, OmpDirective::PARALLEL,
-    OmpDirective::PARALLEL_DO, OmpDirective::PARALLEL_DO_SIMD,
-    OmpDirective::PARALLEL_SECTIONS, OmpDirective::PARALLEL_WORKSHARE,
-    OmpDirective::TARGET_PARALLEL, OmpDirective::TARGET_PARALLEL_DO,
-    OmpDirective::TARGET_PARALLEL_DO_SIMD,
-    OmpDirective::TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO,
-    OmpDirective::TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD,
-    OmpDirective::TEAMS_DISTRIBUTE_PARALLEL_DO,
-    OmpDirective::TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD};
-static constexpr OmpDirectiveSet doSet{OmpDirective::DISTRIBUTE_PARALLEL_DO,
-    OmpDirective::DISTRIBUTE_PARALLEL_DO_SIMD, OmpDirective::PARALLEL_DO,
-    OmpDirective::PARALLEL_DO_SIMD, OmpDirective::DO, OmpDirective::DO_SIMD,
-    OmpDirective::TARGET_PARALLEL_DO, OmpDirective::TARGET_PARALLEL_DO_SIMD,
-    OmpDirective::TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO,
-    OmpDirective::TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD,
-    OmpDirective::TEAMS_DISTRIBUTE_PARALLEL_DO,
-    OmpDirective::TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD};
-static constexpr OmpDirectiveSet doSimdSet{
-    OmpDirective::DISTRIBUTE_PARALLEL_DO_SIMD, OmpDirective::PARALLEL_DO_SIMD,
-    OmpDirective::DO_SIMD, OmpDirective::TARGET_PARALLEL_DO_SIMD,
-    OmpDirective::TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD,
-    OmpDirective::TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD};
-static constexpr OmpDirectiveSet taskloopSet{
-    OmpDirective::TASKLOOP, OmpDirective::TASKLOOP_SIMD};
-static constexpr OmpDirectiveSet targetSet{OmpDirective::TARGET,
-    OmpDirective::TARGET_PARALLEL, OmpDirective::TARGET_PARALLEL_DO,
-    OmpDirective::TARGET_PARALLEL_DO_SIMD, OmpDirective::TARGET_SIMD,
-    OmpDirective::TARGET_TEAMS, OmpDirective::TARGET_TEAMS_DISTRIBUTE,
-    OmpDirective::TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO,
-    OmpDirective::TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD,
-    OmpDirective::TARGET_TEAMS_DISTRIBUTE_SIMD};
-static constexpr OmpDirectiveSet simdSet{
-    OmpDirective::DISTRIBUTE_PARALLEL_DO_SIMD, OmpDirective::DISTRIBUTE_SIMD,
-    OmpDirective::PARALLEL_DO_SIMD, OmpDirective::DO_SIMD, OmpDirective::SIMD,
-    OmpDirective::TARGET_PARALLEL_DO_SIMD,
-    OmpDirective::TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD,
-    OmpDirective::TARGET_TEAMS_DISTRIBUTE_SIMD, OmpDirective::TARGET_SIMD,
-    OmpDirective::TASKLOOP_SIMD,
-    OmpDirective::TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD,
-    OmpDirective::TEAMS_DISTRIBUTE_SIMD};
-static constexpr OmpDirectiveSet taskGeneratingSet{
-    OmpDirectiveSet{OmpDirective::TASK} | taskloopSet};
-
 class OmpStructureChecker : public virtual BaseChecker {
 public:
   OmpStructureChecker(SemanticsContext &context) : context_{context} {}
@@ -169,18 +152,18 @@ class OmpStructureChecker : public virtual BaseChecker {
 
 private:
   struct OmpContext {
-    OmpContext(parser::CharBlock source, OmpDirective d)
+    OmpContext(parser::CharBlock source, llvm::omp::Directive d)
         : directiveSource{source}, directive{d} {}
     parser::CharBlock directiveSource{nullptr};
     parser::CharBlock clauseSource{nullptr};
-    OmpDirective directive;
+    llvm::omp::Directive directive;
     OmpClauseSet allowedClauses{};
     OmpClauseSet allowedOnceClauses{};
     OmpClauseSet allowedExclusiveClauses{};
     OmpClauseSet requiredClauses{};
 
     const parser::OmpClause *clause{nullptr};
-    std::multimap<OmpClause, const parser::OmpClause *> clauseInfo;
+    std::multimap<llvm::omp::Clause, const parser::OmpClause *> clauseInfo;
   };
   // back() is the top of the stack
   OmpContext &GetContext() {
@@ -205,7 +188,7 @@ class OmpStructureChecker : public virtual BaseChecker {
     GetContext().clauseSource = clause.source;
     GetContext().clause = &clause;
   }
-  void SetContextDirectiveEnum(OmpDirective dir) {
+  void SetContextDirectiveEnum(llvm::omp::Directive dir) {
     GetContext().directive = dir;
   }
   void SetContextAllowed(const OmpClauseSet &allowed) {
@@ -220,30 +203,30 @@ class OmpStructureChecker : public virtual BaseChecker {
   void SetContextRequired(const OmpClauseSet &required) {
     GetContext().requiredClauses = required;
   }
-  void SetContextClauseInfo(OmpClause type) {
+  void SetContextClauseInfo(llvm::omp::Clause type) {
     GetContext().clauseInfo.emplace(type, GetContext().clause);
   }
-  const parser::OmpClause *FindClause(OmpClause type) {
+  const parser::OmpClause *FindClause(llvm::omp::Clause type) {
     auto it{GetContext().clauseInfo.find(type)};
     if (it != GetContext().clauseInfo.end()) {
       return it->second;
     }
     return nullptr;
   }
-  void PushContext(const parser::CharBlock &source, OmpDirective dir) {
+  void PushContext(const parser::CharBlock &source, llvm::omp::Directive dir) {
     ompContext_.emplace_back(source, dir);
   }
 
   void RequiresConstantPositiveParameter(
-      const OmpClause &clause, const parser::ScalarIntConstantExpr &i);
+      const llvm::omp::Clause &clause, const parser::ScalarIntConstantExpr &i);
   void RequiresPositiveParameter(
-      const OmpClause &clause, const parser::ScalarIntExpr &i);
+      const llvm::omp::Clause &clause, const parser::ScalarIntExpr &i);
 
   bool CurrentDirectiveIsNested() { return ompContext_.size() > 0; };
   bool HasInvalidWorksharingNesting(
       const parser::CharBlock &, const OmpDirectiveSet &);
-  void CheckAllowed(OmpClause);
-  void CheckRequired(OmpClause);
+  void CheckAllowed(llvm::omp::Clause);
+  void CheckRequired(llvm::omp::Clause);
   std::string ContextDirectiveAsFortran();
   void SayNotMatching(const parser::CharBlock &, const parser::CharBlock &);
   template <typename A, typename B, typename C>

diff  --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 277f5f77d1b3..51abeced62b2 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1150,9 +1150,9 @@ bool OmpVisitor::NeedsScope(const parser::OpenMPBlockConstruct &x) {
   const auto &beginBlockDir{std::get<parser::OmpBeginBlockDirective>(x.t)};
   const auto &beginDir{std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
   switch (beginDir.v) {
-  case parser::OmpBlockDirective::Directive::TargetData:
-  case parser::OmpBlockDirective::Directive::Master:
-  case parser::OmpBlockDirective::Directive::Ordered:
+  case llvm::omp::Directive::OMPD_target_data:
+  case llvm::omp::Directive::OMPD_master:
+  case llvm::omp::Directive::OMPD_ordered:
     return false;
   default:
     return true;
@@ -1236,10 +1236,11 @@ class OmpAttributeVisitor {
 
 private:
   struct OmpContext {
-    OmpContext(const parser::CharBlock &source, OmpDirective d, Scope &s)
+    OmpContext(
+        const parser::CharBlock &source, llvm::omp::Directive d, Scope &s)
         : directiveSource{source}, directive{d}, scope{s} {}
     parser::CharBlock directiveSource;
-    OmpDirective directive;
+    llvm::omp::Directive directive;
     Scope &scope;
     // TODO: default DSA is implicitly determined in 
diff erent ways
     Symbol::Flag defaultDSA{Symbol::Flag::OmpShared};
@@ -1253,14 +1254,14 @@ class OmpAttributeVisitor {
     CHECK(!ompContext_.empty());
     return ompContext_.back();
   }
-  void PushContext(const parser::CharBlock &source, OmpDirective dir) {
+  void PushContext(const parser::CharBlock &source, llvm::omp::Directive dir) {
     ompContext_.emplace_back(source, dir, context_.FindScope(source));
   }
   void PopContext() { ompContext_.pop_back(); }
   void SetContextDirectiveSource(parser::CharBlock &dir) {
     GetContext().directiveSource = dir;
   }
-  void SetContextDirectiveEnum(OmpDirective dir) {
+  void SetContextDirectiveEnum(llvm::omp::Directive dir) {
     GetContext().directive = dir;
   }
   Scope &currScope() { return GetContext().scope; }
@@ -6441,41 +6442,19 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPBlockConstruct &x) {
   const auto &beginBlockDir{std::get<parser::OmpBeginBlockDirective>(x.t)};
   const auto &beginDir{std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
   switch (beginDir.v) {
-  case parser::OmpBlockDirective::Directive::Master:
-    PushContext(beginDir.source, OmpDirective::MASTER);
-    break;
-  case parser::OmpBlockDirective::Directive::Ordered:
-    PushContext(beginDir.source, OmpDirective::ORDERED);
-    break;
-  case parser::OmpBlockDirective::Directive::Parallel:
-    PushContext(beginDir.source, OmpDirective::PARALLEL);
-    break;
-  case parser::OmpBlockDirective::Directive::Single:
-    PushContext(beginDir.source, OmpDirective::SINGLE);
-    break;
-  case parser::OmpBlockDirective::Directive::Target:
-    PushContext(beginDir.source, OmpDirective::TARGET);
-    break;
-  case parser::OmpBlockDirective::Directive::TargetData:
-    PushContext(beginDir.source, OmpDirective::TARGET_DATA);
-    break;
-  case parser::OmpBlockDirective::Directive::Task:
-    PushContext(beginDir.source, OmpDirective::TASK);
-    break;
-  case parser::OmpBlockDirective::Directive::Teams:
-    PushContext(beginDir.source, OmpDirective::TEAMS);
-    break;
-  case parser::OmpBlockDirective::Directive::Workshare:
-    PushContext(beginDir.source, OmpDirective::WORKSHARE);
-    break;
-  case parser::OmpBlockDirective::Directive::ParallelWorkshare:
-    PushContext(beginDir.source, OmpDirective::PARALLEL_WORKSHARE);
-    break;
-  case parser::OmpBlockDirective::Directive::TargetTeams:
-    PushContext(beginDir.source, OmpDirective::TARGET_TEAMS);
-    break;
-  case parser::OmpBlockDirective::Directive::TargetParallel:
-    PushContext(beginDir.source, OmpDirective::TARGET_PARALLEL);
+  case llvm::omp::Directive::OMPD_master:
+  case llvm::omp::Directive::OMPD_ordered:
+  case llvm::omp::Directive::OMPD_parallel:
+  case llvm::omp::Directive::OMPD_single:
+  case llvm::omp::Directive::OMPD_target:
+  case llvm::omp::Directive::OMPD_target_data:
+  case llvm::omp::Directive::OMPD_task:
+  case llvm::omp::Directive::OMPD_teams:
+  case llvm::omp::Directive::OMPD_workshare:
+  case llvm::omp::Directive::OMPD_parallel_workshare:
+  case llvm::omp::Directive::OMPD_target_teams:
+  case llvm::omp::Directive::OMPD_target_parallel:
+    PushContext(beginDir.source, beginDir.v);
     break;
   default:
     // TODO others
@@ -6490,74 +6469,31 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPLoopConstruct &x) {
   const auto &beginDir{std::get<parser::OmpLoopDirective>(beginLoopDir.t)};
   const auto &clauseList{std::get<parser::OmpClauseList>(beginLoopDir.t)};
   switch (beginDir.v) {
-  case parser::OmpLoopDirective::Directive::Distribute:
-    PushContext(beginDir.source, OmpDirective::DISTRIBUTE);
-    break;
-  case parser::OmpLoopDirective::Directive::DistributeParallelDo:
-    PushContext(beginDir.source, OmpDirective::DISTRIBUTE_PARALLEL_DO);
-    break;
-  case parser::OmpLoopDirective::Directive::DistributeParallelDoSimd:
-    PushContext(beginDir.source, OmpDirective::DISTRIBUTE_PARALLEL_DO_SIMD);
-    break;
-  case parser::OmpLoopDirective::Directive::DistributeSimd:
-    PushContext(beginDir.source, OmpDirective::DISTRIBUTE_SIMD);
-    break;
-  case parser::OmpLoopDirective::Directive::Do:
-    PushContext(beginDir.source, OmpDirective::DO);
-    break;
-  case parser::OmpLoopDirective::Directive::DoSimd:
-    PushContext(beginDir.source, OmpDirective::DO_SIMD);
-    break;
-  case parser::OmpLoopDirective::Directive::ParallelDo:
-    PushContext(beginDir.source, OmpDirective::PARALLEL_DO);
+  case llvm::omp::Directive::OMPD_distribute:
+  case llvm::omp::Directive::OMPD_distribute_parallel_do:
+  case llvm::omp::Directive::OMPD_distribute_parallel_do_simd:
+  case llvm::omp::Directive::OMPD_distribute_simd:
+  case llvm::omp::Directive::OMPD_do:
+  case llvm::omp::Directive::OMPD_do_simd:
+  case llvm::omp::Directive::OMPD_parallel_do:
+  case llvm::omp::Directive::OMPD_parallel_do_simd:
+  case llvm::omp::Directive::OMPD_simd:
+  case llvm::omp::Directive::OMPD_target_parallel_do:
+  case llvm::omp::Directive::OMPD_target_parallel_do_simd:
+  case llvm::omp::Directive::OMPD_target_teams_distribute:
+  case llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do:
+  case llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do_simd:
+  case llvm::omp::Directive::OMPD_target_teams_distribute_simd:
+  case llvm::omp::Directive::OMPD_target_simd:
+  case llvm::omp::Directive::OMPD_taskloop:
+  case llvm::omp::Directive::OMPD_taskloop_simd:
+  case llvm::omp::Directive::OMPD_teams_distribute:
+  case llvm::omp::Directive::OMPD_teams_distribute_parallel_do:
+  case llvm::omp::Directive::OMPD_teams_distribute_parallel_do_simd:
+  case llvm::omp::Directive::OMPD_teams_distribute_simd:
+    PushContext(beginDir.source, beginDir.v);
     break;
-  case parser::OmpLoopDirective::Directive::ParallelDoSimd:
-    PushContext(beginDir.source, OmpDirective::PARALLEL_DO_SIMD);
-    break;
-  case parser::OmpLoopDirective::Directive::Simd:
-    PushContext(beginDir.source, OmpDirective::SIMD);
-    break;
-  case parser::OmpLoopDirective::Directive::TargetParallelDo:
-    PushContext(beginDir.source, OmpDirective::TARGET_PARALLEL_DO);
-    break;
-  case parser::OmpLoopDirective::Directive::TargetParallelDoSimd:
-    PushContext(beginDir.source, OmpDirective::TARGET_PARALLEL_DO_SIMD);
-    break;
-  case parser::OmpLoopDirective::Directive::TargetTeamsDistribute:
-    PushContext(beginDir.source, OmpDirective::TARGET_TEAMS_DISTRIBUTE);
-    break;
-  case parser::OmpLoopDirective::Directive::TargetTeamsDistributeParallelDo:
-    PushContext(
-        beginDir.source, OmpDirective::TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO);
-    break;
-  case parser::OmpLoopDirective::Directive::TargetTeamsDistributeParallelDoSimd:
-    PushContext(beginDir.source,
-        OmpDirective::TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD);
-    break;
-  case parser::OmpLoopDirective::Directive::TargetTeamsDistributeSimd:
-    PushContext(beginDir.source, OmpDirective::TARGET_TEAMS_DISTRIBUTE_SIMD);
-    break;
-  case parser::OmpLoopDirective::Directive::TargetSimd:
-    PushContext(beginDir.source, OmpDirective::TARGET_SIMD);
-    break;
-  case parser::OmpLoopDirective::Directive::Taskloop:
-    PushContext(beginDir.source, OmpDirective::TASKLOOP);
-    break;
-  case parser::OmpLoopDirective::Directive::TaskloopSimd:
-    PushContext(beginDir.source, OmpDirective::TASKLOOP_SIMD);
-    break;
-  case parser::OmpLoopDirective::Directive::TeamsDistribute:
-    PushContext(beginDir.source, OmpDirective::TEAMS_DISTRIBUTE);
-    break;
-  case parser::OmpLoopDirective::Directive::TeamsDistributeParallelDo:
-    PushContext(beginDir.source, OmpDirective::TEAMS_DISTRIBUTE_PARALLEL_DO);
-    break;
-  case parser::OmpLoopDirective::Directive::TeamsDistributeParallelDoSimd:
-    PushContext(
-        beginDir.source, OmpDirective::TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD);
-    break;
-  case parser::OmpLoopDirective::Directive::TeamsDistributeSimd:
-    PushContext(beginDir.source, OmpDirective::TEAMS_DISTRIBUTE_SIMD);
+  default:
     break;
   }
   ClearDataSharingAttributeObjects();
@@ -6581,8 +6517,8 @@ void OmpAttributeVisitor::ResolveSeqLoopIndexInParallelOrTaskConstruct(
     if (targetIt == ompContext_.rend()) {
       return;
     }
-    if (parallelSet.test(targetIt->directive) ||
-        taskGeneratingSet.test(targetIt->directive)) {
+    if (llvm::omp::parallelSet.test(targetIt->directive) ||
+        llvm::omp::taskGeneratingSet.test(targetIt->directive)) {
       break;
     }
   }
@@ -6669,7 +6605,7 @@ void OmpAttributeVisitor::PrivatizeAssociatedLoopIndex(
   if (level <= 0)
     return;
   Symbol::Flag ivDSA{Symbol::Flag::OmpPrivate};
-  if (simdSet.test(GetContext().directive)) {
+  if (llvm::omp::simdSet.test(GetContext().directive)) {
     if (level == 1) {
       ivDSA = Symbol::Flag::OmpLinear;
     } else {
@@ -6700,11 +6636,11 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPSectionsConstruct &x) {
   const auto &beginDir{
       std::get<parser::OmpSectionsDirective>(beginSectionsDir.t)};
   switch (beginDir.v) {
-  case parser::OmpSectionsDirective::Directive::ParallelSections:
-    PushContext(beginDir.source, OmpDirective::PARALLEL_SECTIONS);
+  case llvm::omp::Directive::OMPD_parallel_sections:
+  case llvm::omp::Directive::OMPD_sections:
+    PushContext(beginDir.source, beginDir.v);
     break;
-  case parser::OmpSectionsDirective::Directive::Sections:
-    PushContext(beginDir.source, OmpDirective::SECTIONS);
+  default:
     break;
   }
   ClearDataSharingAttributeObjects();
@@ -6712,7 +6648,7 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPSectionsConstruct &x) {
 }
 
 bool OmpAttributeVisitor::Pre(const parser::OpenMPThreadprivate &x) {
-  PushContext(x.source, OmpDirective::THREADPRIVATE);
+  PushContext(x.source, llvm::omp::Directive::OMPD_threadprivate);
   const auto &list{std::get<parser::OmpObjectList>(x.t)};
   ResolveOmpObjectList(list, Symbol::Flag::OmpThreadprivate);
   return false;

diff  --git a/flang/tools/f18-parse-demo/CMakeLists.txt b/flang/tools/f18-parse-demo/CMakeLists.txt
index d60d7d6d5cbd..465873ca00ff 100644
--- a/flang/tools/f18-parse-demo/CMakeLists.txt
+++ b/flang/tools/f18-parse-demo/CMakeLists.txt
@@ -1,3 +1,7 @@
+set(LLVM_LINK_COMPONENTS
+  FrontendOpenMP
+  )
+
 add_flang_tool(f18-parse-demo
   f18-parse-demo.cpp
   stub-evaluate.cpp

diff  --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index 8813b2d434ef..ed44676d2fa1 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -189,6 +189,9 @@ def OMPC_Unknown : Clause<"unknown"> {
   let isImplicit = 1;
   let isDefault = 1;
 }
+def OMPC_Link : Clause<"link"> {}
+def OMPC_Inbranch : Clause<"inbranch"> {}
+def OMPC_Notinbranch : Clause<"notinbranch"> {}
 
 //===----------------------------------------------------------------------===//
 // Definition of OpenMP directives
@@ -216,6 +219,11 @@ def OMP_For : Directive<"for"> {
       OMPC_Reduction, OMPC_Collapse, OMPC_Schedule, OMPC_Ordered, OMPC_NoWait,
       OMPC_Linear, OMPC_Allocate, OMPC_Order];
 }
+def OMP_Do : Directive<"do"> {
+  let allowedClauses = [OMPC_Private, OMPC_FirstPrivate, OMPC_LastPrivate,
+      OMPC_Linear, OMPC_Reduction];
+  let allowedOnceClauses = [OMPC_Schedule, OMPC_Collapse, OMPC_Ordered];
+}
 def OMP_Sections : Directive<"sections"> {
   let allowedClauses = [OMPC_Private, OMPC_LastPrivate, OMPC_FirstPrivate,
       OMPC_Reduction, OMPC_NoWait, OMPC_Allocate];
@@ -289,6 +297,14 @@ def OMP_TargetParallelFor : Directive<"target parallel for"> {
       OMPC_Linear, OMPC_IsDevicePtr, OMPC_Allocator, OMPC_Order,
       OMPC_UsesAllocators];
 }
+def OMP_TargetParallelDo : Directive<"target parallel do"> {
+  let allowedClauses = [OMPC_If, OMPC_Device, OMPC_Map, OMPC_Private,
+      OMPC_FirstPrivate, OMPC_LastPrivate, OMPC_NoWait, OMPC_Depend,
+      OMPC_DefaultMap, OMPC_NumThreads, OMPC_DefaultMap, OMPC_ProcBind,
+      OMPC_Shared, OMPC_Reduction, OMPC_Collapse, OMPC_Schedule, OMPC_Ordered,
+      OMPC_Linear, OMPC_IsDevicePtr, OMPC_Allocator, OMPC_Order,
+      OMPC_UsesAllocators];
+}
 def OMP_TargetUpdate : Directive<"target update"> {
   let allowedClauses = [OMPC_If, OMPC_Device, OMPC_To, OMPC_From, OMPC_NoWait,
       OMPC_Depend];
@@ -299,6 +315,12 @@ def OMP_ParallelFor : Directive<"parallel for"> {
       OMPC_LastPrivate, OMPC_Collapse, OMPC_Schedule, OMPC_Ordered, OMPC_Linear,
       OMPC_Allocate, OMPC_Order];
 }
+def OMP_ParallelDo : Directive<"parallel do"> {
+  let allowedClauses = [ OMPC_Default, OMPC_Private, OMPC_FirstPrivate,
+      OMPC_Shared, OMPC_Reduction, OMPC_Copyin, OMPC_LastPrivate, OMPC_Linear];
+  let allowedOnceClauses = [OMPC_If, OMPC_NumThreads, OMPC_ProcBind,
+      OMPC_Schedule, OMPC_Ordered, OMPC_Collapse];
+}
 def OMP_ParallelForSimd : Directive<"parallel for simd"> {
   let allowedClauses = [OMPC_If, OMPC_NumThreads, OMPC_Default, OMPC_ProcBind,
       OMPC_Private, OMPC_FirstPrivate, OMPC_Shared, OMPC_Reduction, OMPC_Copyin,
@@ -306,6 +328,13 @@ def OMP_ParallelForSimd : Directive<"parallel for simd"> {
       OMPC_SimdLen, OMPC_Linear, OMPC_Aligned, OMPC_Ordered, OMPC_Allocate,
       OMPC_NonTemporal, OMPC_Order];
 }
+def OMP_ParallelDoSimd : Directive<"parallel do simd"> {
+  let allowedClauses = [OMPC_If, OMPC_NumThreads, OMPC_Default, OMPC_ProcBind,
+      OMPC_Private, OMPC_FirstPrivate, OMPC_Shared, OMPC_Reduction, OMPC_Copyin,
+      OMPC_LastPrivate, OMPC_Collapse, OMPC_Schedule, OMPC_SafeLen,
+      OMPC_SimdLen, OMPC_Linear, OMPC_Aligned, OMPC_Ordered, OMPC_Allocate,
+      OMPC_NonTemporal, OMPC_Order];
+}
 def OMP_ParallelMaster : Directive<"parallel master"> {
   let allowedClauses = [OMPC_If, OMPC_NumThreads, OMPC_Default, OMPC_Private,
       OMPC_FirstPrivate, OMPC_Shared, OMPC_Copyin, OMPC_Reduction,
@@ -322,6 +351,12 @@ def OMP_ForSimd : Directive<"for simd"> {
       OMPC_SimdLen, OMPC_Linear, OMPC_Aligned, OMPC_Ordered, OMPC_Allocate,
       OMPC_If, OMPC_NonTemporal, OMPC_Order];
 }
+def OMP_DoSimd : Directive<"do simd"> {
+  let allowedClauses = [OMPC_Aligned, OMPC_Private, OMPC_FirstPrivate,
+      OMPC_LastPrivate, OMPC_Linear, OMPC_Reduction];
+  let allowedOnceClauses = [OMPC_Schedule, OMPC_Collapse, OMPC_Ordered,
+      OMPC_SafeLen, OMPC_SimdLen];
+}
 def OMP_CancellationPoint : Directive<"cancellation point"> {}
 def OMP_DeclareReduction : Directive<"declare reduction"> {}
 def OMP_DeclareMapper : Directive<"declare mapper"> {
@@ -353,6 +388,12 @@ def OMP_DistributeParallelFor : Directive<"distribute parallel for"> {
       OMPC_Private, OMPC_Shared, OMPC_Reduction, OMPC_Copyin, OMPC_Schedule,
       OMPC_Allocate, OMPC_Order];
 }
+def OMP_DistributeParallelDo : Directive<"distribute parallel do"> {
+  let allowedClauses = [OMPC_FirstPrivate, OMPC_LastPrivate, OMPC_Collapse,
+      OMPC_DistSchedule, OMPC_If, OMPC_NumThreads, OMPC_Default, OMPC_ProcBind,
+      OMPC_Private, OMPC_Shared, OMPC_Reduction, OMPC_Copyin, OMPC_Schedule,
+      OMPC_Allocate, OMPC_Order];
+}
 def OMP_DistributeParallelForSimd : Directive<"distribute parallel for simd"> {
   let allowedClauses = [OMPC_FirstPrivate, OMPC_LastPrivate, OMPC_Collapse,
       OMPC_DistSchedule, OMPC_If, OMPC_NumThreads, OMPC_Default, OMPC_ProcBind,
@@ -360,6 +401,13 @@ def OMP_DistributeParallelForSimd : Directive<"distribute parallel for simd"> {
       OMPC_Linear, OMPC_Aligned, OMPC_SafeLen, OMPC_SimdLen, OMPC_Allocate,
       OMPC_NonTemporal, OMPC_Order];
 }
+def OMP_DistributeParallelDoSimd : Directive<"distribute parallel do simd"> {
+  let allowedClauses = [OMPC_FirstPrivate, OMPC_LastPrivate, OMPC_Collapse,
+      OMPC_DistSchedule, OMPC_If, OMPC_NumThreads, OMPC_Default, OMPC_ProcBind,
+      OMPC_Private, OMPC_Shared, OMPC_Reduction, OMPC_Copyin, OMPC_Schedule,
+      OMPC_Linear, OMPC_Aligned, OMPC_SafeLen, OMPC_SimdLen, OMPC_Allocate,
+      OMPC_NonTemporal, OMPC_Order];
+}
 def OMP_DistributeSimd : Directive<"distribute simd"> {
   let allowedClauses = [OMPC_Private, OMPC_FirstPrivate, OMPC_LastPrivate,
       OMPC_Collapse, OMPC_DistSchedule, OMPC_Linear, OMPC_Aligned, OMPC_SafeLen,
@@ -374,6 +422,14 @@ def OMP_TargetParallelForSimd : Directive<"target parallel for simd"> {
       OMPC_Linear, OMPC_SafeLen, OMPC_SimdLen, OMPC_Aligned, OMPC_IsDevicePtr,
       OMPC_Allocate, OMPC_NonTemporal, OMPC_Order, OMPC_UsesAllocators];
 }
+def OMP_TargetParallelDoSimd : Directive<"target parallel do simd"> {
+  let allowedClauses = [OMPC_If, OMPC_Device, OMPC_Map, OMPC_Private,
+      OMPC_FirstPrivate, OMPC_LastPrivate, OMPC_NoWait, OMPC_Depend,
+      OMPC_DefaultMap, OMPC_NumThreads, OMPC_Default, OMPC_ProcBind,
+      OMPC_Shared, OMPC_Reduction, OMPC_Collapse, OMPC_Schedule, OMPC_Ordered,
+      OMPC_Linear, OMPC_SafeLen, OMPC_SimdLen, OMPC_Aligned, OMPC_IsDevicePtr,
+      OMPC_Allocate, OMPC_NonTemporal, OMPC_Order, OMPC_UsesAllocators];
+}
 def OMP_TargetSimd : Directive<"target simd"> {
   let allowedClauses = [OMPC_If, OMPC_Device, OMPC_Map, OMPC_Private,
       OMPC_NoWait, OMPC_Depend, OMPC_DefaultMap, OMPC_FirstPrivate,
@@ -401,6 +457,14 @@ def OMP_TeamsDistributeParallelForSimd :
       OMPC_Aligned, OMPC_SafeLen, OMPC_SimdLen, OMPC_NumTeams, OMPC_ThreadLimit,
       OMPC_Allocate, OMPC_NonTemporal, OMPC_Order];
 }
+def OMP_TeamsDistributeParallelDoSimd :
+    Directive<"teams distribute parallel do simd"> {
+  let allowedClauses = [OMPC_FirstPrivate, OMPC_LastPrivate, OMPC_Collapse,
+      OMPC_DistSchedule, OMPC_If, OMPC_NumThreads, OMPC_Default, OMPC_ProcBind,
+      OMPC_Private, OMPC_Shared, OMPC_Reduction, OMPC_Schedule, OMPC_Linear,
+      OMPC_Aligned, OMPC_SafeLen, OMPC_SimdLen, OMPC_NumTeams, OMPC_ThreadLimit,
+      OMPC_Allocate, OMPC_NonTemporal, OMPC_Order];
+}
 def OMP_TeamsDistributeParallelFor :
     Directive<"teams distribute parallel for"> {
   let allowedClauses = [OMPC_FirstPrivate, OMPC_LastPrivate, OMPC_Collapse,
@@ -408,6 +472,13 @@ def OMP_TeamsDistributeParallelFor :
       OMPC_Private, OMPC_Shared, OMPC_Reduction, OMPC_Schedule, OMPC_NumTeams,
       OMPC_ThreadLimit, OMPC_Copyin, OMPC_Allocate, OMPC_Order];
 }
+def OMP_TeamsDistributeParallelDo :
+    Directive<"teams distribute parallel do"> {
+  let allowedClauses = [OMPC_FirstPrivate, OMPC_LastPrivate, OMPC_Collapse,
+      OMPC_DistSchedule, OMPC_If, OMPC_NumThreads, OMPC_Default, OMPC_ProcBind,
+      OMPC_Private, OMPC_Shared, OMPC_Reduction, OMPC_Schedule, OMPC_NumTeams,
+      OMPC_ThreadLimit, OMPC_Copyin, OMPC_Allocate, OMPC_Order];
+}
 def OMP_TargetTeams : Directive<"target teams"> {
   let allowedClauses = [OMPC_If, OMPC_Device, OMPC_Map, OMPC_Private,
       OMPC_NoWait, OMPC_Depend, OMPC_DefaultMap, OMPC_FirstPrivate,
@@ -430,6 +501,15 @@ def OMP_TargetTeamsDistributeParallelFor :
       OMPC_DistSchedule, OMPC_NumThreads, OMPC_ProcBind, OMPC_Schedule,
       OMPC_Allocate, OMPC_Order, OMPC_UsesAllocators];
 }
+def OMP_TargetTeamsDistributeParallelDo :
+    Directive<"target teams distribute parallel do"> {
+  let allowedClauses = [OMPC_If, OMPC_Device, OMPC_Map, OMPC_Private,
+      OMPC_NoWait, OMPC_Depend, OMPC_DefaultMap, OMPC_FirstPrivate,
+      OMPC_IsDevicePtr, OMPC_Default, OMPC_Shared, OMPC_Reduction,
+      OMPC_NumTeams, OMPC_ThreadLimit, OMPC_LastPrivate, OMPC_Collapse,
+      OMPC_DistSchedule, OMPC_NumThreads, OMPC_ProcBind, OMPC_Schedule,
+      OMPC_Allocate, OMPC_Order, OMPC_UsesAllocators];
+}
 def OMP_TargetTeamsDistributeParallelForSimd :
     Directive<"target teams distribute parallel for simd"> {
   let allowedClauses = [OMPC_If, OMPC_Device, OMPC_Map, OMPC_Private,
@@ -440,6 +520,16 @@ def OMP_TargetTeamsDistributeParallelForSimd :
       OMPC_Linear, OMPC_Aligned, OMPC_SafeLen, OMPC_SimdLen, OMPC_Allocate,
       OMPC_NonTemporal, OMPC_Order, OMPC_UsesAllocators];
 }
+def OMP_TargetTeamsDistributeParallelDoSimd :
+    Directive<"target teams distribute parallel do simd"> {
+  let allowedClauses = [OMPC_If, OMPC_Device, OMPC_Map, OMPC_Private,
+      OMPC_NoWait, OMPC_Depend, OMPC_DefaultMap, OMPC_FirstPrivate,
+      OMPC_IsDevicePtr, OMPC_Default, OMPC_Shared, OMPC_Reduction,
+      OMPC_NumTeams, OMPC_ThreadLimit, OMPC_LastPrivate, OMPC_Collapse,
+      OMPC_DistSchedule, OMPC_NumThreads, OMPC_ProcBind, OMPC_Schedule,
+      OMPC_Linear, OMPC_Aligned, OMPC_SafeLen, OMPC_SimdLen, OMPC_Allocate,
+      OMPC_NonTemporal, OMPC_Order, OMPC_UsesAllocators];
+}
 def OMP_TargetTeamsDistributeSimd :
     Directive<"target teams distribute simd"> {
   let allowedClauses = [OMPC_If, OMPC_Device, OMPC_Map, OMPC_Private,
@@ -494,6 +584,13 @@ def OMP_Scan : Directive<"scan"> {
 }
 def OMP_BeginDeclareVariant : Directive<"begin declare variant"> {}
 def OMP_EndDeclareVariant : Directive<"end declare variant"> {}
+def OMP_ParallelWorkshare : Directive<"parallel workshare"> {}
+def OMP_Workshare : Directive<"workshare"> {}
+def OMP_EndDo : Directive<"end do"> {}
+def OMP_EndDoSimd : Directive<"end do simd"> {}
+def OMP_EndSections : Directive<"end sections"> {}
+def OMP_EndSingle : Directive<"end single"> {}
+def OMP_EndWorkshare : Directive<"end workshare"> {}
 def OMP_Unknown : Directive<"unknown"> {
   let isDefault = 1;
 }


        


More information about the flang-commits mailing list