[clang] [llvm] [clang][OpenMP] Shorten directive classification in ParseOpenMP (PR #94691)

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 25 09:09:16 PDT 2024


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

>From a66fd5d140ad991a440e846416b9f4f281d01354 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Thu, 6 Jun 2024 13:04:07 -0500
Subject: [PATCH 01/10] [Frontend][OpenMP] Sort all the things in OMP.td, NFC

The file OMP.td is becoming tedious to update by hand due to the
seemingly random ordering of various items in it. This patch brings
order to it by sorting most of the contents.

The clause definitions are sorted alphabetically with respect to the
spelling of the clause.[1]

The directive definitions are split into two leaf directives and
compound directives.[2] Within each, definitions are sorted alphabetically
with respect to the spelling, with the exception that "end xyz"
directives are placed immediately following the definition of "xyz".[3]

Within each directive definition, the lists of clauses are also sorted
alphabetically.

[1] All spellings are made of lowercase letters, _, or space. Ordering
between non-letters follow the order assumed by `sort` utility.
[2] Compound directives refer to the consituent leaf directives, hence
the leaf definitions must come first.
[3] Some of the "end xyz" directives have properties derived from the
corresponding "xyz" directive. This exception guarantees that "xyz"
precedes the "end xyz".
---
 llvm/include/llvm/Frontend/OpenMP/OMP.td | 3066 +++++++++++-----------
 1 file changed, 1548 insertions(+), 1518 deletions(-)

diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index 609df6a4c54aa..afb8d5f725753 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -28,151 +28,48 @@ def OpenMP : DirectiveLanguage {
 }
 
 //===----------------------------------------------------------------------===//
-// Definition of OpenMP clauses
+// Definitions of OpenMP clauses
+// Sorted alphabetically wrt clause spelling.
 //===----------------------------------------------------------------------===//
 
-def OMPC_Allocator : Clause<"allocator"> {
-  let clangClass = "OMPAllocatorClause";
-  let flangClass = "ScalarIntExpr";
-}
-def OMPC_If : Clause<"if"> {
-  let clangClass = "OMPIfClause";
-  let flangClass = "OmpIfClause";
-}
-def OMPC_Final : Clause<"final"> {
-  let clangClass = "OMPFinalClause";
-  let flangClass = "ScalarLogicalExpr";
-}
-def OMPC_NumThreads : Clause<"num_threads"> {
-  let clangClass = "OMPNumThreadsClause";
-  let flangClass = "ScalarIntExpr";
-}
-def OMPC_SafeLen : Clause<"safelen"> {
-  let clangClass = "OMPSafelenClause";
-  let flangClass = "ScalarIntConstantExpr";
-}
-def OMPC_SimdLen : Clause<"simdlen"> {
-  let clangClass = "OMPSimdlenClause";
-  let flangClass = "ScalarIntConstantExpr";
-}
-def OMPC_Collapse : Clause<"collapse"> {
-  let clangClass = "OMPCollapseClause";
-  let flangClass = "ScalarIntConstantExpr";
-}
-def OMPC_Default : Clause<"default"> {
-  let clangClass = "OMPDefaultClause";
-  let flangClass = "OmpDefaultClause";
-}
-def OMPC_Private : Clause<"private"> {
-  let clangClass = "OMPPrivateClause";
-  let flangClass = "OmpObjectList";
-}
-def OMPC_Sizes: Clause<"sizes"> {
-  let clangClass = "OMPSizesClause";
-  let flangClass = "ScalarIntExpr";
-  let isValueList = true;
-  }
-def OMPC_Full: Clause<"full"> {
-  let clangClass = "OMPFullClause";
-}
-def OMPC_Partial: Clause<"partial"> {
-  let clangClass = "OMPPartialClause";
-  let flangClass = "ScalarIntConstantExpr";
-  let isValueOptional = true;
- }
-def OMPC_FirstPrivate : Clause<"firstprivate"> {
-  let clangClass = "OMPFirstprivateClause";
-  let flangClass = "OmpObjectList";
+def OMPC_Acquire : Clause<"acquire"> {
+  let clangClass = "OMPAcquireClause";
 }
-def OMPC_LastPrivate : Clause<"lastprivate"> {
-  let clangClass = "OMPLastprivateClause";
-  let flangClass = "OmpObjectList";
+def OMPC_AcqRel : Clause<"acq_rel"> {
+  let clangClass = "OMPAcqRelClause";
 }
-def OMPC_Shared : Clause<"shared"> {
-  let clangClass = "OMPSharedClause";
-  let flangClass = "OmpObjectList";
+def OMPC_AdjustArgs : Clause<"adjust_args"> {
 }
-def OMPC_Reduction : Clause<"reduction"> {
-  let clangClass = "OMPReductionClause";
-  let flangClass = "OmpReductionClause";
+def OMPC_Affinity : Clause<"affinity"> {
+  let clangClass = "OMPAffinityClause";
 }
-def OMPC_Linear : Clause<"linear"> {
-  let clangClass = "OMPLinearClause";
-  let flangClass = "OmpLinearClause";
+def OMPC_Align : Clause<"align"> {
+  let clangClass = "OMPAlignClause";
 }
 def OMPC_Aligned : Clause<"aligned"> {
   let clangClass = "OMPAlignedClause";
   let flangClass = "OmpAlignedClause";
 }
-def OMPC_Copyin : Clause<"copyin"> {
-  let clangClass = "OMPCopyinClause";
-  let flangClass = "OmpObjectList";
+def OMPC_Allocate : Clause<"allocate"> {
+  let clangClass = "OMPAllocateClause";
+  let flangClass = "OmpAllocateClause";
 }
-def OMPC_CopyPrivate : Clause<"copyprivate"> {
-  let clangClass = "OMPCopyprivateClause";
-  let flangClass = "OmpObjectList";
+def OMPC_Allocator : Clause<"allocator"> {
+  let clangClass = "OMPAllocatorClause";
+  let flangClass = "ScalarIntExpr";
 }
-def OMP_PROC_BIND_master : ClauseVal<"master",2,1> {}
-def OMP_PROC_BIND_close : ClauseVal<"close",3,1> {}
-def OMP_PROC_BIND_spread : ClauseVal<"spread",4,1> {}
-def OMP_PROC_BIND_primary : ClauseVal<"primary",5,1> {}
-def OMP_PROC_BIND_default : ClauseVal<"default",6,0> {}
-def OMP_PROC_BIND_unknown : ClauseVal<"unknown",7,0> { let isDefault = true; }
-def OMPC_ProcBind : Clause<"proc_bind"> {
-  let clangClass = "OMPProcBindClause";
-  let flangClass = "OmpProcBindClause";
-  let enumClauseValue = "ProcBindKind";
-  let allowedClauseValues = [
-    OMP_PROC_BIND_primary,
-    OMP_PROC_BIND_master,
-    OMP_PROC_BIND_close,
-    OMP_PROC_BIND_spread,
-    OMP_PROC_BIND_default,
-    OMP_PROC_BIND_unknown
-  ];
+def OMPC_AppendArgs : Clause<"append_args"> {
 }
-
-def OMP_SCHEDULE_Static : ClauseVal<"static", 2, 1> {}
-def OMP_SCHEDULE_Dynamic : ClauseVal<"dynamic", 3, 1> {}
-def OMP_SCHEDULE_Guided : ClauseVal<"guided", 4, 1> {}
-def OMP_SCHEDULE_Auto : ClauseVal<"auto", 5, 1> {}
-def OMP_SCHEDULE_Runtime : ClauseVal<"runtime", 6, 1> {}
-def OMP_SCHEDULE_Default : ClauseVal<"default", 7, 0> { let isDefault = 1; }
-
-def OMPC_Schedule : Clause<"schedule"> {
-  let clangClass = "OMPScheduleClause";
-  let flangClass = "OmpScheduleClause";
-  let enumClauseValue = "ScheduleKind";
-  let allowedClauseValues = [
-    OMP_SCHEDULE_Static,
-    OMP_SCHEDULE_Dynamic,
-    OMP_SCHEDULE_Guided,
-    OMP_SCHEDULE_Auto,
-    OMP_SCHEDULE_Runtime,
-    OMP_SCHEDULE_Default
-  ];
+def OMPC_At : Clause<"at"> {
+  let clangClass = "OMPAtClause";
 }
-
-def OMP_MEMORY_ORDER_SeqCst : ClauseVal<"seq_cst", 1, 1> {}
-def OMP_MEMORY_ORDER_AcqRel : ClauseVal<"acq_rel", 2, 1> {}
-def OMP_MEMORY_ORDER_Acquire : ClauseVal<"acquire", 3, 1> {}
-def OMP_MEMORY_ORDER_Release : ClauseVal<"release", 4, 1> {}
-def OMP_MEMORY_ORDER_Relaxed : ClauseVal<"relaxed", 5, 1> {}
-def OMP_MEMORY_ORDER_Default : ClauseVal<"default", 6, 0> {
-  let isDefault = 1;
+def OMPC_AtomicDefaultMemOrder : Clause<"atomic_default_mem_order"> {
+  let clangClass = "OMPAtomicDefaultMemOrderClause";
+  let flangClass = "OmpAtomicDefaultMemOrderClause";
 }
-def OMPC_MemoryOrder : Clause<"memory_order"> {
-  let enumClauseValue = "MemoryOrderKind";
-  let allowedClauseValues = [
-    OMP_MEMORY_ORDER_SeqCst,
-    OMP_MEMORY_ORDER_AcqRel,
-    OMP_MEMORY_ORDER_Acquire,
-    OMP_MEMORY_ORDER_Release,
-    OMP_MEMORY_ORDER_Relaxed,
-    OMP_MEMORY_ORDER_Default
-  ];
+def OMPC_Bind : Clause<"bind"> {
+  let clangClass = "OMPBindClause";
 }
-
 def OMP_CANCELLATION_CONSTRUCT_Parallel : ClauseVal<"parallel", 1, 1> {}
 def OMP_CANCELLATION_CONSTRUCT_Loop : ClauseVal<"loop", 2, 1> {}
 def OMP_CANCELLATION_CONSTRUCT_Sections : ClauseVal<"sections", 3, 1> {}
@@ -180,7 +77,6 @@ def OMP_CANCELLATION_CONSTRUCT_Taskgroup : ClauseVal<"taskgroup", 4, 1> {}
 def OMP_CANCELLATION_CONSTRUCT_None : ClauseVal<"none", 5, 0> {
   let isDefault = 1;
 }
-
 def OMPC_CancellationConstructType : Clause<"cancellation_construct_type"> {
   let enumClauseValue = "CancellationConstructType";
   let allowedClauseValues = [
@@ -191,35 +87,46 @@ def OMPC_CancellationConstructType : Clause<"cancellation_construct_type"> {
     OMP_CANCELLATION_CONSTRUCT_None
   ];
 }
-
-def OMPC_Ordered : Clause<"ordered"> {
-  let clangClass = "OMPOrderedClause";
+def OMPC_Capture : Clause<"capture"> {
+  let clangClass = "OMPCaptureClause";
+}
+def OMPC_Collapse : Clause<"collapse"> {
+  let clangClass = "OMPCollapseClause";
   let flangClass = "ScalarIntConstantExpr";
-  let isValueOptional = true;
 }
-def OMPC_NoWait : Clause<"nowait"> {
-  let clangClass = "OMPNowaitClause";
+def OMPC_Compare : Clause<"compare"> {
+  let clangClass = "OMPCompareClause";
 }
-def OMPC_Untied : Clause<"untied"> { let clangClass = "OMPUntiedClause"; }
-def OMPC_Mergeable : Clause<"mergeable"> {
-  let clangClass = "OMPMergeableClause";
+def OMPC_Copyin : Clause<"copyin"> {
+  let clangClass = "OMPCopyinClause";
+  let flangClass = "OmpObjectList";
+}
+def OMPC_CopyPrivate : Clause<"copyprivate"> {
+  let clangClass = "OMPCopyprivateClause";
+  let flangClass = "OmpObjectList";
+}
+def OMPC_Default : Clause<"default"> {
+  let clangClass = "OMPDefaultClause";
+  let flangClass = "OmpDefaultClause";
+}
+def OMPC_DefaultMap : Clause<"defaultmap"> {
+  let clangClass = "OMPDefaultmapClause";
+  let flangClass = "OmpDefaultmapClause";
 }
-def OMPC_Read : Clause<"read"> { let clangClass = "OMPReadClause"; }
-def OMPC_Write : Clause<"write"> { let clangClass = "OMPWriteClause"; }
-def OMPC_Update : Clause<"update"> { let clangClass = "OMPUpdateClause"; }
-def OMPC_Capture : Clause<"capture"> { let clangClass = "OMPCaptureClause"; }
-def OMPC_Compare : Clause<"compare"> { let clangClass = "OMPCompareClause"; }
-def OMPC_Fail : Clause<"fail"> { let clangClass = "OMPFailClause"; }
-def OMPC_SeqCst : Clause<"seq_cst"> { let clangClass = "OMPSeqCstClause"; }
-def OMPC_AcqRel : Clause<"acq_rel"> { let clangClass = "OMPAcqRelClause"; }
-def OMPC_Acquire : Clause<"acquire"> { let clangClass = "OMPAcquireClause"; }
-def OMPC_Release : Clause<"release"> { let clangClass = "OMPReleaseClause"; }
-def OMPC_Relaxed : Clause<"relaxed"> { let clangClass = "OMPRelaxedClause"; }
-def OMPC_Weak : Clause<"weak"> { let clangClass = "OMPWeakClause"; }
 def OMPC_Depend : Clause<"depend"> {
   let clangClass = "OMPDependClause";
   let flangClass = "OmpDependClause";
 }
+def OMPC_Depobj : Clause<"depobj"> {
+  let clangClass = "OMPDepobjClause";
+  let isImplicit = true;
+}
+def OMPC_Destroy : Clause<"destroy"> {
+  let clangClass = "OMPDestroyClause";
+}
+def OMPC_Detach : Clause<"detach"> {
+  let clangClass = "OMPDetachClause";
+}
 def OMPC_Device : Clause<"device"> {
   let clangClass = "OMPDeviceClause";
   let flangClass = "OmpDeviceClause";
@@ -227,28 +134,51 @@ def OMPC_Device : Clause<"device"> {
 def OMPC_DeviceType : Clause<"device_type"> {
   let flangClass = "OmpDeviceTypeClause";
 }
-def OMPC_Threads : Clause<"threads"> { let clangClass = "OMPThreadsClause"; }
-def OMPC_Simd : Clause<"simd"> { let clangClass = "OMPSIMDClause"; }
-def OMPC_Map : Clause<"map"> {
-  let clangClass = "OMPMapClause";
-  let flangClass = "OmpMapClause";
-}
-def OMPC_NumTeams : Clause<"num_teams"> {
-  let clangClass = "OMPNumTeamsClause";
+def OMPC_DistSchedule : Clause<"dist_schedule"> {
+  let clangClass = "OMPDistScheduleClause";
   let flangClass = "ScalarIntExpr";
+  let isValueOptional = true;
 }
-def OMPC_ThreadLimit : Clause<"thread_limit"> {
-  let clangClass = "OMPThreadLimitClause";
-  let flangClass = "ScalarIntExpr";
+def OMPC_Doacross : Clause<"doacross"> {
+  let clangClass = "OMPDoacrossClause";
 }
-def OMPC_Priority : Clause<"priority"> {
-  let clangClass = "OMPPriorityClause";
+def OMPC_DynamicAllocators : Clause<"dynamic_allocators"> {
+  let clangClass = "OMPDynamicAllocatorsClause";
+}
+def OMPC_Enter : Clause<"enter"> {
+  let flangClass = "OmpObjectList";
+}
+def OMPC_Exclusive : Clause<"exclusive"> {
+  let clangClass = "OMPExclusiveClause";
+}
+def OMPC_Fail : Clause<"fail"> {
+  let clangClass = "OMPFailClause";
+}
+def OMPC_Filter : Clause<"filter"> {
+  let clangClass = "OMPFilterClause";
   let flangClass = "ScalarIntExpr";
 }
-
+def OMPC_Final : Clause<"final"> {
+  let clangClass = "OMPFinalClause";
+  let flangClass = "ScalarLogicalExpr";
+}
+def OMPC_FirstPrivate : Clause<"firstprivate"> {
+  let clangClass = "OMPFirstprivateClause";
+  let flangClass = "OmpObjectList";
+}
+def OMPC_Flush : Clause<"flush"> {
+  let clangClass = "OMPFlushClause";
+  let isImplicit = true;
+}
+def OMPC_From : Clause<"from"> {
+  let clangClass = "OMPFromClause";
+  let flangClass = "OmpObjectList";
+}
+def OMPC_Full: Clause<"full"> {
+  let clangClass = "OMPFullClause";
+}
 def OMP_GRAINSIZE_Strict : ClauseVal<"strict", 1, 1> {}
 def OMP_GRAINSIZE_Unknown : ClauseVal<"unkonwn", 2, 0> { let isDefault = 1; }
-
 def OMPC_GrainSize : Clause<"grainsize"> {
   let clangClass = "OMPGrainsizeClause";
   let flangClass = "ScalarIntExpr";
@@ -258,101 +188,128 @@ def OMPC_GrainSize : Clause<"grainsize"> {
     OMP_GRAINSIZE_Unknown
   ];
 }
-def OMPC_NoGroup : Clause<"nogroup"> {
-  let clangClass = "OMPNogroupClause";
-}
-
-def OMP_NUMTASKS_Strict : ClauseVal<"strict", 1, 1> {}
-def OMP_NUMTASKS_Unknown : ClauseVal<"unkonwn", 2, 0> { let isDefault = 1; }
-
-def OMPC_NumTasks : Clause<"num_tasks"> {
-  let clangClass = "OMPNumTasksClause";
-  let flangClass = "ScalarIntExpr";
-  let enumClauseValue = "NumTasksType";
-  let allowedClauseValues = [
-    OMP_NUMTASKS_Strict,
-    OMP_NUMTASKS_Unknown
-  ];
+def OMPC_HasDeviceAddr : Clause<"has_device_addr"> {
+  let clangClass = "OMPHasDeviceAddrClause";
+  let flangClass = "OmpObjectList";
 }
 def OMPC_Hint : Clause<"hint"> {
   let clangClass = "OMPHintClause";
   let flangClass = "ConstantExpr";
 }
-def OMPC_DistSchedule : Clause<"dist_schedule"> {
-  let clangClass = "OMPDistScheduleClause";
-  let flangClass = "ScalarIntExpr";
-  let isValueOptional = true;
+def OMPC_If : Clause<"if"> {
+  let clangClass = "OMPIfClause";
+  let flangClass = "OmpIfClause";
 }
-def OMPC_DefaultMap : Clause<"defaultmap"> {
-  let clangClass = "OMPDefaultmapClause";
-  let flangClass = "OmpDefaultmapClause";
+def OMPC_Inbranch : Clause<"inbranch"> {
 }
-def OMPC_To : Clause<"to"> {
-  let clangClass = "OMPToClause";
-  let flangClass = "OmpObjectList";
+def OMPC_Inclusive : Clause<"inclusive"> {
+  let clangClass = "OMPInclusiveClause";
 }
-def OMPC_Enter : Clause<"enter"> {
-  let flangClass = "OmpObjectList";
+def OMPC_Indirect : Clause<"indirect"> {
 }
-def OMPC_From : Clause<"from"> {
-  let clangClass = "OMPFromClause";
-  let flangClass = "OmpObjectList";
+def OMPC_Init : Clause<"init"> {
+  let clangClass = "OMPInitClause";
 }
-def OMPC_UseDevicePtr : Clause<"use_device_ptr"> {
-  let clangClass = "OMPUseDevicePtrClause";
-  let flangClass = "OmpObjectList";
+def OMPC_InReduction : Clause<"in_reduction"> {
+  let clangClass = "OMPInReductionClause";
+  let flangClass = "OmpInReductionClause";
 }
 def OMPC_IsDevicePtr : Clause<"is_device_ptr"> {
   let clangClass = "OMPIsDevicePtrClause";
   let flangClass = "OmpObjectList";
 }
-def OMPC_HasDeviceAddr : Clause<"has_device_addr"> {
-  let clangClass = "OMPHasDeviceAddrClause";
+def OMPC_LastPrivate : Clause<"lastprivate"> {
+  let clangClass = "OMPLastprivateClause";
   let flangClass = "OmpObjectList";
 }
-def OMPC_TaskReduction : Clause<"task_reduction"> {
-  let clangClass = "OMPTaskReductionClause";
-  let flangClass = "OmpReductionClause";
-}
-def OMPC_InReduction : Clause<"in_reduction"> {
-  let clangClass = "OMPInReductionClause";
-  let flangClass = "OmpInReductionClause";
-}
-def OMPC_UnifiedAddress : Clause<"unified_address"> {
-  let clangClass = "OMPUnifiedAddressClause";
+def OMPC_Linear : Clause<"linear"> {
+  let clangClass = "OMPLinearClause";
+  let flangClass = "OmpLinearClause";
 }
-def OMPC_UnifiedSharedMemory : Clause<"unified_shared_memory"> {
-  let clangClass = "OMPUnifiedSharedMemoryClause";
+def OMPC_Link : Clause<"link"> {
+  let flangClass = "OmpObjectList";
 }
-def OMPC_ReverseOffload : Clause<"reverse_offload"> {
-  let clangClass = "OMPReverseOffloadClause";
+def OMPC_Map : Clause<"map"> {
+  let clangClass = "OMPMapClause";
+  let flangClass = "OmpMapClause";
 }
-def OMPC_DynamicAllocators : Clause<"dynamic_allocators"> {
-  let clangClass = "OMPDynamicAllocatorsClause";
+def OMPC_Match : Clause<"match"> {
 }
-def OMPC_AtomicDefaultMemOrder : Clause<"atomic_default_mem_order"> {
-  let clangClass = "OMPAtomicDefaultMemOrderClause";
-  let flangClass = "OmpAtomicDefaultMemOrderClause";
+def OMP_MEMORY_ORDER_SeqCst : ClauseVal<"seq_cst", 1, 1> {}
+def OMP_MEMORY_ORDER_AcqRel : ClauseVal<"acq_rel", 2, 1> {}
+def OMP_MEMORY_ORDER_Acquire : ClauseVal<"acquire", 3, 1> {}
+def OMP_MEMORY_ORDER_Release : ClauseVal<"release", 4, 1> {}
+def OMP_MEMORY_ORDER_Relaxed : ClauseVal<"relaxed", 5, 1> {}
+def OMP_MEMORY_ORDER_Default : ClauseVal<"default", 6, 0> {
+  let isDefault = 1;
 }
-def OMPC_At : Clause<"at"> {
-  let clangClass = "OMPAtClause";
+def OMPC_MemoryOrder : Clause<"memory_order"> {
+  let enumClauseValue = "MemoryOrderKind";
+  let allowedClauseValues = [
+    OMP_MEMORY_ORDER_SeqCst,
+    OMP_MEMORY_ORDER_AcqRel,
+    OMP_MEMORY_ORDER_Acquire,
+    OMP_MEMORY_ORDER_Release,
+    OMP_MEMORY_ORDER_Relaxed,
+    OMP_MEMORY_ORDER_Default
+  ];
 }
-def OMPC_Severity : Clause<"severity"> {
-  let clangClass = "OMPSeverityClause";
+def OMPC_Mergeable : Clause<"mergeable"> {
+  let clangClass = "OMPMergeableClause";
 }
 def OMPC_Message : Clause<"message"> {
   let clangClass = "OMPMessageClause";
 }
-def OMPC_Allocate : Clause<"allocate"> {
-  let clangClass = "OMPAllocateClause";
-  let flangClass = "OmpAllocateClause";
+def OMPC_Nocontext : Clause<"nocontext"> {
+  let clangClass = "OMPNocontextClause";
+  let flangClass = "ScalarLogicalExpr";
+}
+def OMPC_NoGroup : Clause<"nogroup"> {
+  let clangClass = "OMPNogroupClause";
 }
 def OMPC_NonTemporal : Clause<"nontemporal"> {
   let clangClass = "OMPNontemporalClause";
   let flangClass = "Name";
   let isValueList = true;
 }
-
+def OMPC_Notinbranch : Clause<"notinbranch"> {
+}
+def OMPC_Novariants : Clause<"novariants"> {
+  let clangClass = "OMPNovariantsClause";
+  let flangClass = "ScalarLogicalExpr";
+}
+def OMPC_NoWait : Clause<"nowait"> {
+  let clangClass = "OMPNowaitClause";
+}
+def OMP_NUMTASKS_Strict : ClauseVal<"strict", 1, 1> {}
+def OMP_NUMTASKS_Unknown : ClauseVal<"unkonwn", 2, 0> { let isDefault = 1; }
+def OMPC_NumTasks : Clause<"num_tasks"> {
+  let clangClass = "OMPNumTasksClause";
+  let flangClass = "ScalarIntExpr";
+  let enumClauseValue = "NumTasksType";
+  let allowedClauseValues = [
+    OMP_NUMTASKS_Strict,
+    OMP_NUMTASKS_Unknown
+  ];
+}
+def OMPC_NumTeams : Clause<"num_teams"> {
+  let clangClass = "OMPNumTeamsClause";
+  let flangClass = "ScalarIntExpr";
+}
+def OMPC_NumThreads : Clause<"num_threads"> {
+  let clangClass = "OMPNumThreadsClause";
+  let flangClass = "ScalarIntExpr";
+}
+def OMPC_OMPX_Attribute : Clause<"ompx_attribute"> {
+  let clangClass = "OMPXAttributeClause";
+}
+def OMPC_OMX_Bare : Clause<"ompx_bare"> {
+  let clangClass = "OMPXBareClause";
+}
+def OMPC_OMPX_DynCGroupMem : Clause<"ompx_dyn_cgroup_mem"> {
+  let clangClass = "OMPXDynCGroupMemClause";
+  let flangClass = "ScalarIntExpr";
+}
 def OMP_ORDER_concurrent : ClauseVal<"concurrent",1,1> {}
 def OMP_ORDER_unknown : ClauseVal<"unknown",2,0> { let isDefault = 1; }
 def OMPC_Order : Clause<"order"> {
@@ -364,362 +321,467 @@ def OMPC_Order : Clause<"order"> {
     OMP_ORDER_concurrent
   ];
 }
-def OMPC_Init : Clause<"init"> {
-  let clangClass = "OMPInitClause";
+def OMPC_Ordered : Clause<"ordered"> {
+  let clangClass = "OMPOrderedClause";
+  let flangClass = "ScalarIntConstantExpr";
+  let isValueOptional = true;
 }
-def OMPC_Use : Clause<"use"> {
-  let clangClass = "OMPUseClause";
+def OMPC_Partial: Clause<"partial"> {
+  let clangClass = "OMPPartialClause";
+  let flangClass = "ScalarIntConstantExpr";
+  let isValueOptional = true;
 }
-def OMPC_Destroy : Clause<"destroy"> {
-  let clangClass = "OMPDestroyClause";
+def OMPC_Priority : Clause<"priority"> {
+  let clangClass = "OMPPriorityClause";
+  let flangClass = "ScalarIntExpr";
 }
-def OMPC_Novariants : Clause<"novariants"> {
-  let clangClass = "OMPNovariantsClause";
-  let flangClass = "ScalarLogicalExpr";
+def OMPC_Private : Clause<"private"> {
+  let clangClass = "OMPPrivateClause";
+  let flangClass = "OmpObjectList";
 }
-def OMPC_Nocontext : Clause<"nocontext"> {
-  let clangClass = "OMPNocontextClause";
-  let flangClass = "ScalarLogicalExpr";
+def OMP_PROC_BIND_master : ClauseVal<"master",2,1> {}
+def OMP_PROC_BIND_close : ClauseVal<"close",3,1> {}
+def OMP_PROC_BIND_spread : ClauseVal<"spread",4,1> {}
+def OMP_PROC_BIND_primary : ClauseVal<"primary",5,1> {}
+def OMP_PROC_BIND_default : ClauseVal<"default",6,0> {}
+def OMP_PROC_BIND_unknown : ClauseVal<"unknown",7,0> { let isDefault = true; }
+def OMPC_ProcBind : Clause<"proc_bind"> {
+  let clangClass = "OMPProcBindClause";
+  let flangClass = "OmpProcBindClause";
+  let enumClauseValue = "ProcBindKind";
+  let allowedClauseValues = [
+    OMP_PROC_BIND_primary,
+    OMP_PROC_BIND_master,
+    OMP_PROC_BIND_close,
+    OMP_PROC_BIND_spread,
+    OMP_PROC_BIND_default,
+    OMP_PROC_BIND_unknown
+  ];
 }
-def OMPC_Detach : Clause<"detach"> {
-  let clangClass = "OMPDetachClause";
+def OMPC_Read : Clause<"read"> {
+  let clangClass = "OMPReadClause";
 }
-def OMPC_Inclusive : Clause<"inclusive"> {
-  let clangClass = "OMPInclusiveClause";
+def OMPC_Reduction : Clause<"reduction"> {
+  let clangClass = "OMPReductionClause";
+  let flangClass = "OmpReductionClause";
 }
-def OMPC_Exclusive : Clause<"exclusive"> {
-  let clangClass = "OMPExclusiveClause";
+def OMPC_Relaxed : Clause<"relaxed"> {
+  let clangClass = "OMPRelaxedClause";
 }
-def OMPC_UsesAllocators : Clause<"uses_allocators"> {
-  let clangClass = "OMPUsesAllocatorsClause";
+def OMPC_Release : Clause<"release"> {
+  let clangClass = "OMPReleaseClause";
 }
-def OMPC_Affinity : Clause<"affinity"> {
-  let clangClass = "OMPAffinityClause";
+def OMPC_ReverseOffload : Clause<"reverse_offload"> {
+  let clangClass = "OMPReverseOffloadClause";
 }
-def OMPC_UseDeviceAddr : Clause<"use_device_addr"> {
-  let clangClass = "OMPUseDeviceAddrClause";
+def OMPC_SafeLen : Clause<"safelen"> {
+  let clangClass = "OMPSafelenClause";
+  let flangClass = "ScalarIntConstantExpr";
+}
+def OMP_SCHEDULE_Static : ClauseVal<"static", 2, 1> {}
+def OMP_SCHEDULE_Dynamic : ClauseVal<"dynamic", 3, 1> {}
+def OMP_SCHEDULE_Guided : ClauseVal<"guided", 4, 1> {}
+def OMP_SCHEDULE_Auto : ClauseVal<"auto", 5, 1> {}
+def OMP_SCHEDULE_Runtime : ClauseVal<"runtime", 6, 1> {}
+def OMP_SCHEDULE_Default : ClauseVal<"default", 7, 0> { let isDefault = 1; }
+def OMPC_Schedule : Clause<"schedule"> {
+  let clangClass = "OMPScheduleClause";
+  let flangClass = "OmpScheduleClause";
+  let enumClauseValue = "ScheduleKind";
+  let allowedClauseValues = [
+    OMP_SCHEDULE_Static,
+    OMP_SCHEDULE_Dynamic,
+    OMP_SCHEDULE_Guided,
+    OMP_SCHEDULE_Auto,
+    OMP_SCHEDULE_Runtime,
+    OMP_SCHEDULE_Default
+  ];
+}
+def OMPC_SeqCst : Clause<"seq_cst"> {
+  let clangClass = "OMPSeqCstClause";
+}
+def OMPC_Severity : Clause<"severity"> {
+  let clangClass = "OMPSeverityClause";
+}
+def OMPC_Shared : Clause<"shared"> {
+  let clangClass = "OMPSharedClause";
   let flangClass = "OmpObjectList";
 }
-def OMPC_Uniform : Clause<"uniform"> {
-  let flangClass = "Name";
+def OMPC_Simd : Clause<"simd"> {
+  let clangClass = "OMPSIMDClause";
+}
+def OMPC_SimdLen : Clause<"simdlen"> {
+  let clangClass = "OMPSimdlenClause";
+  let flangClass = "ScalarIntConstantExpr";
+}
+def OMPC_Sizes: Clause<"sizes"> {
+  let clangClass = "OMPSizesClause";
+  let flangClass = "ScalarIntExpr";
   let isValueList = true;
 }
-def OMPC_Match : Clause<"match"> {}
-def OMPC_AdjustArgs : Clause<"adjust_args"> { }
-def OMPC_AppendArgs : Clause<"append_args"> { }
-def OMPC_Depobj : Clause<"depobj"> {
-  let clangClass = "OMPDepobjClause";
-  let isImplicit = true;
+def OMPC_TaskReduction : Clause<"task_reduction"> {
+  let clangClass = "OMPTaskReductionClause";
+  let flangClass = "OmpReductionClause";
 }
-def OMPC_Flush : Clause<"flush"> {
-  let clangClass = "OMPFlushClause";
-  let isImplicit = true;
+def OMPC_ThreadLimit : Clause<"thread_limit"> {
+  let clangClass = "OMPThreadLimitClause";
+  let flangClass = "ScalarIntExpr";
 }
 def OMPC_ThreadPrivate : Clause<"threadprivate"> {
   let alternativeName = "threadprivate or thread local";
   let isImplicit = true;
 }
+def OMPC_Threads : Clause<"threads"> {
+  let clangClass = "OMPThreadsClause";
+}
+def OMPC_To : Clause<"to"> {
+  let clangClass = "OMPToClause";
+  let flangClass = "OmpObjectList";
+}
+def OMPC_UnifiedAddress : Clause<"unified_address"> {
+  let clangClass = "OMPUnifiedAddressClause";
+}
+def OMPC_UnifiedSharedMemory : Clause<"unified_shared_memory"> {
+  let clangClass = "OMPUnifiedSharedMemoryClause";
+}
+def OMPC_Uniform : Clause<"uniform"> {
+  let flangClass = "Name";
+  let isValueList = true;
+}
 def OMPC_Unknown : Clause<"unknown"> {
   let isImplicit = true;
   let isDefault = true;
 }
-def OMPC_Link : Clause<"link"> {
-  let flangClass = "OmpObjectList";
+def OMPC_Untied : Clause<"untied"> {
+  let clangClass = "OMPUntiedClause";
 }
-def OMPC_Indirect : Clause<"indirect"> {}
-def OMPC_Inbranch : Clause<"inbranch"> {}
-def OMPC_Notinbranch : Clause<"notinbranch"> {}
-def OMPC_Filter : Clause<"filter"> {
-  let clangClass = "OMPFilterClause";
-  let flangClass = "ScalarIntExpr";
+def OMPC_Update : Clause<"update"> {
+  let clangClass = "OMPUpdateClause";
 }
-def OMPC_Align : Clause<"align"> {
-  let clangClass = "OMPAlignClause";
+def OMPC_Use : Clause<"use"> {
+  let clangClass = "OMPUseClause";
 }
-def OMPC_When: Clause<"when"> {}
-
-def OMPC_Bind : Clause<"bind"> {
-  let clangClass = "OMPBindClause";
+def OMPC_UsesAllocators : Clause<"uses_allocators"> {
+  let clangClass = "OMPUsesAllocatorsClause";
 }
-
-def OMPC_OMPX_DynCGroupMem : Clause<"ompx_dyn_cgroup_mem"> {
-  let clangClass = "OMPXDynCGroupMemClause";
-  let flangClass = "ScalarIntExpr";
+def OMPC_UseDeviceAddr : Clause<"use_device_addr"> {
+  let clangClass = "OMPUseDeviceAddrClause";
+  let flangClass = "OmpObjectList";
 }
-
-def OMPC_Doacross : Clause<"doacross"> {
-  let clangClass = "OMPDoacrossClause";
+def OMPC_UseDevicePtr : Clause<"use_device_ptr"> {
+  let clangClass = "OMPUseDevicePtrClause";
+  let flangClass = "OmpObjectList";
 }
-
-def OMPC_OMPX_Attribute : Clause<"ompx_attribute"> {
-  let clangClass = "OMPXAttributeClause";
+def OMPC_Weak : Clause<"weak"> {
+  let clangClass = "OMPWeakClause";
 }
-
-def OMPC_OMX_Bare : Clause<"ompx_bare"> {
-  let clangClass = "OMPXBareClause";
+def OMPC_When: Clause<"when"> {
+}
+def OMPC_Write : Clause<"write"> {
+  let clangClass = "OMPWriteClause";
 }
 
 //===----------------------------------------------------------------------===//
-// Definition of OpenMP directives
+// Definitions of OpenMP leaf directives
+// Sorted alphabetically wrt directive spelling, except "end xyz" immediately
+// follows "xyz".
 //===----------------------------------------------------------------------===//
 
-def OMP_ThreadPrivate : Directive<"threadprivate"> {
+def OMP_Allocate : Directive<"allocate"> {
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_Align, 51>,
+    VersionedClause<OMPC_Allocator>,
+  ];
   let association = AS_None;
 }
-def OMP_Parallel : Directive<"parallel"> {
+def OMP_Allocators : Directive<"allocators"> {
   let allowedClauses = [
-    VersionedClause<OMPC_Private>,
-    VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Copyin>,
     VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_OMPX_Attribute>,
+  ];
+  let association = AS_Block;
+}
+def OMP_Assumes : Directive<"assumes"> {
+  let association = AS_None;
+}
+def OMP_EndAssumes : Directive<"end assumes"> {
+  let association = AS_Delimited;
+}
+def OMP_Atomic : Directive<"atomic"> {
+  let allowedClauses = [
+    VersionedClause<OMPC_Capture>,
+    VersionedClause<OMPC_Compare, 51>,
+    VersionedClause<OMPC_Read>,
+    VersionedClause<OMPC_Update>,
+    VersionedClause<OMPC_Write>,
   ];
   let allowedOnceClauses = [
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_NumThreads>,
-    VersionedClause<OMPC_ProcBind>,
+    VersionedClause<OMPC_AcqRel, 50>,
+    VersionedClause<OMPC_Acquire, 50>,
+    VersionedClause<OMPC_Fail, 51>,
+    VersionedClause<OMPC_Hint, 50>,
+    VersionedClause<OMPC_Relaxed, 50>,
+    VersionedClause<OMPC_Release, 50>,
+    VersionedClause<OMPC_SeqCst>,
+    VersionedClause<OMPC_Weak, 51>,
   ];
   let association = AS_Block;
 }
-def OMP_Task : Directive<"task"> {
+def OMP_Barrier : Directive<"barrier"> {
+  let association = AS_None;
+}
+def OMP_BeginAssumes : Directive<"begin assumes"> {
+  let association = AS_Delimited;
+}
+def OMP_BeginDeclareTarget : Directive<"begin declare target"> {
   let allowedClauses = [
-    VersionedClause<OMPC_Private>,
-    VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Untied>,
-    VersionedClause<OMPC_Mergeable>,
-    VersionedClause<OMPC_Depend>,
-    VersionedClause<OMPC_InReduction>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_Detach, 50>,
-    VersionedClause<OMPC_Affinity, 50>
+    VersionedClause<OMPC_DeviceType>,
+    VersionedClause<OMPC_Indirect>,
+    VersionedClause<OMPC_Link>,
+    VersionedClause<OMPC_To>,
   ];
+  let association = AS_Delimited;
+}
+def OMP_BeginDeclareVariant : Directive<"begin declare variant"> {
+  let association = AS_Delimited;
+}
+def OMP_Cancel : Directive<"cancel"> {
   let allowedOnceClauses = [
-    VersionedClause<OMPC_Default>,
     VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_Final>,
-    VersionedClause<OMPC_Priority>
+  ];
+  let association = AS_None;
+}
+def OMP_CancellationPoint : Directive<"cancellation point"> {
+  let association = AS_None;
+}
+def OMP_Critical : Directive<"critical"> {
+  let allowedClauses = [
+    VersionedClause<OMPC_Hint>,
   ];
   let association = AS_Block;
 }
-def OMP_Simd : Directive<"simd"> {
+def OMP_DeclareMapper : Directive<"declare mapper"> {
+  let allowedClauses = [
+    VersionedClause<OMPC_Map>,
+  ];
+  let association = AS_None;
+}
+def OMP_DeclareReduction : Directive<"declare reduction"> {
+  let association = AS_None;
+}
+def OMP_DeclareSimd : Directive<"declare simd"> {
   let allowedClauses = [
-    VersionedClause<OMPC_Private>,
-    VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Linear>,
     VersionedClause<OMPC_Aligned>,
-    VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_NonTemporal, 50>,
+    VersionedClause<OMPC_Linear>,
+    VersionedClause<OMPC_Uniform>,
   ];
   let allowedOnceClauses = [
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_SafeLen>,
     VersionedClause<OMPC_SimdLen>,
-    VersionedClause<OMPC_If, 50>,
-    VersionedClause<OMPC_Order, 50>
   ];
-  let association = AS_Loop;
+  let allowedExclusiveClauses = [
+    VersionedClause<OMPC_Inbranch>,
+    VersionedClause<OMPC_Notinbranch>,
+  ];
+  let association = AS_Declaration;
 }
-def OMP_Tile : Directive<"tile"> {
+def OMP_DeclareTarget : Directive<"declare target"> {
+  let allowedClauses = [
+    VersionedClause<OMPC_Enter, 52>,
+    VersionedClause<OMPC_Indirect>,
+    VersionedClause<OMPC_Link>,
+    VersionedClause<OMPC_To>,
+  ];
   let allowedOnceClauses = [
-    VersionedClause<OMPC_Sizes, 51>,
+    VersionedClause<OMPC_DeviceType, 50>,
   ];
-  let association = AS_Loop;
+  let association = AS_None;
 }
-def OMP_Unroll : Directive<"unroll"> {
-  let allowedOnceClauses = [
-    VersionedClause<OMPC_Full, 51>,
-    VersionedClause<OMPC_Partial, 51>,
+def OMP_EndDeclareTarget : Directive<"end declare target"> {
+  let association = AS_Delimited;
+}
+def OMP_DeclareVariant : Directive<"declare variant"> {
+  let allowedClauses = [
+    VersionedClause<OMPC_Match>,
   ];
-  let association = AS_Loop;
+  let allowedExclusiveClauses = [
+    VersionedClause<OMPC_AdjustArgs, 51>,
+    VersionedClause<OMPC_AppendArgs, 51>,
+  ];
+  let association = AS_Declaration;
 }
-def OMP_For : Directive<"for"> {
+def OMP_EndDeclareVariant : Directive<"end declare variant"> {
+  let association = AS_Delimited;
+}
+def OMP_Depobj : Directive<"depobj"> {
   let allowedClauses = [
-    VersionedClause<OMPC_Private>,
-    VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_Schedule>,
-    VersionedClause<OMPC_Ordered>,
+    VersionedClause<OMPC_Depend, 50>,
+    // TODO This should ne `none` instead. Comment carried over from
+    // OMPKinds.def.
+    VersionedClause<OMPC_Depobj, 50>,
+    VersionedClause<OMPC_Destroy, 50>,
+    VersionedClause<OMPC_Update, 50>,
+  ];
+  let association = AS_None;
+}
+def OMP_dispatch : Directive<"dispatch"> {
+  let allowedClauses = [
+    VersionedClause<OMPC_Depend>,
+    VersionedClause<OMPC_Device>,
+    VersionedClause<OMPC_HasDeviceAddr, 51>,
+    VersionedClause<OMPC_IsDevicePtr>,
+    VersionedClause<OMPC_Nocontext>,
+    VersionedClause<OMPC_Novariants>,
     VersionedClause<OMPC_NoWait>,
-    VersionedClause<OMPC_Linear>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_Order, 50>
   ];
-  let association = AS_Loop;
+  let association = AS_Block;
 }
-def OMP_Do : Directive<"do"> {
+def OMP_Distribute : Directive<"distribute"> {
   let allowedClauses = [
-    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Allocate>,
     VersionedClause<OMPC_FirstPrivate>,
     VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Linear>,
-    VersionedClause<OMPC_Reduction>
+    VersionedClause<OMPC_Private>,
   ];
   let allowedOnceClauses = [
-    VersionedClause<OMPC_Schedule>,
     VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_Ordered>,
-    VersionedClause<OMPC_NoWait>,
-    VersionedClause<OMPC_Order, 50>
+    VersionedClause<OMPC_DistSchedule>,
   ];
   let association = AS_Loop;
 }
-def OMP_Sections : Directive<"sections"> {
+def OMP_Do : Directive<"do"> {
   let allowedClauses = [
-    VersionedClause<OMPC_Private>,
-    VersionedClause<OMPC_LastPrivate>,
     VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_LastPrivate>,
+    VersionedClause<OMPC_Linear>,
+    VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_NoWait>,
-    VersionedClause<OMPC_Allocate>
   ];
-  let association = AS_Block;
-}
-def OMP_Section : Directive<"section"> {
-  let association = AS_Separating;
-}
-def OMP_Single : Directive<"single"> {
-  let allowedClauses = [
-    VersionedClause<OMPC_Private>,
-    VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_CopyPrivate>,
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_Collapse>,
     VersionedClause<OMPC_NoWait>,
-    VersionedClause<OMPC_Allocate>
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_Ordered>,
+    VersionedClause<OMPC_Schedule>,
   ];
-  let association = AS_Block;
-}
-def OMP_Master : Directive<"master"> {
-  let association = AS_Block;
+  let association = AS_Loop;
 }
-def OMP_Critical : Directive<"critical"> {
-  let allowedClauses = [
-    VersionedClause<OMPC_Hint>
+def OMP_EndDo : Directive<"end do"> {
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_NoWait>,
   ];
-  let association = AS_Block;
-}
-def OMP_TaskYield : Directive<"taskyield"> {
-  let association = AS_None;
-}
-def OMP_Barrier : Directive<"barrier"> {
-  let association = AS_None;
+  // Needed for association computation, since OMP_Do has it "from leafConstructs".
+  let leafConstructs = OMP_Do.leafConstructs;
+  let association = OMP_Do.association;
 }
 def OMP_Error : Directive<"error"> {
   let allowedClauses = [
     VersionedClause<OMPC_At, 51>,
+    VersionedClause<OMPC_Message, 51>,
     VersionedClause<OMPC_Severity, 51>,
-    VersionedClause<OMPC_Message, 51>
-  ];
-  let association = AS_None;
-}
-def OMP_TaskWait : Directive<"taskwait"> {
-  let allowedClauses = [
-    VersionedClause<OMPC_Depend, 50>,
-    VersionedClause<OMPC_NoWait, 51>
   ];
   let association = AS_None;
 }
-def OMP_TaskGroup : Directive<"taskgroup"> {
-  let allowedClauses = [
-    VersionedClause<OMPC_TaskReduction, 50>,
-    VersionedClause<OMPC_Allocate, 50>
-  ];
-  let association = AS_Block;
-}
 def OMP_Flush : Directive<"flush"> {
   let allowedOnceClauses = [
     VersionedClause<OMPC_AcqRel, 50>,
     VersionedClause<OMPC_Acquire, 50>,
-    VersionedClause<OMPC_Release, 50>,
     // TODO This should ne `none` instead. Comment carried over from
     // OMPKinds.def.
-    VersionedClause<OMPC_Flush>
+    VersionedClause<OMPC_Flush>,
+    VersionedClause<OMPC_Release, 50>,
   ];
   let association = AS_None;
 }
-def OMP_Ordered : Directive<"ordered"> {
+def OMP_For : Directive<"for"> {
   let allowedClauses = [
-    VersionedClause<OMPC_Depend>,
-    VersionedClause<OMPC_Doacross, 52>
-  ];
-  let allowedOnceClauses = [
-    VersionedClause<OMPC_Threads>,
-    VersionedClause<OMPC_Simd>
-  ];
-  let association = AS_None;
-  // There is also a block-associated "ordered" directive.
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_LastPrivate>,
+    VersionedClause<OMPC_Linear>,
+    VersionedClause<OMPC_NoWait>,
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_Ordered>,
+    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Reduction>,
+    VersionedClause<OMPC_Schedule>,
+  ];
+  let association = AS_Loop;
 }
-def OMP_Atomic : Directive<"atomic"> {
+def OMP_interop : Directive<"interop"> {
   let allowedClauses = [
-    VersionedClause<OMPC_Read>,
-    VersionedClause<OMPC_Write>,
-    VersionedClause<OMPC_Update>,
-    VersionedClause<OMPC_Capture>,
-    VersionedClause<OMPC_Compare, 51>
+    VersionedClause<OMPC_Depend>,
+    VersionedClause<OMPC_Destroy>,
+    VersionedClause<OMPC_Device>,
+    VersionedClause<OMPC_Init>,
+    VersionedClause<OMPC_NoWait>,
+    VersionedClause<OMPC_Use>,
+  ];
+  let association = AS_None;
+}
+def OMP_loop : Directive<"loop"> {
+  let allowedClauses = [
+    VersionedClause<OMPC_LastPrivate>,
+    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Reduction>,
   ];
   let allowedOnceClauses = [
-    VersionedClause<OMPC_SeqCst>,
-    VersionedClause<OMPC_AcqRel, 50>,
-    VersionedClause<OMPC_Acquire, 50>,
-    VersionedClause<OMPC_Release, 50>,
-    VersionedClause<OMPC_Relaxed, 50>,
-    VersionedClause<OMPC_Hint, 50>,
-    VersionedClause<OMPC_Fail, 51>,
-    VersionedClause<OMPC_Weak, 51>
+    VersionedClause<OMPC_Bind, 50>,
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_Order, 50>,
+  ];
+  let association = AS_Loop;
+}
+def OMP_masked : Directive<"masked"> {
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_Filter>,
   ];
   let association = AS_Block;
 }
-def OMP_Target : Directive<"target"> {
+def OMP_Master : Directive<"master"> {
+  let association = AS_Block;
+}
+def OMP_Metadirective : Directive<"metadirective"> {
+  let allowedClauses = [
+    VersionedClause<OMPC_When>,
+  ];
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_Default>,
+  ];
+  let association = AS_None;
+}
+def OMP_Nothing : Directive<"nothing"> {
+  let association = AS_None;
+}
+def OMP_Ordered : Directive<"ordered"> {
   let allowedClauses = [
-    VersionedClause<OMPC_Map>,
-    VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_Depend>,
-    VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_IsDevicePtr>,
-    VersionedClause<OMPC_HasDeviceAddr, 51>,
-    VersionedClause<OMPC_InReduction, 50>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_UsesAllocators, 50>,
-    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Doacross, 52>,
   ];
   let allowedOnceClauses = [
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_Device>,
-    VersionedClause<OMPC_ThreadLimit, 51>,
-    VersionedClause<OMPC_DefaultMap>,
-    VersionedClause<OMPC_NoWait>,
-    VersionedClause<OMPC_OMPX_DynCGroupMem>,
+    VersionedClause<OMPC_Simd>,
+    VersionedClause<OMPC_Threads>,
   ];
-  let association = AS_Block;
+  let association = AS_None;
+  // There is also a block-associated "ordered" directive.
 }
-def OMP_Teams : Directive<"teams"> {
+def OMP_Parallel : Directive<"parallel"> {
   let allowedClauses = [
-    VersionedClause<OMPC_Private>,
-    VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Reduction>,
     VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Copyin>,
+    VersionedClause<OMPC_FirstPrivate>,
     VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Reduction>,
+    VersionedClause<OMPC_Shared>,
   ];
   let allowedOnceClauses = [
     VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_If, 52>,
-    VersionedClause<OMPC_NumTeams>,
-    VersionedClause<OMPC_ThreadLimit>
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_ProcBind>,
   ];
   let association = AS_Block;
 }
-def OMP_Cancel : Directive<"cancel"> {
-  let allowedOnceClauses = [
-    VersionedClause<OMPC_If>
-  ];
-  let association = AS_None;
-}
 def OMP_Requires : Directive<"requires"> {
   let allowedOnceClauses = [
     VersionedClause<OMPC_UnifiedAddress>,
@@ -732,1596 +794,1564 @@ def OMP_Requires : Directive<"requires"> {
     //
     // TODO: Correct this supprted version number whenever complete
     // implementation of reverse_offload is available.
-    VersionedClause<OMPC_ReverseOffload, 99>,
+    VersionedClause<OMPC_AtomicDefaultMemOrder>,
     VersionedClause<OMPC_DynamicAllocators>,
-    VersionedClause<OMPC_AtomicDefaultMemOrder>
+    VersionedClause<OMPC_ReverseOffload, 99>,
   ];
   let association = AS_None;
 }
-def OMP_Nothing : Directive<"nothing"> {
-  let association = AS_None;
+def OMP_Scan : Directive<"scan"> {
+  let allowedClauses = [
+    VersionedClause<OMPC_Exclusive, 50>,
+    VersionedClause<OMPC_Inclusive, 50>,
+  ];
+  let association = AS_Separating;
+}
+def OMP_scope : Directive<"scope"> {
+  let allowedClauses = [
+    VersionedClause<OMPC_Private, 51>,
+    VersionedClause<OMPC_Reduction, 51>,
+  ];
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_NoWait, 51>,
+  ];
+  let association = AS_Block;
+}
+def OMP_Section : Directive<"section"> {
+  let association = AS_Separating;
+}
+def OMP_Sections : Directive<"sections"> {
+  let allowedClauses = [
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_LastPrivate>,
+    VersionedClause<OMPC_NoWait>,
+    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Reduction>,
+  ];
+  let association = AS_Block;
+}
+def OMP_EndSections : Directive<"end sections"> {
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_NoWait>,
+  ];
+  let leafConstructs = OMP_Sections.leafConstructs;
+  let association = OMP_Sections.association;
+}
+def OMP_Simd : Directive<"simd"> {
+  let allowedClauses = [
+    VersionedClause<OMPC_Aligned>,
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_LastPrivate>,
+    VersionedClause<OMPC_Linear>,
+    VersionedClause<OMPC_NonTemporal, 50>,
+    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Reduction>,
+  ];
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_If, 50>,
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_SafeLen>,
+    VersionedClause<OMPC_SimdLen>,
+  ];
+  let association = AS_Loop;
+}
+def OMP_Single : Directive<"single"> {
+  let allowedClauses = [
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_CopyPrivate>,
+    VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_NoWait>,
+    VersionedClause<OMPC_Private>,
+  ];
+  let association = AS_Block;
+}
+def OMP_EndSingle : Directive<"end single"> {
+  let allowedClauses = [
+    VersionedClause<OMPC_CopyPrivate>,
+  ];
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_NoWait>,
+  ];
+  let leafConstructs = OMP_Single.leafConstructs;
+  let association = OMP_Single.association;
+}
+def OMP_Target : Directive<"target"> {
+  let allowedClauses = [
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Depend>,
+    VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_HasDeviceAddr, 51>,
+    VersionedClause<OMPC_InReduction, 50>,
+    VersionedClause<OMPC_IsDevicePtr>,
+    VersionedClause<OMPC_Map>,
+    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_UsesAllocators, 50>,
+  ];
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_DefaultMap>,
+    VersionedClause<OMPC_Device>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_NoWait>,
+    VersionedClause<OMPC_OMPX_DynCGroupMem>,
+    VersionedClause<OMPC_ThreadLimit, 51>,
+  ];
+  let association = AS_Block;
 }
 def OMP_TargetData : Directive<"target data"> {
   let allowedOnceClauses = [
     VersionedClause<OMPC_Device>,
-    VersionedClause<OMPC_If>
+    VersionedClause<OMPC_If>,
   ];
   let requiredClauses = [
     VersionedClause<OMPC_Map>,
+    VersionedClause<OMPC_UseDeviceAddr, 50>,
     VersionedClause<OMPC_UseDevicePtr>,
-    VersionedClause<OMPC_UseDeviceAddr, 50>
   ];
   let association = AS_Block;
 }
 def OMP_TargetEnterData : Directive<"target enter data"> {
   let allowedClauses = [
-    VersionedClause<OMPC_Depend>
+    VersionedClause<OMPC_Depend>,
   ];
   let allowedOnceClauses = [
-    VersionedClause<OMPC_If>,
     VersionedClause<OMPC_Device>,
-    VersionedClause<OMPC_NoWait>
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_NoWait>,
   ];
   let requiredClauses = [
-    VersionedClause<OMPC_Map>
+    VersionedClause<OMPC_Map>,
   ];
   let association = AS_None;
 }
 def OMP_TargetExitData : Directive<"target exit data"> {
   let allowedClauses = [
-    VersionedClause<OMPC_Depend>
+    VersionedClause<OMPC_Depend>,
   ];
   let allowedOnceClauses = [
     VersionedClause<OMPC_Device>,
     VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_NoWait>
+    VersionedClause<OMPC_NoWait>,
   ];
   let requiredClauses = [
-    VersionedClause<OMPC_Map>
+    VersionedClause<OMPC_Map>,
   ];
   let association = AS_None;
 }
-def OMP_TargetParallel : Directive<"target parallel"> {
+def OMP_TargetUpdate : Directive<"target update"> {
   let allowedClauses = [
+    VersionedClause<OMPC_Depend>,
+    VersionedClause<OMPC_From>,
+    VersionedClause<OMPC_To>,
+  ];
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_Device>,
     VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_Map>,
     VersionedClause<OMPC_NoWait>,
+  ];
+  let association = AS_None;
+}
+def OMP_Task : Directive<"task"> {
+  let allowedClauses = [
+    VersionedClause<OMPC_Affinity, 50>,
+    VersionedClause<OMPC_Allocate>,
     VersionedClause<OMPC_Depend>,
-    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Detach, 50>,
     VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_InReduction>,
+    VersionedClause<OMPC_Mergeable>,
+    VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_IsDevicePtr>,
-    VersionedClause<OMPC_HasDeviceAddr, 51>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_UsesAllocators, 50>,
-    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Untied>,
   ];
   let allowedOnceClauses = [
-    VersionedClause<OMPC_DefaultMap>,
-    VersionedClause<OMPC_Device>,
-    VersionedClause<OMPC_NumThreads>,
-    VersionedClause<OMPC_ProcBind>,
-    VersionedClause<OMPC_OMPX_DynCGroupMem>,
-    VersionedClause<OMPC_ThreadLimit, 51>,
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_Final>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_Priority>,
   ];
-  let leafConstructs = [OMP_Target, OMP_Parallel];
+  let association = AS_Block;
 }
-def OMP_TargetParallelFor : Directive<"target parallel for"> {
+def OMP_TaskGroup : Directive<"taskgroup"> {
   let allowedClauses = [
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_Device>,
-    VersionedClause<OMPC_Map>,
-    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Allocate, 50>,
+    VersionedClause<OMPC_TaskReduction, 50>,
+  ];
+  let association = AS_Block;
+}
+def OMP_TaskLoop : Directive<"taskloop"> {
+  let allowedClauses = [
+    VersionedClause<OMPC_Allocate>,
     VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_InReduction>,
     VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_NoWait>,
-    VersionedClause<OMPC_Depend>,
-    VersionedClause<OMPC_DefaultMap>,
-    VersionedClause<OMPC_NumThreads>,
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_ProcBind>,
-    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_Mergeable>,
+    VersionedClause<OMPC_NoGroup>,
+    VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_Schedule>,
-    VersionedClause<OMPC_Ordered>,
-    VersionedClause<OMPC_Linear>,
-    VersionedClause<OMPC_IsDevicePtr>,
-    VersionedClause<OMPC_HasDeviceAddr, 51>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_Order, 50>,
-    VersionedClause<OMPC_UsesAllocators, 50>,
-    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_Untied>,
   ];
   let allowedOnceClauses = [
-    VersionedClause<OMPC_OMPX_DynCGroupMem>,
-    VersionedClause<OMPC_ThreadLimit, 51>,
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_Final>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_Priority>,
   ];
-  let leafConstructs = [OMP_Target, OMP_Parallel, OMP_For];
+  let allowedExclusiveClauses = [
+    VersionedClause<OMPC_GrainSize>,
+    VersionedClause<OMPC_NumTasks>,
+  ];
+  let association = AS_Loop;
 }
-def OMP_TargetParallelDo : Directive<"target parallel do"> {
+def OMP_TaskWait : Directive<"taskwait"> {
   let allowedClauses = [
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_Map>,
-    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Depend, 50>,
+    VersionedClause<OMPC_NoWait, 51>,
+  ];
+  let association = AS_None;
+}
+def OMP_TaskYield : Directive<"taskyield"> {
+  let association = AS_None;
+}
+def OMP_Teams : Directive<"teams"> {
+  let allowedClauses = [
+    VersionedClause<OMPC_Allocate>,
     VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Depend>,
-    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Linear>,
-    VersionedClause<OMPC_IsDevicePtr>,
-    VersionedClause<OMPC_HasDeviceAddr, 51>,
-    VersionedClause<OMPC_Allocator>,
-    VersionedClause<OMPC_UsesAllocators>,
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_Copyin>
+    VersionedClause<OMPC_Shared>,
   ];
   let allowedOnceClauses = [
-    VersionedClause<OMPC_NumThreads>,
-    VersionedClause<OMPC_ProcBind>,
-    VersionedClause<OMPC_Device>,
-    VersionedClause<OMPC_DefaultMap>,
-    VersionedClause<OMPC_Schedule>,
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_Ordered>,
-    VersionedClause<OMPC_NoWait>,
-    VersionedClause<OMPC_Order, 50>
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_If, 52>,
+    VersionedClause<OMPC_NumTeams>,
+    VersionedClause<OMPC_ThreadLimit>,
   ];
-  let leafConstructs = [OMP_Target, OMP_Parallel, OMP_Do];
+  let association = AS_Block;
 }
-def OMP_TargetUpdate : Directive<"target update"> {
-  let allowedClauses = [
-    VersionedClause<OMPC_To>,
-    VersionedClause<OMPC_From>,
-    VersionedClause<OMPC_Depend>
-  ];
+def OMP_ThreadPrivate : Directive<"threadprivate"> {
+  let association = AS_None;
+}
+def OMP_Tile : Directive<"tile"> {
   let allowedOnceClauses = [
-    VersionedClause<OMPC_Device>,
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_NoWait>
+    VersionedClause<OMPC_Sizes, 51>,
   ];
+  let association = AS_Loop;
+}
+def OMP_Unknown : Directive<"unknown"> {
+  let isDefault = true;
   let association = AS_None;
 }
-def OMP_masked : Directive<"masked"> {
+def OMP_Unroll : Directive<"unroll"> {
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_Full, 51>,
+    VersionedClause<OMPC_Partial, 51>,
+  ];
+  let association = AS_Loop;
+}
+def OMP_Workshare : Directive<"workshare"> {
   let allowedOnceClauses = [
-    VersionedClause<OMPC_Filter>
+    VersionedClause<OMPC_NoWait>,
   ];
   let association = AS_Block;
 }
-def OMP_ParallelFor : Directive<"parallel for"> {
+def OMP_EndWorkshare : Directive<"end workshare"> {
   let allowedClauses = [
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_NumThreads>,
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_ProcBind>,
-    VersionedClause<OMPC_Private>,
-    VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Copyin>,
-    VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_Schedule>,
-    VersionedClause<OMPC_Ordered>,
-    VersionedClause<OMPC_Linear>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_Order, 50>,
-    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_NoWait>,
   ];
-  let leafConstructs = [OMP_Parallel, OMP_For];
+  let leafConstructs = OMP_Workshare.leafConstructs;
+  let association = OMP_Workshare.association;
 }
-def OMP_ParallelDo : Directive<"parallel do"> {
+
+//===----------------------------------------------------------------------===//
+// Definitions of OpenMP compound directives
+// Sorted alphabetically wrt directive spelling, except "end xyz" immediately
+// follows "xyz".
+//===----------------------------------------------------------------------===//
+
+def OMP_DistributeParallelDo : Directive<"distribute parallel do"> {
   let allowedClauses = [
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Copyin>,
     VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Copyin>,
     VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Linear>
+    VersionedClause<OMPC_Linear>,
+    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Reduction>,
+    VersionedClause<OMPC_Shared>,
   ];
   let allowedOnceClauses = [
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_DistSchedule>,
     VersionedClause<OMPC_If>,
     VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_Ordered>,
     VersionedClause<OMPC_ProcBind>,
     VersionedClause<OMPC_Schedule>,
-    VersionedClause<OMPC_Ordered>,
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_Order, 50>
   ];
-  let leafConstructs = [OMP_Parallel, OMP_Do];
+  let leafConstructs = [OMP_Distribute, OMP_Parallel, OMP_Do];
 }
-def OMP_ParallelForSimd : Directive<"parallel for simd"> {
+def OMP_DistributeParallelDoSimd : Directive<"distribute parallel do simd"> {
   let allowedClauses = [
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_NumThreads>,
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_ProcBind>,
-    VersionedClause<OMPC_Private>,
-    VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Copyin>,
-    VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_Schedule>,
-    VersionedClause<OMPC_SafeLen>,
-    VersionedClause<OMPC_SimdLen>,
-    VersionedClause<OMPC_Linear>,
     VersionedClause<OMPC_Aligned>,
-    VersionedClause<OMPC_Ordered>,
     VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_NonTemporal, 50>,
-    VersionedClause<OMPC_Order, 50>,
-    VersionedClause<OMPC_OMPX_Attribute>,
-  ];
-  let leafConstructs = [OMP_Parallel, OMP_For, OMP_Simd];
-}
-def OMP_ParallelDoSimd : Directive<"parallel do simd"> {
-  let allowedClauses = [
-    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_Copyin>,
     VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_DistSchedule>,
     VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Copyin>,
+    VersionedClause<OMPC_If>,
     VersionedClause<OMPC_LastPrivate>,
     VersionedClause<OMPC_Linear>,
-    VersionedClause<OMPC_Aligned>,
-    VersionedClause<OMPC_Allocate>,
     VersionedClause<OMPC_NonTemporal>,
-  ];
-  let allowedOnceClauses = [
     VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_ProcBind>,
-    VersionedClause<OMPC_Schedule>,
-    VersionedClause<OMPC_Ordered>,
-    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_Reduction>,
     VersionedClause<OMPC_SafeLen>,
+    VersionedClause<OMPC_Schedule>,
+    VersionedClause<OMPC_Shared>,
     VersionedClause<OMPC_SimdLen>,
-    VersionedClause<OMPC_Order, 50>
   ];
-  let leafConstructs = [OMP_Parallel, OMP_Do, OMP_Simd];
+  let leafConstructs = [OMP_Distribute, OMP_Parallel, OMP_Do, OMP_Simd];
 }
-def OMP_ParallelMaster : Directive<"parallel master"> {
+def OMP_DistributeParallelFor : Directive<"distribute parallel for"> {
   let allowedClauses = [
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_Copyin>,
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_DistSchedule>,
+    VersionedClause<OMPC_FirstPrivate>,
     VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_LastPrivate>,
     VersionedClause<OMPC_NumThreads>,
-    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Order, 50>,
     VersionedClause<OMPC_Private>,
-    VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Copyin>,
-    VersionedClause<OMPC_Reduction>,
     VersionedClause<OMPC_ProcBind>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Reduction>,
+    VersionedClause<OMPC_Schedule>,
+    VersionedClause<OMPC_Shared>,
   ];
-  let leafConstructs = [OMP_Parallel, OMP_Master];
+  let leafConstructs = [OMP_Distribute, OMP_Parallel, OMP_For];
 }
-def OMP_ParallelMasked : Directive<"parallel masked"> {
+def OMP_DistributeParallelForSimd : Directive<"distribute parallel for simd"> {
   let allowedClauses = [
+    VersionedClause<OMPC_Aligned>,
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_Copyin>,
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_DistSchedule>,
+    VersionedClause<OMPC_FirstPrivate>,
     VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_LastPrivate>,
+    VersionedClause<OMPC_Linear>,
+    VersionedClause<OMPC_NonTemporal, 50>,
     VersionedClause<OMPC_NumThreads>,
-    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Order, 50>,
     VersionedClause<OMPC_Private>,
-    VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Copyin>,
-    VersionedClause<OMPC_Reduction>,
     VersionedClause<OMPC_ProcBind>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_Filter>,
-    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Reduction>,
+    VersionedClause<OMPC_SafeLen>,
+    VersionedClause<OMPC_Schedule>,
+    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_SimdLen>,
   ];
-  let leafConstructs = [OMP_Parallel, OMP_masked];
+  let leafConstructs = [OMP_Distribute, OMP_Parallel, OMP_For, OMP_Simd];
 }
-def OMP_ParallelSections : Directive<"parallel sections"> {
+def OMP_DistributeSimd : Directive<"distribute simd"> {
   let allowedClauses = [
+    VersionedClause<OMPC_Aligned>,
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Copyin>,
     VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_ProcBind>,
-    VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Copyin>,
     VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_OMPX_Attribute>,
-  ];
-  let allowedOnceClauses = [
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_NumThreads>
-  ];
-  let leafConstructs = [OMP_Parallel, OMP_Sections];
-}
-def OMP_ForSimd : Directive<"for simd"> {
-  let allowedClauses = [
+    VersionedClause<OMPC_Linear>,
+    VersionedClause<OMPC_NonTemporal, 50>,
     VersionedClause<OMPC_Private>,
-    VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_LastPrivate>,
     VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Schedule>,
+  ];
+  let allowedOnceClauses = [
     VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_NoWait>,
+    VersionedClause<OMPC_DistSchedule>,
+    VersionedClause<OMPC_If, 50>,
+    VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_Ordered>,
+    VersionedClause<OMPC_ProcBind>,
     VersionedClause<OMPC_SafeLen>,
+    VersionedClause<OMPC_Schedule>,
     VersionedClause<OMPC_SimdLen>,
-    VersionedClause<OMPC_Linear>,
-    VersionedClause<OMPC_Aligned>,
-    VersionedClause<OMPC_Ordered>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_If, 50>,
-    VersionedClause<OMPC_NonTemporal, 50>,
-    VersionedClause<OMPC_Order, 50>
   ];
-  let leafConstructs = [OMP_For, OMP_Simd];
+  let leafConstructs = [OMP_Distribute, OMP_Simd];
 }
 def OMP_DoSimd : Directive<"do simd"> {
   let allowedClauses = [
     VersionedClause<OMPC_Aligned>,
-    VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_FirstPrivate>,
     VersionedClause<OMPC_LastPrivate>,
     VersionedClause<OMPC_Linear>,
-    VersionedClause<OMPC_Reduction>
+    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Reduction>,
   ];
   let allowedOnceClauses = [
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_Schedule>,
     VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_NoWait>,
+    VersionedClause<OMPC_Order, 50>,
     VersionedClause<OMPC_Ordered>,
     VersionedClause<OMPC_SafeLen>,
+    VersionedClause<OMPC_Schedule>,
     VersionedClause<OMPC_SimdLen>,
-    VersionedClause<OMPC_NoWait>,
-    VersionedClause<OMPC_Order, 50>
   ];
   let leafConstructs = [OMP_Do, OMP_Simd];
 }
-def OMP_CancellationPoint : Directive<"cancellation point"> {
-  let association = AS_None;
-}
-def OMP_DeclareReduction : Directive<"declare reduction"> {
-  let association = AS_None;
-}
-def OMP_DeclareMapper : Directive<"declare mapper"> {
-  let allowedClauses = [
-    VersionedClause<OMPC_Map>
+def OMP_EndDoSimd : Directive<"end do simd"> {
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_NoWait>,
   ];
-  let association = AS_None;
+  let leafConstructs = OMP_DoSimd.leafConstructs;
+  let association = OMP_DoSimd.association;
 }
-def OMP_DeclareSimd : Directive<"declare simd"> {
+def OMP_ForSimd : Directive<"for simd"> {
   let allowedClauses = [
-    VersionedClause<OMPC_Linear>,
     VersionedClause<OMPC_Aligned>,
-    VersionedClause<OMPC_Uniform>
-  ];
-  let allowedOnceClauses = [
-    VersionedClause<OMPC_SimdLen>
-  ];
-  let allowedExclusiveClauses = [
-    VersionedClause<OMPC_Inbranch>,
-    VersionedClause<OMPC_Notinbranch>
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_If, 50>,
+    VersionedClause<OMPC_LastPrivate>,
+    VersionedClause<OMPC_Linear>,
+    VersionedClause<OMPC_NonTemporal, 50>,
+    VersionedClause<OMPC_NoWait>,
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_Ordered>,
+    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Reduction>,
+    VersionedClause<OMPC_SafeLen>,
+    VersionedClause<OMPC_Schedule>,
+    VersionedClause<OMPC_SimdLen>,
   ];
-  let association = AS_Declaration;
+  let leafConstructs = [OMP_For, OMP_Simd];
 }
-def OMP_TaskLoop : Directive<"taskloop"> {
+def OMP_MaskedTaskloop : Directive<"masked taskloop"> {
   let allowedClauses = [
-    VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_Filter>,
+    VersionedClause<OMPC_Final>,
     VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_GrainSize>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_InReduction>,
     VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Untied>,
     VersionedClause<OMPC_Mergeable>,
     VersionedClause<OMPC_NoGroup>,
-    VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_InReduction>,
-    VersionedClause<OMPC_Allocate>
-  ];
-  let allowedOnceClauses = [
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_Final>,
+    VersionedClause<OMPC_NumTasks>,
     VersionedClause<OMPC_Priority>,
+    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Reduction>,
+    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_Untied>,
   ];
-  let allowedExclusiveClauses = [
-    VersionedClause<OMPC_GrainSize>,
-    VersionedClause<OMPC_NumTasks>
-  ];
-  let association = AS_Loop;
+  let leafConstructs = [OMP_masked, OMP_TaskLoop];
 }
-def OMP_TaskLoopSimd : Directive<"taskloop simd"> {
+def OMP_MaskedTaskloopSimd : Directive<"masked taskloop simd"> {
   let allowedClauses = [
-    VersionedClause<OMPC_If>,
     VersionedClause<OMPC_Aligned>,
     VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Collapse>,
     VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_Filter>,
+    VersionedClause<OMPC_Final>,
     VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_GrainSize>,
+    VersionedClause<OMPC_If>,
     VersionedClause<OMPC_InReduction>,
     VersionedClause<OMPC_LastPrivate>,
     VersionedClause<OMPC_Linear>,
     VersionedClause<OMPC_Mergeable>,
     VersionedClause<OMPC_NoGroup>,
     VersionedClause<OMPC_NonTemporal, 50>,
+    VersionedClause<OMPC_NumTasks>,
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_Priority>,
     VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Untied>
-  ];
-  let allowedOnceClauses = [
-    VersionedClause<OMPC_Collapse>,
     VersionedClause<OMPC_SafeLen>,
+    VersionedClause<OMPC_Shared>,
     VersionedClause<OMPC_SimdLen>,
-    VersionedClause<OMPC_Final>,
-    VersionedClause<OMPC_Priority>,
-    VersionedClause<OMPC_Order, 50>
-  ];
-  let allowedExclusiveClauses = [
-    VersionedClause<OMPC_GrainSize>,
-    VersionedClause<OMPC_NumTasks>
+    VersionedClause<OMPC_Untied>,
   ];
-  let leafConstructs = [OMP_TaskLoop, OMP_Simd];
+  let leafConstructs = [OMP_masked, OMP_TaskLoop, OMP_Simd];
 }
-def OMP_Distribute : Directive<"distribute"> {
+def OMP_MasterTaskloop : Directive<"master taskloop"> {
   let allowedClauses = [
-    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_Final>,
     VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_GrainSize>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_InReduction>,
     VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Allocate>
-  ];
-  let allowedOnceClauses = [
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_DistSchedule>
-  ];
-  let association = AS_Loop;
-}
-def OMP_BeginDeclareTarget : Directive<"begin declare target"> {
-  let allowedClauses = [
-    VersionedClause<OMPC_To>,
-    VersionedClause<OMPC_Link>,
-    VersionedClause<OMPC_DeviceType>,
-    VersionedClause<OMPC_Indirect>
-  ];
-  let association = AS_Delimited;
-}
-def OMP_DeclareTarget : Directive<"declare target"> {
-  let allowedClauses = [
-    VersionedClause<OMPC_To>,
-    VersionedClause<OMPC_Link>,
-    VersionedClause<OMPC_Indirect>,
-    VersionedClause<OMPC_Enter, 52>
-  ];
-  let allowedOnceClauses = [
-    VersionedClause<OMPC_DeviceType, 50>
+    VersionedClause<OMPC_Mergeable>,
+    VersionedClause<OMPC_NoGroup>,
+    VersionedClause<OMPC_NumTasks>,
+    VersionedClause<OMPC_Priority>,
+    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Reduction>,
+    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_Untied>,
   ];
-  let association = AS_None;
-}
-def OMP_EndDeclareTarget : Directive<"end declare target"> {
-  let association = AS_Delimited;
+  let leafConstructs = [OMP_Master, OMP_TaskLoop];
 }
-def OMP_DistributeParallelFor : Directive<"distribute parallel for"> {
+def OMP_MasterTaskloopSimd : Directive<"master taskloop simd"> {
   let allowedClauses = [
-    VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_LastPrivate>,
+    VersionedClause<OMPC_Aligned>,
+    VersionedClause<OMPC_Allocate>,
     VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_DistSchedule>,
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_NumThreads>,
     VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_ProcBind>,
+    VersionedClause<OMPC_Final>,
+    VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_GrainSize>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_InReduction>,
+    VersionedClause<OMPC_LastPrivate>,
+    VersionedClause<OMPC_Linear>,
+    VersionedClause<OMPC_Mergeable>,
+    VersionedClause<OMPC_NoGroup>,
+    VersionedClause<OMPC_NonTemporal, 50>,
+    VersionedClause<OMPC_NumTasks>,
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_Priority>,
     VersionedClause<OMPC_Private>,
-    VersionedClause<OMPC_Shared>,
     VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Copyin>,
-    VersionedClause<OMPC_Schedule>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_Order, 50>,
-    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_SafeLen>,
+    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_SimdLen>,
+    VersionedClause<OMPC_Untied>,
   ];
-  let leafConstructs = [OMP_Distribute, OMP_Parallel, OMP_For];
+  let leafConstructs = [OMP_Master, OMP_TaskLoop, OMP_Simd];
 }
-def OMP_DistributeParallelDo : Directive<"distribute parallel do"> {
+def OMP_ParallelDo : Directive<"parallel do"> {
   let allowedClauses = [
-    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Copyin>,
+    VersionedClause<OMPC_Default>,
     VersionedClause<OMPC_FirstPrivate>,
     VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_Linear>,
+    VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Copyin>,
-    VersionedClause<OMPC_Linear>
+    VersionedClause<OMPC_Shared>,
   ];
   let allowedOnceClauses = [
     VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_DistSchedule>,
     VersionedClause<OMPC_If>,
     VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_Ordered>,
     VersionedClause<OMPC_ProcBind>,
     VersionedClause<OMPC_Schedule>,
-    VersionedClause<OMPC_Ordered>,
-    VersionedClause<OMPC_Order, 50>
   ];
-  let leafConstructs = [OMP_Distribute, OMP_Parallel, OMP_Do];
+  let leafConstructs = [OMP_Parallel, OMP_Do];
 }
-def OMP_DistributeParallelForSimd : Directive<"distribute parallel for simd"> {
-  let allowedClauses = [
-    VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_DistSchedule>,
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_NumThreads>,
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_ProcBind>,
-    VersionedClause<OMPC_Private>,
-    VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Copyin>,
-    VersionedClause<OMPC_Schedule>,
-    VersionedClause<OMPC_Linear>,
-    VersionedClause<OMPC_Aligned>,
-    VersionedClause<OMPC_SafeLen>,
-    VersionedClause<OMPC_SimdLen>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_NonTemporal, 50>,
-    VersionedClause<OMPC_Order, 50>,
-    VersionedClause<OMPC_OMPX_Attribute>,
-  ];
-  let leafConstructs = [OMP_Distribute, OMP_Parallel, OMP_For, OMP_Simd];
-}
-def OMP_DistributeParallelDoSimd : Directive<"distribute parallel do simd"> {
-  let allowedClauses = [
-    VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_DistSchedule>,
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_NumThreads>,
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_ProcBind>,
-    VersionedClause<OMPC_Private>,
-    VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Copyin>,
-    VersionedClause<OMPC_Schedule>,
-    VersionedClause<OMPC_Linear>,
-    VersionedClause<OMPC_Aligned>,
-    VersionedClause<OMPC_SafeLen>,
-    VersionedClause<OMPC_SimdLen>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_NonTemporal>,
-    VersionedClause<OMPC_Order, 50>
-  ];
-  let leafConstructs = [OMP_Distribute, OMP_Parallel, OMP_Do, OMP_Simd];
-}
-def OMP_DistributeSimd : Directive<"distribute simd"> {
+def OMP_ParallelDoSimd : Directive<"parallel do simd"> {
   let allowedClauses = [
     VersionedClause<OMPC_Aligned>,
     VersionedClause<OMPC_Allocate>,
     VersionedClause<OMPC_Copyin>,
     VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_Linear>,
     VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_If>,
     VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_NonTemporal, 50>,
+    VersionedClause<OMPC_Linear>,
+    VersionedClause<OMPC_NonTemporal>,
     VersionedClause<OMPC_Private>,
-    VersionedClause<OMPC_Reduction>
+    VersionedClause<OMPC_Reduction>,
+    VersionedClause<OMPC_Shared>,
   ];
   let allowedOnceClauses = [
     VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_DistSchedule>,
-    VersionedClause<OMPC_If, 50>,
     VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_Order, 50>,
     VersionedClause<OMPC_Ordered>,
     VersionedClause<OMPC_ProcBind>,
-    VersionedClause<OMPC_Schedule>,
     VersionedClause<OMPC_SafeLen>,
+    VersionedClause<OMPC_Schedule>,
     VersionedClause<OMPC_SimdLen>,
-    VersionedClause<OMPC_Order, 50>
   ];
-  let leafConstructs = [OMP_Distribute, OMP_Simd];
+  let leafConstructs = [OMP_Parallel, OMP_Do, OMP_Simd];
 }
-
-def OMP_TargetParallelForSimd : Directive<"target parallel for simd"> {
+def OMP_ParallelFor : Directive<"parallel for"> {
   let allowedClauses = [
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_Device>,
-    VersionedClause<OMPC_Map>,
-    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_Copyin>,
+    VersionedClause<OMPC_Default>,
     VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_If>,
     VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_NoWait>,
-    VersionedClause<OMPC_Depend>,
-    VersionedClause<OMPC_DefaultMap>,
+    VersionedClause<OMPC_Linear>,
     VersionedClause<OMPC_NumThreads>,
-    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_Ordered>,
+    VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_ProcBind>,
-    VersionedClause<OMPC_Shared>,
     VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Collapse>,
     VersionedClause<OMPC_Schedule>,
-    VersionedClause<OMPC_Ordered>,
-    VersionedClause<OMPC_Linear>,
-    VersionedClause<OMPC_SafeLen>,
-    VersionedClause<OMPC_SimdLen>,
-    VersionedClause<OMPC_Aligned>,
-    VersionedClause<OMPC_IsDevicePtr>,
-    VersionedClause<OMPC_HasDeviceAddr, 51>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_NonTemporal, 50>,
-    VersionedClause<OMPC_Order, 50>,
-    VersionedClause<OMPC_UsesAllocators, 50>,
-    VersionedClause<OMPC_OMPX_Attribute>,
-  ];
-  let allowedOnceClauses = [
-    VersionedClause<OMPC_OMPX_DynCGroupMem>,
-    VersionedClause<OMPC_ThreadLimit, 51>,
+    VersionedClause<OMPC_Shared>,
   ];
-  let leafConstructs = [OMP_Target, OMP_Parallel, OMP_For, OMP_Simd];
+  let leafConstructs = [OMP_Parallel, OMP_For];
 }
-def OMP_TargetParallelDoSimd : Directive<"target parallel do simd"> {
+def OMP_ParallelForSimd : Directive<"parallel for simd"> {
   let allowedClauses = [
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_Device>,
-    VersionedClause<OMPC_Map>,
-    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Aligned>,
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_Copyin>,
+    VersionedClause<OMPC_Default>,
     VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_If>,
     VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_NoWait>,
-    VersionedClause<OMPC_Depend>,
-    VersionedClause<OMPC_DefaultMap>,
+    VersionedClause<OMPC_Linear>,
+    VersionedClause<OMPC_NonTemporal, 50>,
     VersionedClause<OMPC_NumThreads>,
-    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_Ordered>,
+    VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_ProcBind>,
-    VersionedClause<OMPC_Shared>,
     VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_Schedule>,
-    VersionedClause<OMPC_Ordered>,
-    VersionedClause<OMPC_Linear>,
     VersionedClause<OMPC_SafeLen>,
+    VersionedClause<OMPC_Schedule>,
+    VersionedClause<OMPC_Shared>,
     VersionedClause<OMPC_SimdLen>,
-    VersionedClause<OMPC_Aligned>,
-    VersionedClause<OMPC_IsDevicePtr>,
-    VersionedClause<OMPC_HasDeviceAddr, 51>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_NonTemporal>,
-    VersionedClause<OMPC_Order, 50>,
-    VersionedClause<OMPC_UsesAllocators>
   ];
-  let leafConstructs = [OMP_Target, OMP_Parallel, OMP_Do, OMP_Simd];
+  let leafConstructs = [OMP_Parallel, OMP_For, OMP_Simd];
 }
-def OMP_TargetSimd : Directive<"target simd"> {
+def OMP_parallel_loop : Directive<"parallel loop"> {
   let allowedClauses = [
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_Aligned>,
     VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_Depend>,
+    VersionedClause<OMPC_Copyin>,
     VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_IsDevicePtr>,
-    VersionedClause<OMPC_HasDeviceAddr, 51>,
     VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Linear>,
-    VersionedClause<OMPC_Map>,
-    VersionedClause<OMPC_NonTemporal, 50>,
-    VersionedClause<OMPC_NoWait>,
+    VersionedClause<OMPC_OMPX_Attribute>,
     VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_Reduction>,
     VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_UsesAllocators, 50>,
-    VersionedClause<OMPC_OMPX_Attribute>,
   ];
   let allowedOnceClauses = [
+    VersionedClause<OMPC_Bind, 50>,
     VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_SafeLen>,
-    VersionedClause<OMPC_SimdLen>,
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_If>,
     VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_Order>,
     VersionedClause<OMPC_ProcBind>,
-    VersionedClause<OMPC_Device>,
-    VersionedClause<OMPC_DefaultMap>,
-    VersionedClause<OMPC_Schedule>,
-    VersionedClause<OMPC_OMPX_DynCGroupMem>,
-    VersionedClause<OMPC_Order, 50>,
-    VersionedClause<OMPC_ThreadLimit, 51>,
   ];
-  let leafConstructs = [OMP_Target, OMP_Simd];
+  let leafConstructs = [OMP_Parallel, OMP_loop];
 }
-def OMP_TeamsDistribute : Directive<"teams distribute"> {
+def OMP_ParallelMasked : Directive<"parallel masked"> {
   let allowedClauses = [
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Copyin>,
     VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Filter>,
     VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_ProcBind>,
     VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_NumTeams>,
-    VersionedClause<OMPC_ThreadLimit>,
-    VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_DistSchedule>,
+    VersionedClause<OMPC_Shared>,
+  ];
+  let leafConstructs = [OMP_Parallel, OMP_masked];
+}
+def OMP_ParallelMaskedTaskloop :
+    Directive<"parallel masked taskloop"> {
+  let allowedClauses = [
     VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_Copyin>,
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_Filter>,
+    VersionedClause<OMPC_Final>,
+    VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_GrainSize>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_LastPrivate>,
+    VersionedClause<OMPC_Mergeable>,
+    VersionedClause<OMPC_NoGroup>,
+    VersionedClause<OMPC_NumTasks>,
+    VersionedClause<OMPC_NumThreads>,
     VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Priority>,
+    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_ProcBind>,
+    VersionedClause<OMPC_Reduction>,
+    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_Untied>,
   ];
-  let allowedOnceClauses = [
-    VersionedClause<OMPC_If>
-  ];
-  let leafConstructs = [OMP_Teams, OMP_Distribute];
+  let leafConstructs = [OMP_Parallel, OMP_masked, OMP_TaskLoop];
 }
-def OMP_TeamsDistributeSimd : Directive<"teams distribute simd"> {
+def OMP_ParallelMaskedTaskloopSimd :
+    Directive<"parallel masked taskloop simd"> {
   let allowedClauses = [
-    VersionedClause<OMPC_If, 50>,
     VersionedClause<OMPC_Aligned>,
     VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_Copyin>,
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_Filter>,
+    VersionedClause<OMPC_Final>,
     VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_GrainSize>,
+    VersionedClause<OMPC_If>,
     VersionedClause<OMPC_LastPrivate>,
     VersionedClause<OMPC_Linear>,
+    VersionedClause<OMPC_Mergeable>,
+    VersionedClause<OMPC_NoGroup>,
     VersionedClause<OMPC_NonTemporal, 50>,
+    VersionedClause<OMPC_NumTasks>,
+    VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_Priority>,
     VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_ProcBind>,
     VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_OMPX_Attribute>,
-  ];
-  let allowedOnceClauses = [
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_DistSchedule>,
-    VersionedClause<OMPC_NumTeams>,
     VersionedClause<OMPC_SafeLen>,
+    VersionedClause<OMPC_Shared>,
     VersionedClause<OMPC_SimdLen>,
-    VersionedClause<OMPC_ThreadLimit>,
-    VersionedClause<OMPC_Order, 50>
+    VersionedClause<OMPC_Untied>,
   ];
-  let leafConstructs = [OMP_Teams, OMP_Distribute, OMP_Simd];
+  let leafConstructs = [OMP_Parallel, OMP_masked, OMP_TaskLoop, OMP_Simd];
 }
-
-def OMP_TeamsDistributeParallelForSimd :
-    Directive<"teams distribute parallel for simd"> {
+def OMP_ParallelMaster : Directive<"parallel master"> {
   let allowedClauses = [
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Copyin>,
+    VersionedClause<OMPC_Default>,
     VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_DistSchedule>,
     VersionedClause<OMPC_If>,
     VersionedClause<OMPC_NumThreads>,
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_ProcBind>,
+    VersionedClause<OMPC_OMPX_Attribute>,
     VersionedClause<OMPC_Private>,
-    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_ProcBind>,
     VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Schedule>,
-    VersionedClause<OMPC_Linear>,
-    VersionedClause<OMPC_Aligned>,
-    VersionedClause<OMPC_SafeLen>,
-    VersionedClause<OMPC_SimdLen>,
-    VersionedClause<OMPC_NumTeams>,
-    VersionedClause<OMPC_ThreadLimit>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_NonTemporal, 50>,
-    VersionedClause<OMPC_Order, 50>,
-    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Shared>,
   ];
-  let leafConstructs = [OMP_Teams, OMP_Distribute, OMP_Parallel, OMP_For, OMP_Simd];
+  let leafConstructs = [OMP_Parallel, OMP_Master];
 }
-def OMP_TeamsDistributeParallelDoSimd :
-    Directive<"teams distribute parallel do simd"> {
+def OMP_ParallelMasterTaskloop :
+    Directive<"parallel master taskloop"> {
   let allowedClauses = [
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_Private>,
-    VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_LastPrivate>,
     VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Linear>,
-    VersionedClause<OMPC_Aligned>,
-    VersionedClause<OMPC_NonTemporal>
-  ];
-  let allowedOnceClauses = [
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_NumTeams>,
-    VersionedClause<OMPC_ThreadLimit>,
     VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_DistSchedule>,
+    VersionedClause<OMPC_Copyin>,
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_Final>,
+    VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_GrainSize>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_LastPrivate>,
+    VersionedClause<OMPC_Mergeable>,
+    VersionedClause<OMPC_NoGroup>,
+    VersionedClause<OMPC_NumTasks>,
     VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Priority>,
+    VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_ProcBind>,
-    VersionedClause<OMPC_Schedule>,
-    VersionedClause<OMPC_SafeLen>,
-    VersionedClause<OMPC_SimdLen>,
-    VersionedClause<OMPC_Order, 50>
+    VersionedClause<OMPC_Reduction>,
+    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_Untied>,
   ];
-  let leafConstructs = [OMP_Teams, OMP_Distribute, OMP_Parallel, OMP_Do, OMP_Simd];
+  let leafConstructs = [OMP_Parallel, OMP_Master, OMP_TaskLoop];
 }
-def OMP_TeamsDistributeParallelFor :
-    Directive<"teams distribute parallel for"> {
+def OMP_ParallelMasterTaskloopSimd :
+    Directive<"parallel master taskloop simd"> {
   let allowedClauses = [
-    VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_LastPrivate>,
+    VersionedClause<OMPC_Aligned>,
+    VersionedClause<OMPC_Allocate>,
     VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_DistSchedule>,
+    VersionedClause<OMPC_Copyin>,
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_Final>,
+    VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_GrainSize>,
     VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_LastPrivate>,
+    VersionedClause<OMPC_Linear>,
+    VersionedClause<OMPC_Mergeable>,
+    VersionedClause<OMPC_NoGroup>,
+    VersionedClause<OMPC_NonTemporal, 50>,
+    VersionedClause<OMPC_NumTasks>,
     VersionedClause<OMPC_NumThreads>,
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_ProcBind>,
+    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_Priority>,
     VersionedClause<OMPC_Private>,
-    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_ProcBind>,
     VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Schedule>,
-    VersionedClause<OMPC_NumTeams>,
-    VersionedClause<OMPC_ThreadLimit>,
-    VersionedClause<OMPC_Copyin>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_Order, 50>,
-    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_SafeLen>,
+    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_SimdLen>,
+    VersionedClause<OMPC_Untied>,
   ];
-  let leafConstructs = [OMP_Teams, OMP_Distribute, OMP_Parallel, OMP_For];
+  let leafConstructs = [OMP_Parallel, OMP_Master, OMP_TaskLoop, OMP_Simd];
 }
-def OMP_TeamsDistributeParallelDo :
-    Directive<"teams distribute parallel do"> {
+def OMP_ParallelSections : Directive<"parallel sections"> {
   let allowedClauses = [
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Copyin>,
+    VersionedClause<OMPC_Default>,
     VersionedClause<OMPC_FirstPrivate>,
     VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_ProcBind>,
     VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_Copyin>,
-    VersionedClause<OMPC_Linear>
+    VersionedClause<OMPC_Shared>,
   ];
-let allowedOnceClauses = [
-    VersionedClause<OMPC_NumTeams>,
-    VersionedClause<OMPC_ThreadLimit>,
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_DistSchedule>,
-    VersionedClause<OMPC_Ordered>,
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_If>,
     VersionedClause<OMPC_NumThreads>,
-    VersionedClause<OMPC_ProcBind>,
-    VersionedClause<OMPC_Schedule>,
-    VersionedClause<OMPC_Order, 50>
   ];
-  let leafConstructs = [OMP_Teams, OMP_Distribute, OMP_Parallel, OMP_Do];
+  let leafConstructs = [OMP_Parallel, OMP_Sections];
 }
-def OMP_TargetTeams : Directive<"target teams"> {
+def OMP_ParallelWorkshare : Directive<"parallel workshare"> {
   let allowedClauses = [
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_Map>,
-    VersionedClause<OMPC_Private>,
-    VersionedClause<OMPC_Depend>,
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Copyin>,
+    VersionedClause<OMPC_Default>,
     VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_IsDevicePtr>,
-    VersionedClause<OMPC_HasDeviceAddr, 51>,
+    VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_UsesAllocators, 50>,
     VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_OMPX_Attribute>,
   ];
-
   let allowedOnceClauses = [
-    VersionedClause<OMPC_Device>,
-    VersionedClause<OMPC_NoWait>,
-    VersionedClause<OMPC_DefaultMap>,
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_NumTeams>,
-    VersionedClause<OMPC_ThreadLimit>,
-    VersionedClause<OMPC_OMPX_DynCGroupMem>,
-    VersionedClause<OMPC_OMX_Bare>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_ProcBind>,
   ];
-  let leafConstructs = [OMP_Target, OMP_Teams];
+  let leafConstructs = [OMP_Parallel, OMP_Workshare];
 }
-def OMP_TargetTeamsDistribute : Directive<"target teams distribute"> {
+def OMP_TargetParallel : Directive<"target parallel"> {
   let allowedClauses = [
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_Map>,
-    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Default>,
     VersionedClause<OMPC_Depend>,
     VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_IsDevicePtr>,
     VersionedClause<OMPC_HasDeviceAddr, 51>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_IsDevicePtr>,
+    VersionedClause<OMPC_Map>,
+    VersionedClause<OMPC_NoWait>,
+    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_UsesAllocators, 50>,
     VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_UsesAllocators, 50>,
   ];
   let allowedOnceClauses = [
-    VersionedClause<OMPC_Device>,
-    VersionedClause<OMPC_NoWait>,
     VersionedClause<OMPC_DefaultMap>,
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_NumTeams>,
-    VersionedClause<OMPC_ThreadLimit>,
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_DistSchedule>,
+    VersionedClause<OMPC_Device>,
+    VersionedClause<OMPC_NumThreads>,
     VersionedClause<OMPC_OMPX_DynCGroupMem>,
+    VersionedClause<OMPC_ProcBind>,
+    VersionedClause<OMPC_ThreadLimit, 51>,
   ];
-  let leafConstructs = [OMP_Target, OMP_Teams, OMP_Distribute];
+  let leafConstructs = [OMP_Target, OMP_Parallel];
 }
-
-def OMP_TargetTeamsDistributeParallelFor :
-    Directive<"target teams distribute parallel for"> {
+def OMP_TargetParallelDo : Directive<"target parallel do"> {
   let allowedClauses = [
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_Device>,
-    VersionedClause<OMPC_Map>,
-    VersionedClause<OMPC_Private>,
-    VersionedClause<OMPC_NoWait>,
+    VersionedClause<OMPC_Allocator>,
+    VersionedClause<OMPC_Copyin>,
+    VersionedClause<OMPC_Default>,
     VersionedClause<OMPC_Depend>,
-    VersionedClause<OMPC_DefaultMap>,
     VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_IsDevicePtr>,
     VersionedClause<OMPC_HasDeviceAddr, 51>,
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_NumTeams>,
-    VersionedClause<OMPC_ThreadLimit>,
-    VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_DistSchedule>,
-    VersionedClause<OMPC_NumThreads>,
-    VersionedClause<OMPC_ProcBind>,
-    VersionedClause<OMPC_Schedule>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_Order, 50>,
-    VersionedClause<OMPC_UsesAllocators, 50>,
-    VersionedClause<OMPC_OMPX_Attribute>,
-  ];
-  let allowedOnceClauses = [
-    VersionedClause<OMPC_OMPX_DynCGroupMem>,
-  ];
-  let leafConstructs = [OMP_Target, OMP_Teams, OMP_Distribute, OMP_Parallel, OMP_For];
-}
-def OMP_TargetTeamsDistributeParallelDo :
-    Directive<"target teams distribute parallel do"> {
-  let allowedClauses = [
     VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_IsDevicePtr>,
+    VersionedClause<OMPC_LastPrivate>,
+    VersionedClause<OMPC_Linear>,
     VersionedClause<OMPC_Map>,
     VersionedClause<OMPC_Private>,
-    VersionedClause<OMPC_Depend>,
-    VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_IsDevicePtr>,
-    VersionedClause<OMPC_HasDeviceAddr, 51>,
     VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_UsesAllocators>,
     VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Copyin>,
-    VersionedClause<OMPC_Linear>,
-    VersionedClause<OMPC_Ordered>,
+    VersionedClause<OMPC_UsesAllocators>,
   ];
   let allowedOnceClauses = [
-    VersionedClause<OMPC_Device>,
+    VersionedClause<OMPC_Collapse>,
     VersionedClause<OMPC_DefaultMap>,
+    VersionedClause<OMPC_Device>,
     VersionedClause<OMPC_NoWait>,
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_NumTeams>,
-    VersionedClause<OMPC_ThreadLimit>,
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_DistSchedule>,
     VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_Ordered>,
     VersionedClause<OMPC_ProcBind>,
     VersionedClause<OMPC_Schedule>,
-    VersionedClause<OMPC_Order, 50>
   ];
-  let leafConstructs = [OMP_Target, OMP_Teams, OMP_Distribute, OMP_Parallel, OMP_Do];
+  let leafConstructs = [OMP_Target, OMP_Parallel, OMP_Do];
 }
-def OMP_TargetTeamsDistributeParallelForSimd :
-    Directive<"target teams distribute parallel for simd"> {
+def OMP_TargetParallelDoSimd : Directive<"target parallel do simd"> {
   let allowedClauses = [
-    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_Aligned>,
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_DefaultMap>,
+    VersionedClause<OMPC_Depend>,
     VersionedClause<OMPC_Device>,
+    VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_HasDeviceAddr, 51>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_IsDevicePtr>,
+    VersionedClause<OMPC_LastPrivate>,
+    VersionedClause<OMPC_Linear>,
     VersionedClause<OMPC_Map>,
-    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_NonTemporal>,
     VersionedClause<OMPC_NoWait>,
-    VersionedClause<OMPC_Depend>,
+    VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_Ordered>,
+    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_ProcBind>,
+    VersionedClause<OMPC_Reduction>,
+    VersionedClause<OMPC_SafeLen>,
+    VersionedClause<OMPC_Schedule>,
+    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_SimdLen>,
+    VersionedClause<OMPC_UsesAllocators>,
+  ];
+  let leafConstructs = [OMP_Target, OMP_Parallel, OMP_Do, OMP_Simd];
+}
+def OMP_TargetParallelFor : Directive<"target parallel for"> {
+  let allowedClauses = [
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_Default>,
     VersionedClause<OMPC_DefaultMap>,
+    VersionedClause<OMPC_Depend>,
+    VersionedClause<OMPC_Device>,
     VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_IsDevicePtr>,
     VersionedClause<OMPC_HasDeviceAddr, 51>,
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_NumTeams>,
-    VersionedClause<OMPC_ThreadLimit>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_IsDevicePtr>,
     VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_DistSchedule>,
+    VersionedClause<OMPC_Linear>,
+    VersionedClause<OMPC_Map>,
+    VersionedClause<OMPC_NoWait>,
     VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_Ordered>,
+    VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_ProcBind>,
+    VersionedClause<OMPC_Reduction>,
     VersionedClause<OMPC_Schedule>,
-    VersionedClause<OMPC_Linear>,
+    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_UsesAllocators, 50>,
+  ];
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_OMPX_DynCGroupMem>,
+    VersionedClause<OMPC_ThreadLimit, 51>,
+  ];
+  let leafConstructs = [OMP_Target, OMP_Parallel, OMP_For];
+}
+def OMP_TargetParallelForSimd : Directive<"target parallel for simd"> {
+  let allowedClauses = [
     VersionedClause<OMPC_Aligned>,
-    VersionedClause<OMPC_SafeLen>,
-    VersionedClause<OMPC_SimdLen>,
     VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_DefaultMap>,
+    VersionedClause<OMPC_Depend>,
+    VersionedClause<OMPC_Device>,
+    VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_HasDeviceAddr, 51>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_IsDevicePtr>,
+    VersionedClause<OMPC_LastPrivate>,
+    VersionedClause<OMPC_Linear>,
+    VersionedClause<OMPC_Map>,
     VersionedClause<OMPC_NonTemporal, 50>,
+    VersionedClause<OMPC_NoWait>,
+    VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_OMPX_Attribute>,
     VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_Ordered>,
+    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_ProcBind>,
+    VersionedClause<OMPC_Reduction>,
+    VersionedClause<OMPC_SafeLen>,
+    VersionedClause<OMPC_Schedule>,
+    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_SimdLen>,
     VersionedClause<OMPC_UsesAllocators, 50>,
-    VersionedClause<OMPC_OMPX_Attribute>,
   ];
   let allowedOnceClauses = [
     VersionedClause<OMPC_OMPX_DynCGroupMem>,
+    VersionedClause<OMPC_ThreadLimit, 51>,
   ];
-  let leafConstructs = [OMP_Target, OMP_Teams, OMP_Distribute, OMP_Parallel, OMP_For, OMP_Simd];
+  let leafConstructs = [OMP_Target, OMP_Parallel, OMP_For, OMP_Simd];
 }
-def OMP_TargetTeamsDistributeParallelDoSimd :
-    Directive<"target teams distribute parallel do simd"> {
+def OMP_target_parallel_loop : Directive<"target parallel loop"> {
   let allowedClauses = [
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_Map>,
-    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Copyin>,
     VersionedClause<OMPC_Depend>,
+    VersionedClause<OMPC_Device>,
     VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_IsDevicePtr>,
     VersionedClause<OMPC_HasDeviceAddr, 51>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_IsDevicePtr>,
+    VersionedClause<OMPC_LastPrivate>,
+    VersionedClause<OMPC_Map>,
+    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_UsesAllocators>,
     VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Copyin>,
-    VersionedClause<OMPC_Linear>,
-    VersionedClause<OMPC_Ordered>,
-    VersionedClause<OMPC_Aligned>,
-    VersionedClause<OMPC_NonTemporal>
+    VersionedClause<OMPC_UsesAllocators, 50>,
   ];
   let allowedOnceClauses = [
-    VersionedClause<OMPC_Device>,
-    VersionedClause<OMPC_NoWait>,
-    VersionedClause<OMPC_DefaultMap>,
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_NumTeams>,
-    VersionedClause<OMPC_ThreadLimit>,
+    VersionedClause<OMPC_Bind, 50>,
     VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_DistSchedule>,
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_DefaultMap>,
+    VersionedClause<OMPC_NoWait>,
     VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_OMPX_DynCGroupMem>,
+    VersionedClause<OMPC_Order>,
     VersionedClause<OMPC_ProcBind>,
-    VersionedClause<OMPC_Schedule>,
-    VersionedClause<OMPC_SafeLen>,
-    VersionedClause<OMPC_SimdLen>,
-    VersionedClause<OMPC_Order, 50>
+    VersionedClause<OMPC_ThreadLimit, 51>,
   ];
-  let leafConstructs = [OMP_Target, OMP_Teams, OMP_Distribute, OMP_Parallel, OMP_Do, OMP_Simd];
+  let leafConstructs = [OMP_Target, OMP_Parallel, OMP_loop];
 }
-def OMP_TargetTeamsDistributeSimd :
-    Directive<"target teams distribute simd"> {
+def OMP_TargetSimd : Directive<"target simd"> {
   let allowedClauses = [
     VersionedClause<OMPC_Aligned>,
     VersionedClause<OMPC_Allocate>,
     VersionedClause<OMPC_Depend>,
     VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_HasDeviceAddr, 51>,
     VersionedClause<OMPC_If>,
     VersionedClause<OMPC_IsDevicePtr>,
-    VersionedClause<OMPC_HasDeviceAddr, 51>,
     VersionedClause<OMPC_LastPrivate>,
     VersionedClause<OMPC_Linear>,
     VersionedClause<OMPC_Map>,
     VersionedClause<OMPC_NonTemporal, 50>,
+    VersionedClause<OMPC_NoWait>,
+    VersionedClause<OMPC_OMPX_Attribute>,
     VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_Reduction>,
     VersionedClause<OMPC_Shared>,
     VersionedClause<OMPC_UsesAllocators, 50>,
-    VersionedClause<OMPC_OMPX_Attribute>,
   ];
   let allowedOnceClauses = [
-    VersionedClause<OMPC_Device>,
-    VersionedClause<OMPC_DefaultMap>,
-    VersionedClause<OMPC_NoWait>,
-    VersionedClause<OMPC_NumTeams>,
-    VersionedClause<OMPC_ThreadLimit>,
     VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_DistSchedule>,
+    VersionedClause<OMPC_DefaultMap>,
+    VersionedClause<OMPC_Device>,
+    VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_OMPX_DynCGroupMem>,
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_ProcBind>,
     VersionedClause<OMPC_SafeLen>,
+    VersionedClause<OMPC_Schedule>,
     VersionedClause<OMPC_SimdLen>,
-    VersionedClause<OMPC_OMPX_DynCGroupMem>,
-    VersionedClause<OMPC_Order, 50>
-  ];
-  let leafConstructs = [OMP_Target, OMP_Teams, OMP_Distribute, OMP_Simd];
-}
-def OMP_Allocate : Directive<"allocate"> {
-  let allowedOnceClauses = [
-    VersionedClause<OMPC_Allocator>,
-    VersionedClause<OMPC_Align, 51>
-  ];
-  let association = AS_None;
-}
-def OMP_Allocators : Directive<"allocators"> {
-  let allowedClauses = [
-    VersionedClause<OMPC_Allocate>
+    VersionedClause<OMPC_ThreadLimit, 51>,
   ];
-  let association = AS_Block;
+  let leafConstructs = [OMP_Target, OMP_Simd];
 }
-def OMP_DeclareVariant : Directive<"declare variant"> {
+def OMP_TargetTeams : Directive<"target teams"> {
   let allowedClauses = [
-    VersionedClause<OMPC_Match>
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Depend>,
+    VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_HasDeviceAddr, 51>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_IsDevicePtr>,
+    VersionedClause<OMPC_Map>,
+    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Reduction>,
+    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_UsesAllocators, 50>,
   ];
-  let allowedExclusiveClauses = [
-    VersionedClause<OMPC_AdjustArgs, 51>,
-    VersionedClause<OMPC_AppendArgs, 51>
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_DefaultMap>,
+    VersionedClause<OMPC_Device>,
+    VersionedClause<OMPC_NoWait>,
+    VersionedClause<OMPC_NumTeams>,
+    VersionedClause<OMPC_OMPX_DynCGroupMem>,
+    VersionedClause<OMPC_OMX_Bare>,
+    VersionedClause<OMPC_ThreadLimit>,
   ];
-  let association = AS_Declaration;
+  let leafConstructs = [OMP_Target, OMP_Teams];
 }
-def OMP_MasterTaskloop : Directive<"master taskloop"> {
+def OMP_TargetTeamsDistribute : Directive<"target teams distribute"> {
   let allowedClauses = [
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Depend>,
     VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_HasDeviceAddr, 51>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_IsDevicePtr>,
     VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_Final>,
-    VersionedClause<OMPC_Untied>,
-    VersionedClause<OMPC_Mergeable>,
-    VersionedClause<OMPC_Priority>,
-    VersionedClause<OMPC_GrainSize>,
-    VersionedClause<OMPC_NoGroup>,
-    VersionedClause<OMPC_NumTasks>,
+    VersionedClause<OMPC_Map>,
+    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_InReduction>,
-    VersionedClause<OMPC_Allocate>
+    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_UsesAllocators, 50>,
   ];
-  let leafConstructs = [OMP_Master, OMP_TaskLoop];
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_DefaultMap>,
+    VersionedClause<OMPC_Device>,
+    VersionedClause<OMPC_DistSchedule>,
+    VersionedClause<OMPC_NoWait>,
+    VersionedClause<OMPC_NumTeams>,
+    VersionedClause<OMPC_OMPX_DynCGroupMem>,
+    VersionedClause<OMPC_ThreadLimit>,
+  ];
+  let leafConstructs = [OMP_Target, OMP_Teams, OMP_Distribute];
 }
-def OMP_MaskedTaskloop : Directive<"masked taskloop"> {
+def OMP_TargetTeamsDistributeParallelDo :
+    Directive<"target teams distribute parallel do"> {
   let allowedClauses = [
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Copyin>,
+    VersionedClause<OMPC_Depend>,
     VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_HasDeviceAddr, 51>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_IsDevicePtr>,
     VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_Final>,
-    VersionedClause<OMPC_Untied>,
-    VersionedClause<OMPC_Mergeable>,
-    VersionedClause<OMPC_Priority>,
-    VersionedClause<OMPC_GrainSize>,
-    VersionedClause<OMPC_NoGroup>,
-    VersionedClause<OMPC_NumTasks>,
+    VersionedClause<OMPC_Linear>,
+    VersionedClause<OMPC_Map>,
+    VersionedClause<OMPC_Ordered>,
+    VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_InReduction>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_Filter>
-  ];
-  let leafConstructs = [OMP_masked, OMP_TaskLoop];
-}
-def OMP_ParallelMasterTaskloop :
-    Directive<"parallel master taskloop"> {
-  let allowedClauses = [
-    VersionedClause<OMPC_If>,
     VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Private>,
-    VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_UsesAllocators>,
+  ];
+  let allowedOnceClauses = [
     VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_Final>,
-    VersionedClause<OMPC_Untied>,
-    VersionedClause<OMPC_Mergeable>,
-    VersionedClause<OMPC_Priority>,
-    VersionedClause<OMPC_GrainSize>,
-    VersionedClause<OMPC_NoGroup>,
-    VersionedClause<OMPC_NumTasks>,
-    VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_DefaultMap>,
+    VersionedClause<OMPC_Device>,
+    VersionedClause<OMPC_DistSchedule>,
+    VersionedClause<OMPC_NoWait>,
+    VersionedClause<OMPC_NumTeams>,
     VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_Order, 50>,
     VersionedClause<OMPC_ProcBind>,
-    VersionedClause<OMPC_Copyin>,
-    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Schedule>,
+    VersionedClause<OMPC_ThreadLimit>,
   ];
-  let leafConstructs = [OMP_Parallel, OMP_Master, OMP_TaskLoop];
+  let leafConstructs = [OMP_Target, OMP_Teams, OMP_Distribute, OMP_Parallel, OMP_Do];
 }
-def OMP_ParallelMaskedTaskloop :
-    Directive<"parallel masked taskloop"> {
+def OMP_TargetTeamsDistributeParallelDoSimd :
+    Directive<"target teams distribute parallel do simd"> {
   let allowedClauses = [
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Aligned>,
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Copyin>,
+    VersionedClause<OMPC_Depend>,
     VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_HasDeviceAddr, 51>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_IsDevicePtr>,
     VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_Final>,
-    VersionedClause<OMPC_Untied>,
-    VersionedClause<OMPC_Mergeable>,
-    VersionedClause<OMPC_Priority>,
-    VersionedClause<OMPC_GrainSize>,
-    VersionedClause<OMPC_NoGroup>,
-    VersionedClause<OMPC_NumTasks>,
+    VersionedClause<OMPC_Linear>,
+    VersionedClause<OMPC_Map>,
+    VersionedClause<OMPC_NonTemporal>,
+    VersionedClause<OMPC_Ordered>,
+    VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_UsesAllocators>,
+  ];
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_DefaultMap>,
+    VersionedClause<OMPC_Device>,
+    VersionedClause<OMPC_DistSchedule>,
+    VersionedClause<OMPC_NoWait>,
+    VersionedClause<OMPC_NumTeams>,
     VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_Order, 50>,
     VersionedClause<OMPC_ProcBind>,
-    VersionedClause<OMPC_Copyin>,
-    VersionedClause<OMPC_Filter>,
-    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_SafeLen>,
+    VersionedClause<OMPC_Schedule>,
+    VersionedClause<OMPC_SimdLen>,
+    VersionedClause<OMPC_ThreadLimit>,
   ];
-  let leafConstructs = [OMP_Parallel, OMP_masked, OMP_TaskLoop];
+  let leafConstructs = [OMP_Target, OMP_Teams, OMP_Distribute, OMP_Parallel, OMP_Do, OMP_Simd];
 }
-def OMP_MasterTaskloopSimd : Directive<"master taskloop simd"> {
+def OMP_TargetTeamsDistributeParallelFor :
+    Directive<"target teams distribute parallel for"> {
   let allowedClauses = [
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_DefaultMap>,
+    VersionedClause<OMPC_Depend>,
+    VersionedClause<OMPC_Device>,
+    VersionedClause<OMPC_DistSchedule>,
     VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_HasDeviceAddr, 51>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_IsDevicePtr>,
     VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_Final>,
-    VersionedClause<OMPC_Untied>,
-    VersionedClause<OMPC_Mergeable>,
-    VersionedClause<OMPC_Priority>,
-    VersionedClause<OMPC_Linear>,
-    VersionedClause<OMPC_Aligned>,
-    VersionedClause<OMPC_SafeLen>,
-    VersionedClause<OMPC_SimdLen>,
-    VersionedClause<OMPC_GrainSize>,
-    VersionedClause<OMPC_NoGroup>,
-    VersionedClause<OMPC_NumTasks>,
+    VersionedClause<OMPC_Map>,
+    VersionedClause<OMPC_NoWait>,
+    VersionedClause<OMPC_NumTeams>,
+    VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_ProcBind>,
     VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_InReduction>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_NonTemporal, 50>,
-    VersionedClause<OMPC_Order, 50>
+    VersionedClause<OMPC_Schedule>,
+    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_ThreadLimit>,
+    VersionedClause<OMPC_UsesAllocators, 50>,
   ];
-  let leafConstructs = [OMP_Master, OMP_TaskLoop, OMP_Simd];
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_OMPX_DynCGroupMem>,
+  ];
+  let leafConstructs = [OMP_Target, OMP_Teams, OMP_Distribute, OMP_Parallel, OMP_For];
 }
-def OMP_MaskedTaskloopSimd : Directive<"masked taskloop simd"> {
+def OMP_TargetTeamsDistributeParallelForSimd :
+    Directive<"target teams distribute parallel for simd"> {
   let allowedClauses = [
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Aligned>,
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_DefaultMap>,
+    VersionedClause<OMPC_Depend>,
+    VersionedClause<OMPC_Device>,
+    VersionedClause<OMPC_DistSchedule>,
     VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_HasDeviceAddr, 51>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_IsDevicePtr>,
     VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_Final>,
-    VersionedClause<OMPC_Untied>,
-    VersionedClause<OMPC_Mergeable>,
-    VersionedClause<OMPC_Priority>,
     VersionedClause<OMPC_Linear>,
-    VersionedClause<OMPC_Aligned>,
-    VersionedClause<OMPC_SafeLen>,
-    VersionedClause<OMPC_SimdLen>,
-    VersionedClause<OMPC_GrainSize>,
-    VersionedClause<OMPC_NoGroup>,
-    VersionedClause<OMPC_NumTasks>,
-    VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_InReduction>,
-    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Map>,
     VersionedClause<OMPC_NonTemporal, 50>,
+    VersionedClause<OMPC_NoWait>,
+    VersionedClause<OMPC_NumTeams>,
+    VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_OMPX_Attribute>,
     VersionedClause<OMPC_Order, 50>,
-    VersionedClause<OMPC_Filter>
-  ];
-  let leafConstructs = [OMP_masked, OMP_TaskLoop, OMP_Simd];
-}
-def OMP_ParallelMasterTaskloopSimd :
-    Directive<"parallel master taskloop simd"> {
-  let allowedClauses = [
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_Shared>,
     VersionedClause<OMPC_Private>,
-    VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_Final>,
-    VersionedClause<OMPC_Untied>,
-    VersionedClause<OMPC_Mergeable>,
-    VersionedClause<OMPC_Priority>,
-    VersionedClause<OMPC_GrainSize>,
-    VersionedClause<OMPC_NoGroup>,
-    VersionedClause<OMPC_NumTasks>,
-    VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_NumThreads>,
     VersionedClause<OMPC_ProcBind>,
-    VersionedClause<OMPC_Copyin>,
-    VersionedClause<OMPC_Linear>,
-    VersionedClause<OMPC_Aligned>,
+    VersionedClause<OMPC_Reduction>,
     VersionedClause<OMPC_SafeLen>,
+    VersionedClause<OMPC_Schedule>,
+    VersionedClause<OMPC_Shared>,
     VersionedClause<OMPC_SimdLen>,
-    VersionedClause<OMPC_NonTemporal, 50>,
-    VersionedClause<OMPC_Order, 50>,
-    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_ThreadLimit>,
+    VersionedClause<OMPC_UsesAllocators, 50>,
   ];
-  let leafConstructs = [OMP_Parallel, OMP_Master, OMP_TaskLoop, OMP_Simd];
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_OMPX_DynCGroupMem>,
+  ];
+  let leafConstructs = [OMP_Target, OMP_Teams, OMP_Distribute, OMP_Parallel, OMP_For, OMP_Simd];
 }
-def OMP_ParallelMaskedTaskloopSimd :
-    Directive<"parallel masked taskloop simd"> {
+def OMP_TargetTeamsDistributeSimd :
+    Directive<"target teams distribute simd"> {
   let allowedClauses = [
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Aligned>,
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Depend>,
     VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_HasDeviceAddr, 51>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_IsDevicePtr>,
     VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_Final>,
-    VersionedClause<OMPC_Untied>,
-    VersionedClause<OMPC_Mergeable>,
-    VersionedClause<OMPC_Priority>,
-    VersionedClause<OMPC_GrainSize>,
-    VersionedClause<OMPC_NoGroup>,
-    VersionedClause<OMPC_NumTasks>,
-    VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_NumThreads>,
-    VersionedClause<OMPC_ProcBind>,
-    VersionedClause<OMPC_Copyin>,
     VersionedClause<OMPC_Linear>,
-    VersionedClause<OMPC_Aligned>,
-    VersionedClause<OMPC_SafeLen>,
-    VersionedClause<OMPC_SimdLen>,
+    VersionedClause<OMPC_Map>,
     VersionedClause<OMPC_NonTemporal, 50>,
-    VersionedClause<OMPC_Order, 50>,
-    VersionedClause<OMPC_Filter>,
     VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Reduction>,
+    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_UsesAllocators, 50>,
   ];
-  let leafConstructs = [OMP_Parallel, OMP_masked, OMP_TaskLoop, OMP_Simd];
-}
-def OMP_Depobj : Directive<"depobj"> {
-  let allowedClauses = [
-    VersionedClause<OMPC_Depend, 50>,
-    VersionedClause<OMPC_Destroy, 50>,
-    VersionedClause<OMPC_Update, 50>,
-    // TODO This should ne `none` instead. Comment carried over from
-    // OMPKinds.def.
-    VersionedClause<OMPC_Depobj, 50>
-  ];
-  let association = AS_None;
-}
-def OMP_Scan : Directive<"scan"> {
-  let allowedClauses = [
-    VersionedClause<OMPC_Inclusive, 50>,
-    VersionedClause<OMPC_Exclusive, 50>
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_DefaultMap>,
+    VersionedClause<OMPC_Device>,
+    VersionedClause<OMPC_DistSchedule>,
+    VersionedClause<OMPC_NoWait>,
+    VersionedClause<OMPC_NumTeams>,
+    VersionedClause<OMPC_OMPX_DynCGroupMem>,
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_SafeLen>,
+    VersionedClause<OMPC_SimdLen>,
+    VersionedClause<OMPC_ThreadLimit>,
   ];
-  let association = AS_Separating;
-}
-def OMP_Assumes : Directive<"assumes"> {
-  let association = AS_None;
-}
-def OMP_BeginAssumes : Directive<"begin assumes"> {
-  let association = AS_Delimited;
-}
-def OMP_EndAssumes : Directive<"end assumes"> {
-  let association = AS_Delimited;
-}
-def OMP_BeginDeclareVariant : Directive<"begin declare variant"> {
-  let association = AS_Delimited;
-}
-def OMP_EndDeclareVariant : Directive<"end declare variant"> {
-  let association = AS_Delimited;
+  let leafConstructs = [OMP_Target, OMP_Teams, OMP_Distribute, OMP_Simd];
 }
-def OMP_scope : Directive<"scope"> {
+def OMP_target_teams_loop : Directive<"target teams loop"> {
   let allowedClauses = [
-    VersionedClause<OMPC_Private, 51>,
-    VersionedClause<OMPC_Reduction, 51>,
-  ];
-  let allowedOnceClauses = [
-    VersionedClause<OMPC_NoWait, 51>
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_DefaultMap>,
+    VersionedClause<OMPC_Depend>,
+    VersionedClause<OMPC_Device>,
+    VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_HasDeviceAddr, 51>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_IsDevicePtr>,
+    VersionedClause<OMPC_LastPrivate>,
+    VersionedClause<OMPC_Map>,
+    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Reduction>,
+    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_UsesAllocators, 50>,
   ];
-  let association = AS_Block;
-}
-def OMP_Workshare : Directive<"workshare"> {
   let allowedOnceClauses = [
-    VersionedClause<OMPC_NoWait>
+    VersionedClause<OMPC_Bind, 50>,
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_NoWait>,
+    VersionedClause<OMPC_NumTeams>,
+    VersionedClause<OMPC_OMPX_DynCGroupMem>,
+    VersionedClause<OMPC_Order>,
+    VersionedClause<OMPC_ThreadLimit>,
   ];
-  let association = AS_Block;
+  let leafConstructs = [OMP_Target, OMP_Teams, OMP_loop];
 }
-def OMP_ParallelWorkshare : Directive<"parallel workshare"> {
+def OMP_TaskLoopSimd : Directive<"taskloop simd"> {
   let allowedClauses = [
+    VersionedClause<OMPC_Aligned>,
     VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_Copyin>,
     VersionedClause<OMPC_Default>,
     VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_InReduction>,
+    VersionedClause<OMPC_LastPrivate>,
+    VersionedClause<OMPC_Linear>,
+    VersionedClause<OMPC_Mergeable>,
+    VersionedClause<OMPC_NoGroup>,
+    VersionedClause<OMPC_NonTemporal, 50>,
     VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_Reduction>,
-    VersionedClause<OMPC_Shared>
-  ];
-  let allowedOnceClauses = [
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_NumThreads>,
-    VersionedClause<OMPC_ProcBind>
-  ];
-  let leafConstructs = [OMP_Parallel, OMP_Workshare];
-}
-def OMP_EndDo : Directive<"end do"> {
-  let allowedOnceClauses = [
-    VersionedClause<OMPC_NoWait>
+    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_Untied>,
   ];
-  // Needed for association computation, since OMP_Do has it "from leafConstructs".
-  let leafConstructs = OMP_Do.leafConstructs;
-  let association = OMP_Do.association;
-}
-def OMP_EndDoSimd : Directive<"end do simd"> {
   let allowedOnceClauses = [
-    VersionedClause<OMPC_NoWait>
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_Final>,
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_Priority>,
+    VersionedClause<OMPC_SafeLen>,
+    VersionedClause<OMPC_SimdLen>,
   ];
-  let leafConstructs = OMP_DoSimd.leafConstructs;
-  let association = OMP_DoSimd.association;
-}
-def OMP_EndSections : Directive<"end sections"> {
-  let allowedOnceClauses = [
-    VersionedClause<OMPC_NoWait>
+  let allowedExclusiveClauses = [
+    VersionedClause<OMPC_GrainSize>,
+    VersionedClause<OMPC_NumTasks>,
   ];
-  let leafConstructs = OMP_Sections.leafConstructs;
-  let association = OMP_Sections.association;
+  let leafConstructs = [OMP_TaskLoop, OMP_Simd];
 }
-def OMP_EndSingle : Directive<"end single"> {
+def OMP_TeamsDistribute : Directive<"teams distribute"> {
   let allowedClauses = [
-    VersionedClause<OMPC_CopyPrivate>
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_DistSchedule>,
+    VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_LastPrivate>,
+    VersionedClause<OMPC_NumTeams>,
+    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_Reduction>,
+    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_ThreadLimit>,
   ];
   let allowedOnceClauses = [
-    VersionedClause<OMPC_NoWait>
-  ];
-  let leafConstructs = OMP_Single.leafConstructs;
-  let association = OMP_Single.association;
-}
-def OMP_EndWorkshare : Directive<"end workshare"> {
-  let allowedClauses = [
-    VersionedClause<OMPC_NoWait>
-  ];
-  let leafConstructs = OMP_Workshare.leafConstructs;
-  let association = OMP_Workshare.association;
-}
-def OMP_interop : Directive<"interop"> {
-  let allowedClauses = [
-    VersionedClause<OMPC_Device>,
-    VersionedClause<OMPC_Depend>,
-    VersionedClause<OMPC_Destroy>,
-    VersionedClause<OMPC_Init>,
-    VersionedClause<OMPC_NoWait>,
-    VersionedClause<OMPC_Use>,
-  ];
-  let association = AS_None;
-}
-def OMP_dispatch : Directive<"dispatch"> {
-  let allowedClauses = [
-    VersionedClause<OMPC_Device>,
-    VersionedClause<OMPC_IsDevicePtr>,
-    VersionedClause<OMPC_HasDeviceAddr, 51>,
-    VersionedClause<OMPC_NoWait>,
-    VersionedClause<OMPC_Depend>,
-    VersionedClause<OMPC_Novariants>,
-    VersionedClause<OMPC_Nocontext>
+    VersionedClause<OMPC_If>,
   ];
-  let association = AS_Block;
+  let leafConstructs = [OMP_Teams, OMP_Distribute];
 }
-def OMP_loop : Directive<"loop"> {
+def OMP_TeamsDistributeParallelDo :
+    Directive<"teams distribute parallel do"> {
   let allowedClauses = [
+    VersionedClause<OMPC_Allocate>,
+    VersionedClause<OMPC_Copyin>,
+    VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_If>,
     VersionedClause<OMPC_LastPrivate>,
+    VersionedClause<OMPC_Linear>,
     VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_Reduction>,
+    VersionedClause<OMPC_Shared>,
   ];
   let allowedOnceClauses = [
-    VersionedClause<OMPC_Bind, 50>,
     VersionedClause<OMPC_Collapse>,
-    VersionedClause<OMPC_Order, 50>
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_DistSchedule>,
+    VersionedClause<OMPC_NumTeams>,
+    VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_Ordered>,
+    VersionedClause<OMPC_ProcBind>,
+    VersionedClause<OMPC_Schedule>,
+    VersionedClause<OMPC_ThreadLimit>,
   ];
-  let association = AS_Loop;
+  let leafConstructs = [OMP_Teams, OMP_Distribute, OMP_Parallel, OMP_Do];
 }
-def OMP_teams_loop : Directive<"teams loop"> {
+def OMP_TeamsDistributeParallelDoSimd :
+    Directive<"teams distribute parallel do simd"> {
   let allowedClauses = [
+    VersionedClause<OMPC_Aligned>,
     VersionedClause<OMPC_Allocate>,
     VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_If>,
     VersionedClause<OMPC_LastPrivate>,
+    VersionedClause<OMPC_Linear>,
+    VersionedClause<OMPC_NonTemporal>,
     VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_Reduction>,
     VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_OMPX_Attribute>,
   ];
   let allowedOnceClauses = [
-    VersionedClause<OMPC_Bind, 50>,
     VersionedClause<OMPC_Collapse>,
     VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_DistSchedule>,
     VersionedClause<OMPC_NumTeams>,
-    VersionedClause<OMPC_Order>,
+    VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_ProcBind>,
+    VersionedClause<OMPC_SafeLen>,
+    VersionedClause<OMPC_Schedule>,
+    VersionedClause<OMPC_SimdLen>,
     VersionedClause<OMPC_ThreadLimit>,
   ];
-  let leafConstructs = [OMP_Teams, OMP_loop];
+  let leafConstructs = [OMP_Teams, OMP_Distribute, OMP_Parallel, OMP_Do, OMP_Simd];
 }
-def OMP_target_teams_loop : Directive<"target teams loop"> {
+def OMP_TeamsDistributeParallelFor :
+    Directive<"teams distribute parallel for"> {
   let allowedClauses = [
-    VersionedClause<OMPC_If>,
     VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_Depend>,
-    VersionedClause<OMPC_DefaultMap>,
-    VersionedClause<OMPC_Device>,
+    VersionedClause<OMPC_Collapse>,
+    VersionedClause<OMPC_Copyin>,
+    VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_DistSchedule>,
     VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_IsDevicePtr>,
-    VersionedClause<OMPC_HasDeviceAddr, 51>,
+    VersionedClause<OMPC_If>,
     VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Map>,
+    VersionedClause<OMPC_NumTeams>,
+    VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Order, 50>,
     VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_ProcBind>,
     VersionedClause<OMPC_Reduction>,
+    VersionedClause<OMPC_Schedule>,
     VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_UsesAllocators, 50>,
-    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_ThreadLimit>,
   ];
-  let allowedOnceClauses = [
-    VersionedClause<OMPC_Bind, 50>,
+  let leafConstructs = [OMP_Teams, OMP_Distribute, OMP_Parallel, OMP_For];
+}
+def OMP_TeamsDistributeParallelForSimd :
+    Directive<"teams distribute parallel for simd"> {
+  let allowedClauses = [
+    VersionedClause<OMPC_Aligned>,
+    VersionedClause<OMPC_Allocate>,
     VersionedClause<OMPC_Collapse>,
     VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_NoWait>,
+    VersionedClause<OMPC_DistSchedule>,
+    VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_If>,
+    VersionedClause<OMPC_LastPrivate>,
+    VersionedClause<OMPC_Linear>,
+    VersionedClause<OMPC_NonTemporal, 50>,
     VersionedClause<OMPC_NumTeams>,
-    VersionedClause<OMPC_Order>,
+    VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_OMPX_Attribute>,
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_Private>,
+    VersionedClause<OMPC_ProcBind>,
+    VersionedClause<OMPC_Reduction>,
+    VersionedClause<OMPC_SafeLen>,
+    VersionedClause<OMPC_Schedule>,
+    VersionedClause<OMPC_Shared>,
+    VersionedClause<OMPC_SimdLen>,
     VersionedClause<OMPC_ThreadLimit>,
-    VersionedClause<OMPC_OMPX_DynCGroupMem>,
   ];
-  let leafConstructs = [OMP_Target, OMP_Teams, OMP_loop];
+  let leafConstructs = [OMP_Teams, OMP_Distribute, OMP_Parallel, OMP_For, OMP_Simd];
 }
-def OMP_parallel_loop : Directive<"parallel loop"> {
+def OMP_TeamsDistributeSimd : Directive<"teams distribute simd"> {
   let allowedClauses = [
+    VersionedClause<OMPC_Aligned>,
     VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_Copyin>,
     VersionedClause<OMPC_FirstPrivate>,
+    VersionedClause<OMPC_If, 50>,
     VersionedClause<OMPC_LastPrivate>,
+    VersionedClause<OMPC_Linear>,
+    VersionedClause<OMPC_NonTemporal, 50>,
+    VersionedClause<OMPC_OMPX_Attribute>,
     VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_Reduction>,
     VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_OMPX_Attribute>,
   ];
   let allowedOnceClauses = [
-    VersionedClause<OMPC_Bind, 50>,
     VersionedClause<OMPC_Collapse>,
     VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_If>,
-    VersionedClause<OMPC_NumThreads>,
-    VersionedClause<OMPC_Order>,
-    VersionedClause<OMPC_ProcBind>,
+    VersionedClause<OMPC_DistSchedule>,
+    VersionedClause<OMPC_NumTeams>,
+    VersionedClause<OMPC_Order, 50>,
+    VersionedClause<OMPC_SafeLen>,
+    VersionedClause<OMPC_SimdLen>,
+    VersionedClause<OMPC_ThreadLimit>,
   ];
-  let leafConstructs = [OMP_Parallel, OMP_loop];
+  let leafConstructs = [OMP_Teams, OMP_Distribute, OMP_Simd];
 }
-def OMP_target_parallel_loop : Directive<"target parallel loop"> {
+def OMP_teams_loop : Directive<"teams loop"> {
   let allowedClauses = [
-    VersionedClause<OMPC_If>,
     VersionedClause<OMPC_Allocate>,
-    VersionedClause<OMPC_Copyin>,
-    VersionedClause<OMPC_Depend>,
-    VersionedClause<OMPC_Device>,
     VersionedClause<OMPC_FirstPrivate>,
-    VersionedClause<OMPC_IsDevicePtr>,
-    VersionedClause<OMPC_HasDeviceAddr, 51>,
     VersionedClause<OMPC_LastPrivate>,
-    VersionedClause<OMPC_Map>,
+    VersionedClause<OMPC_OMPX_Attribute>,
     VersionedClause<OMPC_Private>,
     VersionedClause<OMPC_Reduction>,
     VersionedClause<OMPC_Shared>,
-    VersionedClause<OMPC_UsesAllocators, 50>,
-    VersionedClause<OMPC_OMPX_Attribute>,
   ];
   let allowedOnceClauses = [
     VersionedClause<OMPC_Bind, 50>,
     VersionedClause<OMPC_Collapse>,
     VersionedClause<OMPC_Default>,
-    VersionedClause<OMPC_DefaultMap>,
-    VersionedClause<OMPC_NoWait>,
-    VersionedClause<OMPC_NumThreads>,
+    VersionedClause<OMPC_NumTeams>,
     VersionedClause<OMPC_Order>,
-    VersionedClause<OMPC_ProcBind>,
-    VersionedClause<OMPC_OMPX_DynCGroupMem>,
-    VersionedClause<OMPC_ThreadLimit, 51>,
+    VersionedClause<OMPC_ThreadLimit>,
   ];
-  let leafConstructs = [OMP_Target, OMP_Parallel, OMP_loop];
-}
-def OMP_Metadirective : Directive<"metadirective"> {
-  let allowedClauses = [VersionedClause<OMPC_When>];
-  let allowedOnceClauses = [VersionedClause<OMPC_Default>];
-  let association = AS_None;
-}
-
-def OMP_Unknown : Directive<"unknown"> {
-  let isDefault = true;
-  let association = AS_None;
+  let leafConstructs = [OMP_Teams, OMP_loop];
 }

>From 64fcf25e2158de44bccf725a0f91d8228b7cb7a5 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Thu, 6 Jun 2024 15:10:13 -0500
Subject: [PATCH 02/10] [Frontend] Introduce `getDirectiveCategory` for ACC/OMP
 directives

The categories are primarily meant for OpenMP, where the spec assigns
a category to each directive. It's one of declarative, executable,
informational, meta, subsidiary, and utility.

These will be used in clang to avoid listing directives belonging
to certain categories by hand.
---
 .../llvm/Frontend/Directive/DirectiveBase.td  |  15 +++
 llvm/include/llvm/Frontend/OpenACC/ACC.td     |  21 ++++
 llvm/include/llvm/Frontend/OpenMP/OMP.td      | 109 ++++++++++++++++++
 llvm/include/llvm/TableGen/DirectiveEmitter.h |   6 +
 llvm/test/TableGen/directive1.td              |  23 +++-
 llvm/test/TableGen/directive2.td              |  23 +++-
 llvm/utils/TableGen/DirectiveEmitter.cpp      |  31 ++++-
 7 files changed, 225 insertions(+), 3 deletions(-)

diff --git a/llvm/include/llvm/Frontend/Directive/DirectiveBase.td b/llvm/include/llvm/Frontend/Directive/DirectiveBase.td
index ce532e0cfae29..6889c7e642ec6 100644
--- a/llvm/include/llvm/Frontend/Directive/DirectiveBase.td
+++ b/llvm/include/llvm/Frontend/Directive/DirectiveBase.td
@@ -156,6 +156,18 @@ def AS_FromLeaves : Association<"FromLeaves"> {}    // See below
 // The name "AS_FromLeaves" is recognized by TableGen, and there is no enum
 // generated for it.
 
+// Kinds of directive categories.
+class Category<string n> {
+  string name = n;  // Name of the enum value in enum class Category.
+}
+
+def CA_Declarative: Category<"Declarative"> {}
+def CA_Executable: Category<"Executable"> {}
+def CA_Informational: Category<"Informational"> {}
+def CA_Meta: Category<"Meta"> {}
+def CA_Subsidiary: Category<"Subsidiary"> {}
+def CA_Utility: Category<"Utility"> {}
+
 // Information about a specific directive.
 class Directive<string d> {
   // Name of the directive. Can be composite directive sepearted by whitespace.
@@ -190,4 +202,7 @@ class Directive<string d> {
 
   // What the directive is associated with.
   Association association = AS_FromLeaves;
+
+  // The category if the directive.
+  Category category = ?;
 }
diff --git a/llvm/include/llvm/Frontend/OpenACC/ACC.td b/llvm/include/llvm/Frontend/OpenACC/ACC.td
index dfa6a222e9f77..30a81efe7f8a6 100644
--- a/llvm/include/llvm/Frontend/OpenACC/ACC.td
+++ b/llvm/include/llvm/Frontend/OpenACC/ACC.td
@@ -268,6 +268,7 @@ def ACCC_Unknown : Clause<"unknown"> {
 // 2.12
 def ACC_Atomic : Directive<"atomic"> {
   let association = AS_Block;
+  let category = CA_Executable;
 }
 
 // 2.6.5
@@ -293,6 +294,7 @@ def ACC_Data : Directive<"data"> {
     VersionedClause<ACCC_Present>
   ];
   let association = AS_Block;
+  let category = CA_Executable;
 }
 
 // 2.13
@@ -308,6 +310,7 @@ def ACC_Declare : Directive<"declare"> {
     VersionedClause<ACCC_Link>
   ];
   let association = AS_None;
+  let category = CA_Executable;
 }
 
 // 2.5.3
@@ -334,6 +337,7 @@ def ACC_Kernels : Directive<"kernels"> {
     VersionedClause<ACCC_VectorLength>
   ];
   let association = AS_Block;
+  let category = CA_Executable;
 }
 
 // 2.5.1
@@ -363,6 +367,7 @@ def ACC_Parallel : Directive<"parallel"> {
     VersionedClause<ACCC_Self>
   ];
   let association = AS_Block;
+  let category = CA_Executable;
 }
 
 // 2.5.2
@@ -391,6 +396,7 @@ def ACC_Serial : Directive<"serial"> {
     VersionedClause<ACCC_Self>
   ];
   let association = AS_Block;
+  let category = CA_Executable;
 }
 
 // 2.9
@@ -411,11 +417,13 @@ def ACC_Loop : Directive<"loop"> {
     VersionedClause<ACCC_Seq>
   ];
   let association = AS_Loop;
+  let category = CA_Executable;
 }
 
 // 2.10
 def ACC_Cache : Directive<"cache"> {
   let association = AS_None;
+  let category = CA_Executable;
 }
 
 // 2.14.1
@@ -426,6 +434,7 @@ def ACC_Init : Directive<"init"> {
     VersionedClause<ACCC_If>
   ];
   let association = AS_None;
+  let category = CA_Executable;
 }
 
 // 2.15.1
@@ -442,6 +451,7 @@ def ACC_Routine : Directive<"routine"> {
     VersionedClause<ACCC_NoHost>
   ];
   let association = AS_Declaration;
+  let category = CA_Declarative;
 }
 
 // 2.14.3
@@ -461,6 +471,7 @@ def ACC_Set : Directive<"set"> {
     VersionedClause<ACCC_DeviceType>
   ];
   let association = AS_None;
+  let category = CA_Executable;
 }
 
 // 2.14.2
@@ -471,6 +482,7 @@ def ACC_Shutdown : Directive<"shutdown"> {
     VersionedClause<ACCC_If>
   ];
   let association = AS_None;
+  let category = CA_Executable;
 }
 
 // 2.14.4
@@ -490,6 +502,7 @@ def ACC_Update : Directive<"update"> {
     VersionedClause<ACCC_Self>
   ];
   let association = AS_None;
+  let category = CA_Executable;
 }
 
 // 2.16.3
@@ -499,6 +512,7 @@ def ACC_Wait : Directive<"wait"> {
     VersionedClause<ACCC_If>
   ];
   let association = AS_None;
+  let category = CA_Executable;
 }
 
 // 2.14.6
@@ -516,6 +530,7 @@ def ACC_EnterData : Directive<"enter data"> {
     VersionedClause<ACCC_Copyin>
   ];
   let association = AS_None;
+  let category = CA_Executable;
 }
 
 // 2.14.7
@@ -534,6 +549,7 @@ def ACC_ExitData : Directive<"exit data"> {
     VersionedClause<ACCC_Detach>
   ];
   let association = AS_None;
+  let category = CA_Executable;
 }
 
 // 2.8
@@ -546,6 +562,7 @@ def ACC_HostData : Directive<"host_data"> {
     VersionedClause<ACCC_UseDevice>
   ];
   let association = AS_Block;
+  let category = CA_Executable;
 }
 
 // 2.11
@@ -584,6 +601,7 @@ def ACC_KernelsLoop : Directive<"kernels loop"> {
     VersionedClause<ACCC_Seq>
   ];
   let leafConstructs = [ACC_Kernels, ACC_Loop];
+  let category = CA_Executable;
 }
 
 // 2.11
@@ -623,6 +641,7 @@ def ACC_ParallelLoop : Directive<"parallel loop"> {
     VersionedClause<ACCC_Seq>
   ];
   let leafConstructs = [ACC_Parallel, ACC_Loop];
+  let category = CA_Executable;
 }
 
 // 2.11
@@ -659,9 +678,11 @@ def ACC_SerialLoop : Directive<"serial loop"> {
     VersionedClause<ACCC_Seq>
   ];
   let leafConstructs = [ACC_Serial, ACC_Loop];
+  let category = CA_Executable;
 }
 
 def ACC_Unknown : Directive<"unknown"> {
   let isDefault = true;
   let association = AS_None;
+  let category = CA_Utility;
 }
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index afb8d5f725753..12a944e34c414 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -493,18 +493,22 @@ def OMP_Allocate : Directive<"allocate"> {
     VersionedClause<OMPC_Allocator>,
   ];
   let association = AS_None;
+  let category = CA_Declarative;
 }
 def OMP_Allocators : Directive<"allocators"> {
   let allowedClauses = [
     VersionedClause<OMPC_Allocate>,
   ];
   let association = AS_Block;
+  let category = CA_Executable;
 }
 def OMP_Assumes : Directive<"assumes"> {
   let association = AS_None;
+  let category = CA_Informational;
 }
 def OMP_EndAssumes : Directive<"end assumes"> {
   let association = AS_Delimited;
+  let category = OMP_Assumes.category;
 }
 def OMP_Atomic : Directive<"atomic"> {
   let allowedClauses = [
@@ -525,12 +529,15 @@ def OMP_Atomic : Directive<"atomic"> {
     VersionedClause<OMPC_Weak, 51>,
   ];
   let association = AS_Block;
+  let category = CA_Executable;
 }
 def OMP_Barrier : Directive<"barrier"> {
   let association = AS_None;
+  let category = CA_Executable;
 }
 def OMP_BeginAssumes : Directive<"begin assumes"> {
   let association = AS_Delimited;
+  let category = CA_Informational;
 }
 def OMP_BeginDeclareTarget : Directive<"begin declare target"> {
   let allowedClauses = [
@@ -540,33 +547,40 @@ def OMP_BeginDeclareTarget : Directive<"begin declare target"> {
     VersionedClause<OMPC_To>,
   ];
   let association = AS_Delimited;
+  let category = CA_Declarative;
 }
 def OMP_BeginDeclareVariant : Directive<"begin declare variant"> {
   let association = AS_Delimited;
+  let category = CA_Declarative;
 }
 def OMP_Cancel : Directive<"cancel"> {
   let allowedOnceClauses = [
     VersionedClause<OMPC_If>,
   ];
   let association = AS_None;
+  let category = CA_Executable;
 }
 def OMP_CancellationPoint : Directive<"cancellation point"> {
   let association = AS_None;
+  let category = CA_Executable;
 }
 def OMP_Critical : Directive<"critical"> {
   let allowedClauses = [
     VersionedClause<OMPC_Hint>,
   ];
   let association = AS_Block;
+  let category = CA_Executable;
 }
 def OMP_DeclareMapper : Directive<"declare mapper"> {
   let allowedClauses = [
     VersionedClause<OMPC_Map>,
   ];
   let association = AS_None;
+  let category = CA_Declarative;
 }
 def OMP_DeclareReduction : Directive<"declare reduction"> {
   let association = AS_None;
+  let category = CA_Declarative;
 }
 def OMP_DeclareSimd : Directive<"declare simd"> {
   let allowedClauses = [
@@ -582,6 +596,7 @@ def OMP_DeclareSimd : Directive<"declare simd"> {
     VersionedClause<OMPC_Notinbranch>,
   ];
   let association = AS_Declaration;
+  let category = CA_Declarative;
 }
 def OMP_DeclareTarget : Directive<"declare target"> {
   let allowedClauses = [
@@ -594,9 +609,11 @@ def OMP_DeclareTarget : Directive<"declare target"> {
     VersionedClause<OMPC_DeviceType, 50>,
   ];
   let association = AS_None;
+  let category = CA_Declarative;
 }
 def OMP_EndDeclareTarget : Directive<"end declare target"> {
   let association = AS_Delimited;
+  let category = OMP_DeclareTarget.category;
 }
 def OMP_DeclareVariant : Directive<"declare variant"> {
   let allowedClauses = [
@@ -607,9 +624,11 @@ def OMP_DeclareVariant : Directive<"declare variant"> {
     VersionedClause<OMPC_AppendArgs, 51>,
   ];
   let association = AS_Declaration;
+  let category = CA_Declarative;
 }
 def OMP_EndDeclareVariant : Directive<"end declare variant"> {
   let association = AS_Delimited;
+  let category = OMP_DeclareVariant.category;
 }
 def OMP_Depobj : Directive<"depobj"> {
   let allowedClauses = [
@@ -621,6 +640,7 @@ def OMP_Depobj : Directive<"depobj"> {
     VersionedClause<OMPC_Update, 50>,
   ];
   let association = AS_None;
+  let category = CA_Executable;
 }
 def OMP_dispatch : Directive<"dispatch"> {
   let allowedClauses = [
@@ -633,6 +653,7 @@ def OMP_dispatch : Directive<"dispatch"> {
     VersionedClause<OMPC_NoWait>,
   ];
   let association = AS_Block;
+  let category = CA_Executable;
 }
 def OMP_Distribute : Directive<"distribute"> {
   let allowedClauses = [
@@ -646,6 +667,7 @@ def OMP_Distribute : Directive<"distribute"> {
     VersionedClause<OMPC_DistSchedule>,
   ];
   let association = AS_Loop;
+  let category = CA_Executable;
 }
 def OMP_Do : Directive<"do"> {
   let allowedClauses = [
@@ -663,6 +685,7 @@ def OMP_Do : Directive<"do"> {
     VersionedClause<OMPC_Schedule>,
   ];
   let association = AS_Loop;
+  let category = CA_Executable;
 }
 def OMP_EndDo : Directive<"end do"> {
   let allowedOnceClauses = [
@@ -671,6 +694,7 @@ def OMP_EndDo : Directive<"end do"> {
   // Needed for association computation, since OMP_Do has it "from leafConstructs".
   let leafConstructs = OMP_Do.leafConstructs;
   let association = OMP_Do.association;
+  let category = OMP_Do.category;
 }
 def OMP_Error : Directive<"error"> {
   let allowedClauses = [
@@ -679,6 +703,7 @@ def OMP_Error : Directive<"error"> {
     VersionedClause<OMPC_Severity, 51>,
   ];
   let association = AS_None;
+  let category = CA_Utility;
 }
 def OMP_Flush : Directive<"flush"> {
   let allowedOnceClauses = [
@@ -690,6 +715,7 @@ def OMP_Flush : Directive<"flush"> {
     VersionedClause<OMPC_Release, 50>,
   ];
   let association = AS_None;
+  let category = CA_Executable;
 }
 def OMP_For : Directive<"for"> {
   let allowedClauses = [
@@ -706,6 +732,7 @@ def OMP_For : Directive<"for"> {
     VersionedClause<OMPC_Schedule>,
   ];
   let association = AS_Loop;
+  let category = CA_Executable;
 }
 def OMP_interop : Directive<"interop"> {
   let allowedClauses = [
@@ -717,6 +744,7 @@ def OMP_interop : Directive<"interop"> {
     VersionedClause<OMPC_Use>,
   ];
   let association = AS_None;
+  let category = CA_Executable;
 }
 def OMP_loop : Directive<"loop"> {
   let allowedClauses = [
@@ -730,15 +758,18 @@ def OMP_loop : Directive<"loop"> {
     VersionedClause<OMPC_Order, 50>,
   ];
   let association = AS_Loop;
+  let category = CA_Executable;
 }
 def OMP_masked : Directive<"masked"> {
   let allowedOnceClauses = [
     VersionedClause<OMPC_Filter>,
   ];
   let association = AS_Block;
+  let category = CA_Executable;
 }
 def OMP_Master : Directive<"master"> {
   let association = AS_Block;
+  let category = CA_Executable;
 }
 def OMP_Metadirective : Directive<"metadirective"> {
   let allowedClauses = [
@@ -748,9 +779,11 @@ def OMP_Metadirective : Directive<"metadirective"> {
     VersionedClause<OMPC_Default>,
   ];
   let association = AS_None;
+  let category = CA_Meta;
 }
 def OMP_Nothing : Directive<"nothing"> {
   let association = AS_None;
+  let category = CA_Utility;
 }
 def OMP_Ordered : Directive<"ordered"> {
   let allowedClauses = [
@@ -763,6 +796,7 @@ def OMP_Ordered : Directive<"ordered"> {
   ];
   let association = AS_None;
   // There is also a block-associated "ordered" directive.
+  let category = CA_Executable;
 }
 def OMP_Parallel : Directive<"parallel"> {
   let allowedClauses = [
@@ -781,6 +815,7 @@ def OMP_Parallel : Directive<"parallel"> {
     VersionedClause<OMPC_ProcBind>,
   ];
   let association = AS_Block;
+  let category = CA_Executable;
 }
 def OMP_Requires : Directive<"requires"> {
   let allowedOnceClauses = [
@@ -799,6 +834,7 @@ def OMP_Requires : Directive<"requires"> {
     VersionedClause<OMPC_ReverseOffload, 99>,
   ];
   let association = AS_None;
+  let category = CA_Informational;
 }
 def OMP_Scan : Directive<"scan"> {
   let allowedClauses = [
@@ -806,6 +842,7 @@ def OMP_Scan : Directive<"scan"> {
     VersionedClause<OMPC_Inclusive, 50>,
   ];
   let association = AS_Separating;
+  let category = CA_Subsidiary;
 }
 def OMP_scope : Directive<"scope"> {
   let allowedClauses = [
@@ -816,9 +853,11 @@ def OMP_scope : Directive<"scope"> {
     VersionedClause<OMPC_NoWait, 51>,
   ];
   let association = AS_Block;
+  let category = CA_Executable;
 }
 def OMP_Section : Directive<"section"> {
   let association = AS_Separating;
+  let category = CA_Subsidiary;
 }
 def OMP_Sections : Directive<"sections"> {
   let allowedClauses = [
@@ -830,6 +869,7 @@ def OMP_Sections : Directive<"sections"> {
     VersionedClause<OMPC_Reduction>,
   ];
   let association = AS_Block;
+  let category = CA_Executable;
 }
 def OMP_EndSections : Directive<"end sections"> {
   let allowedOnceClauses = [
@@ -837,6 +877,7 @@ def OMP_EndSections : Directive<"end sections"> {
   ];
   let leafConstructs = OMP_Sections.leafConstructs;
   let association = OMP_Sections.association;
+  let category = OMP_Sections.category;
 }
 def OMP_Simd : Directive<"simd"> {
   let allowedClauses = [
@@ -856,6 +897,7 @@ def OMP_Simd : Directive<"simd"> {
     VersionedClause<OMPC_SimdLen>,
   ];
   let association = AS_Loop;
+  let category = CA_Executable;
 }
 def OMP_Single : Directive<"single"> {
   let allowedClauses = [
@@ -866,6 +908,7 @@ def OMP_Single : Directive<"single"> {
     VersionedClause<OMPC_Private>,
   ];
   let association = AS_Block;
+  let category = CA_Executable;
 }
 def OMP_EndSingle : Directive<"end single"> {
   let allowedClauses = [
@@ -876,6 +919,7 @@ def OMP_EndSingle : Directive<"end single"> {
   ];
   let leafConstructs = OMP_Single.leafConstructs;
   let association = OMP_Single.association;
+  let category = OMP_Single.category;
 }
 def OMP_Target : Directive<"target"> {
   let allowedClauses = [
@@ -899,6 +943,7 @@ def OMP_Target : Directive<"target"> {
     VersionedClause<OMPC_ThreadLimit, 51>,
   ];
   let association = AS_Block;
+  let category = CA_Executable;
 }
 def OMP_TargetData : Directive<"target data"> {
   let allowedOnceClauses = [
@@ -911,6 +956,7 @@ def OMP_TargetData : Directive<"target data"> {
     VersionedClause<OMPC_UseDevicePtr>,
   ];
   let association = AS_Block;
+  let category = CA_Executable;
 }
 def OMP_TargetEnterData : Directive<"target enter data"> {
   let allowedClauses = [
@@ -925,6 +971,7 @@ def OMP_TargetEnterData : Directive<"target enter data"> {
     VersionedClause<OMPC_Map>,
   ];
   let association = AS_None;
+  let category = CA_Executable;
 }
 def OMP_TargetExitData : Directive<"target exit data"> {
   let allowedClauses = [
@@ -939,6 +986,7 @@ def OMP_TargetExitData : Directive<"target exit data"> {
     VersionedClause<OMPC_Map>,
   ];
   let association = AS_None;
+  let category = CA_Executable;
 }
 def OMP_TargetUpdate : Directive<"target update"> {
   let allowedClauses = [
@@ -952,6 +1000,7 @@ def OMP_TargetUpdate : Directive<"target update"> {
     VersionedClause<OMPC_NoWait>,
   ];
   let association = AS_None;
+  let category = CA_Executable;
 }
 def OMP_Task : Directive<"task"> {
   let allowedClauses = [
@@ -973,6 +1022,7 @@ def OMP_Task : Directive<"task"> {
     VersionedClause<OMPC_Priority>,
   ];
   let association = AS_Block;
+  let category = CA_Executable;
 }
 def OMP_TaskGroup : Directive<"taskgroup"> {
   let allowedClauses = [
@@ -980,6 +1030,7 @@ def OMP_TaskGroup : Directive<"taskgroup"> {
     VersionedClause<OMPC_TaskReduction, 50>,
   ];
   let association = AS_Block;
+  let category = CA_Executable;
 }
 def OMP_TaskLoop : Directive<"taskloop"> {
   let allowedClauses = [
@@ -1006,6 +1057,7 @@ def OMP_TaskLoop : Directive<"taskloop"> {
     VersionedClause<OMPC_NumTasks>,
   ];
   let association = AS_Loop;
+  let category = CA_Executable;
 }
 def OMP_TaskWait : Directive<"taskwait"> {
   let allowedClauses = [
@@ -1013,9 +1065,11 @@ def OMP_TaskWait : Directive<"taskwait"> {
     VersionedClause<OMPC_NoWait, 51>,
   ];
   let association = AS_None;
+  let category = CA_Executable;
 }
 def OMP_TaskYield : Directive<"taskyield"> {
   let association = AS_None;
+  let category = CA_Executable;
 }
 def OMP_Teams : Directive<"teams"> {
   let allowedClauses = [
@@ -1033,19 +1087,23 @@ def OMP_Teams : Directive<"teams"> {
     VersionedClause<OMPC_ThreadLimit>,
   ];
   let association = AS_Block;
+  let category = CA_Executable;
 }
 def OMP_ThreadPrivate : Directive<"threadprivate"> {
   let association = AS_None;
+  let category = CA_Declarative;
 }
 def OMP_Tile : Directive<"tile"> {
   let allowedOnceClauses = [
     VersionedClause<OMPC_Sizes, 51>,
   ];
   let association = AS_Loop;
+  let category = CA_Executable;
 }
 def OMP_Unknown : Directive<"unknown"> {
   let isDefault = true;
   let association = AS_None;
+  let category = CA_Utility;
 }
 def OMP_Unroll : Directive<"unroll"> {
   let allowedOnceClauses = [
@@ -1053,12 +1111,14 @@ def OMP_Unroll : Directive<"unroll"> {
     VersionedClause<OMPC_Partial, 51>,
   ];
   let association = AS_Loop;
+  let category = CA_Executable;
 }
 def OMP_Workshare : Directive<"workshare"> {
   let allowedOnceClauses = [
     VersionedClause<OMPC_NoWait>,
   ];
   let association = AS_Block;
+  let category = CA_Executable;
 }
 def OMP_EndWorkshare : Directive<"end workshare"> {
   let allowedClauses = [
@@ -1066,6 +1126,7 @@ def OMP_EndWorkshare : Directive<"end workshare"> {
   ];
   let leafConstructs = OMP_Workshare.leafConstructs;
   let association = OMP_Workshare.association;
+  let category = OMP_Workshare.category;
 }
 
 //===----------------------------------------------------------------------===//
@@ -1097,6 +1158,7 @@ def OMP_DistributeParallelDo : Directive<"distribute parallel do"> {
     VersionedClause<OMPC_Schedule>,
   ];
   let leafConstructs = [OMP_Distribute, OMP_Parallel, OMP_Do];
+  let category = CA_Executable;
 }
 def OMP_DistributeParallelDoSimd : Directive<"distribute parallel do simd"> {
   let allowedClauses = [
@@ -1122,6 +1184,7 @@ def OMP_DistributeParallelDoSimd : Directive<"distribute parallel do simd"> {
     VersionedClause<OMPC_SimdLen>,
   ];
   let leafConstructs = [OMP_Distribute, OMP_Parallel, OMP_Do, OMP_Simd];
+  let category = CA_Executable;
 }
 def OMP_DistributeParallelFor : Directive<"distribute parallel for"> {
   let allowedClauses = [
@@ -1143,6 +1206,7 @@ def OMP_DistributeParallelFor : Directive<"distribute parallel for"> {
     VersionedClause<OMPC_Shared>,
   ];
   let leafConstructs = [OMP_Distribute, OMP_Parallel, OMP_For];
+  let category = CA_Executable;
 }
 def OMP_DistributeParallelForSimd : Directive<"distribute parallel for simd"> {
   let allowedClauses = [
@@ -1169,6 +1233,7 @@ def OMP_DistributeParallelForSimd : Directive<"distribute parallel for simd"> {
     VersionedClause<OMPC_SimdLen>,
   ];
   let leafConstructs = [OMP_Distribute, OMP_Parallel, OMP_For, OMP_Simd];
+  let category = CA_Executable;
 }
 def OMP_DistributeSimd : Directive<"distribute simd"> {
   let allowedClauses = [
@@ -1196,6 +1261,7 @@ def OMP_DistributeSimd : Directive<"distribute simd"> {
     VersionedClause<OMPC_SimdLen>,
   ];
   let leafConstructs = [OMP_Distribute, OMP_Simd];
+  let category = CA_Executable;
 }
 def OMP_DoSimd : Directive<"do simd"> {
   let allowedClauses = [
@@ -1217,6 +1283,7 @@ def OMP_DoSimd : Directive<"do simd"> {
     VersionedClause<OMPC_SimdLen>,
   ];
   let leafConstructs = [OMP_Do, OMP_Simd];
+  let category = CA_Executable;
 }
 def OMP_EndDoSimd : Directive<"end do simd"> {
   let allowedOnceClauses = [
@@ -1224,6 +1291,7 @@ def OMP_EndDoSimd : Directive<"end do simd"> {
   ];
   let leafConstructs = OMP_DoSimd.leafConstructs;
   let association = OMP_DoSimd.association;
+  let category = OMP_DoSimd.category;
 }
 def OMP_ForSimd : Directive<"for simd"> {
   let allowedClauses = [
@@ -1245,6 +1313,7 @@ def OMP_ForSimd : Directive<"for simd"> {
     VersionedClause<OMPC_SimdLen>,
   ];
   let leafConstructs = [OMP_For, OMP_Simd];
+  let category = CA_Executable;
 }
 def OMP_MaskedTaskloop : Directive<"masked taskloop"> {
   let allowedClauses = [
@@ -1268,6 +1337,7 @@ def OMP_MaskedTaskloop : Directive<"masked taskloop"> {
     VersionedClause<OMPC_Untied>,
   ];
   let leafConstructs = [OMP_masked, OMP_TaskLoop];
+  let category = CA_Executable;
 }
 def OMP_MaskedTaskloopSimd : Directive<"masked taskloop simd"> {
   let allowedClauses = [
@@ -1297,6 +1367,7 @@ def OMP_MaskedTaskloopSimd : Directive<"masked taskloop simd"> {
     VersionedClause<OMPC_Untied>,
   ];
   let leafConstructs = [OMP_masked, OMP_TaskLoop, OMP_Simd];
+  let category = CA_Executable;
 }
 def OMP_MasterTaskloop : Directive<"master taskloop"> {
   let allowedClauses = [
@@ -1319,6 +1390,7 @@ def OMP_MasterTaskloop : Directive<"master taskloop"> {
     VersionedClause<OMPC_Untied>,
   ];
   let leafConstructs = [OMP_Master, OMP_TaskLoop];
+  let category = CA_Executable;
 }
 def OMP_MasterTaskloopSimd : Directive<"master taskloop simd"> {
   let allowedClauses = [
@@ -1347,6 +1419,7 @@ def OMP_MasterTaskloopSimd : Directive<"master taskloop simd"> {
     VersionedClause<OMPC_Untied>,
   ];
   let leafConstructs = [OMP_Master, OMP_TaskLoop, OMP_Simd];
+  let category = CA_Executable;
 }
 def OMP_ParallelDo : Directive<"parallel do"> {
   let allowedClauses = [
@@ -1369,6 +1442,7 @@ def OMP_ParallelDo : Directive<"parallel do"> {
     VersionedClause<OMPC_Schedule>,
   ];
   let leafConstructs = [OMP_Parallel, OMP_Do];
+  let category = CA_Executable;
 }
 def OMP_ParallelDoSimd : Directive<"parallel do simd"> {
   let allowedClauses = [
@@ -1396,6 +1470,7 @@ def OMP_ParallelDoSimd : Directive<"parallel do simd"> {
     VersionedClause<OMPC_SimdLen>,
   ];
   let leafConstructs = [OMP_Parallel, OMP_Do, OMP_Simd];
+  let category = CA_Executable;
 }
 def OMP_ParallelFor : Directive<"parallel for"> {
   let allowedClauses = [
@@ -1418,6 +1493,7 @@ def OMP_ParallelFor : Directive<"parallel for"> {
     VersionedClause<OMPC_Shared>,
   ];
   let leafConstructs = [OMP_Parallel, OMP_For];
+  let category = CA_Executable;
 }
 def OMP_ParallelForSimd : Directive<"parallel for simd"> {
   let allowedClauses = [
@@ -1444,6 +1520,7 @@ def OMP_ParallelForSimd : Directive<"parallel for simd"> {
     VersionedClause<OMPC_SimdLen>,
   ];
   let leafConstructs = [OMP_Parallel, OMP_For, OMP_Simd];
+  let category = CA_Executable;
 }
 def OMP_parallel_loop : Directive<"parallel loop"> {
   let allowedClauses = [
@@ -1466,6 +1543,7 @@ def OMP_parallel_loop : Directive<"parallel loop"> {
     VersionedClause<OMPC_ProcBind>,
   ];
   let leafConstructs = [OMP_Parallel, OMP_loop];
+  let category = CA_Executable;
 }
 def OMP_ParallelMasked : Directive<"parallel masked"> {
   let allowedClauses = [
@@ -1483,6 +1561,7 @@ def OMP_ParallelMasked : Directive<"parallel masked"> {
     VersionedClause<OMPC_Shared>,
   ];
   let leafConstructs = [OMP_Parallel, OMP_masked];
+  let category = CA_Executable;
 }
 def OMP_ParallelMaskedTaskloop :
     Directive<"parallel masked taskloop"> {
@@ -1510,6 +1589,7 @@ def OMP_ParallelMaskedTaskloop :
     VersionedClause<OMPC_Untied>,
   ];
   let leafConstructs = [OMP_Parallel, OMP_masked, OMP_TaskLoop];
+  let category = CA_Executable;
 }
 def OMP_ParallelMaskedTaskloopSimd :
     Directive<"parallel masked taskloop simd"> {
@@ -1543,6 +1623,7 @@ def OMP_ParallelMaskedTaskloopSimd :
     VersionedClause<OMPC_Untied>,
   ];
   let leafConstructs = [OMP_Parallel, OMP_masked, OMP_TaskLoop, OMP_Simd];
+  let category = CA_Executable;
 }
 def OMP_ParallelMaster : Directive<"parallel master"> {
   let allowedClauses = [
@@ -1559,6 +1640,7 @@ def OMP_ParallelMaster : Directive<"parallel master"> {
     VersionedClause<OMPC_Shared>,
   ];
   let leafConstructs = [OMP_Parallel, OMP_Master];
+  let category = CA_Executable;
 }
 def OMP_ParallelMasterTaskloop :
     Directive<"parallel master taskloop"> {
@@ -1585,6 +1667,7 @@ def OMP_ParallelMasterTaskloop :
     VersionedClause<OMPC_Untied>,
   ];
   let leafConstructs = [OMP_Parallel, OMP_Master, OMP_TaskLoop];
+  let category = CA_Executable;
 }
 def OMP_ParallelMasterTaskloopSimd :
     Directive<"parallel master taskloop simd"> {
@@ -1617,6 +1700,7 @@ def OMP_ParallelMasterTaskloopSimd :
     VersionedClause<OMPC_Untied>,
   ];
   let leafConstructs = [OMP_Parallel, OMP_Master, OMP_TaskLoop, OMP_Simd];
+  let category = CA_Executable;
 }
 def OMP_ParallelSections : Directive<"parallel sections"> {
   let allowedClauses = [
@@ -1636,6 +1720,7 @@ def OMP_ParallelSections : Directive<"parallel sections"> {
     VersionedClause<OMPC_NumThreads>,
   ];
   let leafConstructs = [OMP_Parallel, OMP_Sections];
+  let category = CA_Executable;
 }
 def OMP_ParallelWorkshare : Directive<"parallel workshare"> {
   let allowedClauses = [
@@ -1653,6 +1738,7 @@ def OMP_ParallelWorkshare : Directive<"parallel workshare"> {
     VersionedClause<OMPC_ProcBind>,
   ];
   let leafConstructs = [OMP_Parallel, OMP_Workshare];
+  let category = CA_Executable;
 }
 def OMP_TargetParallel : Directive<"target parallel"> {
   let allowedClauses = [
@@ -1680,6 +1766,7 @@ def OMP_TargetParallel : Directive<"target parallel"> {
     VersionedClause<OMPC_ThreadLimit, 51>,
   ];
   let leafConstructs = [OMP_Target, OMP_Parallel];
+  let category = CA_Executable;
 }
 def OMP_TargetParallelDo : Directive<"target parallel do"> {
   let allowedClauses = [
@@ -1711,6 +1798,7 @@ def OMP_TargetParallelDo : Directive<"target parallel do"> {
     VersionedClause<OMPC_Schedule>,
   ];
   let leafConstructs = [OMP_Target, OMP_Parallel, OMP_Do];
+  let category = CA_Executable;
 }
 def OMP_TargetParallelDoSimd : Directive<"target parallel do simd"> {
   let allowedClauses = [
@@ -1743,6 +1831,7 @@ def OMP_TargetParallelDoSimd : Directive<"target parallel do simd"> {
     VersionedClause<OMPC_UsesAllocators>,
   ];
   let leafConstructs = [OMP_Target, OMP_Parallel, OMP_Do, OMP_Simd];
+  let category = CA_Executable;
 }
 def OMP_TargetParallelFor : Directive<"target parallel for"> {
   let allowedClauses = [
@@ -1776,6 +1865,7 @@ def OMP_TargetParallelFor : Directive<"target parallel for"> {
     VersionedClause<OMPC_ThreadLimit, 51>,
   ];
   let leafConstructs = [OMP_Target, OMP_Parallel, OMP_For];
+  let category = CA_Executable;
 }
 def OMP_TargetParallelForSimd : Directive<"target parallel for simd"> {
   let allowedClauses = [
@@ -1813,6 +1903,7 @@ def OMP_TargetParallelForSimd : Directive<"target parallel for simd"> {
     VersionedClause<OMPC_ThreadLimit, 51>,
   ];
   let leafConstructs = [OMP_Target, OMP_Parallel, OMP_For, OMP_Simd];
+  let category = CA_Executable;
 }
 def OMP_target_parallel_loop : Directive<"target parallel loop"> {
   let allowedClauses = [
@@ -1845,6 +1936,7 @@ def OMP_target_parallel_loop : Directive<"target parallel loop"> {
     VersionedClause<OMPC_ThreadLimit, 51>,
   ];
   let leafConstructs = [OMP_Target, OMP_Parallel, OMP_loop];
+  let category = CA_Executable;
 }
 def OMP_TargetSimd : Directive<"target simd"> {
   let allowedClauses = [
@@ -1880,6 +1972,7 @@ def OMP_TargetSimd : Directive<"target simd"> {
     VersionedClause<OMPC_ThreadLimit, 51>,
   ];
   let leafConstructs = [OMP_Target, OMP_Simd];
+  let category = CA_Executable;
 }
 def OMP_TargetTeams : Directive<"target teams"> {
   let allowedClauses = [
@@ -1907,6 +2000,7 @@ def OMP_TargetTeams : Directive<"target teams"> {
     VersionedClause<OMPC_ThreadLimit>,
   ];
   let leafConstructs = [OMP_Target, OMP_Teams];
+  let category = CA_Executable;
 }
 def OMP_TargetTeamsDistribute : Directive<"target teams distribute"> {
   let allowedClauses = [
@@ -1936,6 +2030,7 @@ def OMP_TargetTeamsDistribute : Directive<"target teams distribute"> {
     VersionedClause<OMPC_ThreadLimit>,
   ];
   let leafConstructs = [OMP_Target, OMP_Teams, OMP_Distribute];
+  let category = CA_Executable;
 }
 def OMP_TargetTeamsDistributeParallelDo :
     Directive<"target teams distribute parallel do"> {
@@ -1971,6 +2066,7 @@ def OMP_TargetTeamsDistributeParallelDo :
     VersionedClause<OMPC_ThreadLimit>,
   ];
   let leafConstructs = [OMP_Target, OMP_Teams, OMP_Distribute, OMP_Parallel, OMP_Do];
+  let category = CA_Executable;
 }
 def OMP_TargetTeamsDistributeParallelDoSimd :
     Directive<"target teams distribute parallel do simd"> {
@@ -2010,6 +2106,7 @@ def OMP_TargetTeamsDistributeParallelDoSimd :
     VersionedClause<OMPC_ThreadLimit>,
   ];
   let leafConstructs = [OMP_Target, OMP_Teams, OMP_Distribute, OMP_Parallel, OMP_Do, OMP_Simd];
+  let category = CA_Executable;
 }
 def OMP_TargetTeamsDistributeParallelFor :
     Directive<"target teams distribute parallel for"> {
@@ -2044,6 +2141,7 @@ def OMP_TargetTeamsDistributeParallelFor :
     VersionedClause<OMPC_OMPX_DynCGroupMem>,
   ];
   let leafConstructs = [OMP_Target, OMP_Teams, OMP_Distribute, OMP_Parallel, OMP_For];
+  let category = CA_Executable;
 }
 def OMP_TargetTeamsDistributeParallelForSimd :
     Directive<"target teams distribute parallel for simd"> {
@@ -2083,6 +2181,7 @@ def OMP_TargetTeamsDistributeParallelForSimd :
     VersionedClause<OMPC_OMPX_DynCGroupMem>,
   ];
   let leafConstructs = [OMP_Target, OMP_Teams, OMP_Distribute, OMP_Parallel, OMP_For, OMP_Simd];
+  let category = CA_Executable;
 }
 def OMP_TargetTeamsDistributeSimd :
     Directive<"target teams distribute simd"> {
@@ -2118,6 +2217,7 @@ def OMP_TargetTeamsDistributeSimd :
     VersionedClause<OMPC_ThreadLimit>,
   ];
   let leafConstructs = [OMP_Target, OMP_Teams, OMP_Distribute, OMP_Simd];
+  let category = CA_Executable;
 }
 def OMP_target_teams_loop : Directive<"target teams loop"> {
   let allowedClauses = [
@@ -2148,6 +2248,7 @@ def OMP_target_teams_loop : Directive<"target teams loop"> {
     VersionedClause<OMPC_ThreadLimit>,
   ];
   let leafConstructs = [OMP_Target, OMP_Teams, OMP_loop];
+  let category = CA_Executable;
 }
 def OMP_TaskLoopSimd : Directive<"taskloop simd"> {
   let allowedClauses = [
@@ -2180,6 +2281,7 @@ def OMP_TaskLoopSimd : Directive<"taskloop simd"> {
     VersionedClause<OMPC_NumTasks>,
   ];
   let leafConstructs = [OMP_TaskLoop, OMP_Simd];
+  let category = CA_Executable;
 }
 def OMP_TeamsDistribute : Directive<"teams distribute"> {
   let allowedClauses = [
@@ -2200,6 +2302,7 @@ def OMP_TeamsDistribute : Directive<"teams distribute"> {
     VersionedClause<OMPC_If>,
   ];
   let leafConstructs = [OMP_Teams, OMP_Distribute];
+  let category = CA_Executable;
 }
 def OMP_TeamsDistributeParallelDo :
     Directive<"teams distribute parallel do"> {
@@ -2227,6 +2330,7 @@ def OMP_TeamsDistributeParallelDo :
     VersionedClause<OMPC_ThreadLimit>,
   ];
   let leafConstructs = [OMP_Teams, OMP_Distribute, OMP_Parallel, OMP_Do];
+  let category = CA_Executable;
 }
 def OMP_TeamsDistributeParallelDoSimd :
     Directive<"teams distribute parallel do simd"> {
@@ -2256,6 +2360,7 @@ def OMP_TeamsDistributeParallelDoSimd :
     VersionedClause<OMPC_ThreadLimit>,
   ];
   let leafConstructs = [OMP_Teams, OMP_Distribute, OMP_Parallel, OMP_Do, OMP_Simd];
+  let category = CA_Executable;
 }
 def OMP_TeamsDistributeParallelFor :
     Directive<"teams distribute parallel for"> {
@@ -2280,6 +2385,7 @@ def OMP_TeamsDistributeParallelFor :
     VersionedClause<OMPC_ThreadLimit>,
   ];
   let leafConstructs = [OMP_Teams, OMP_Distribute, OMP_Parallel, OMP_For];
+  let category = CA_Executable;
 }
 def OMP_TeamsDistributeParallelForSimd :
     Directive<"teams distribute parallel for simd"> {
@@ -2308,6 +2414,7 @@ def OMP_TeamsDistributeParallelForSimd :
     VersionedClause<OMPC_ThreadLimit>,
   ];
   let leafConstructs = [OMP_Teams, OMP_Distribute, OMP_Parallel, OMP_For, OMP_Simd];
+  let category = CA_Executable;
 }
 def OMP_TeamsDistributeSimd : Directive<"teams distribute simd"> {
   let allowedClauses = [
@@ -2334,6 +2441,7 @@ def OMP_TeamsDistributeSimd : Directive<"teams distribute simd"> {
     VersionedClause<OMPC_ThreadLimit>,
   ];
   let leafConstructs = [OMP_Teams, OMP_Distribute, OMP_Simd];
+  let category = CA_Executable;
 }
 def OMP_teams_loop : Directive<"teams loop"> {
   let allowedClauses = [
@@ -2354,4 +2462,5 @@ def OMP_teams_loop : Directive<"teams loop"> {
     VersionedClause<OMPC_ThreadLimit>,
   ];
   let leafConstructs = [OMP_Teams, OMP_loop];
+  let category = CA_Executable;
 }
diff --git a/llvm/include/llvm/TableGen/DirectiveEmitter.h b/llvm/include/llvm/TableGen/DirectiveEmitter.h
index bd536d4a2b7f8..1121459be6ce7 100644
--- a/llvm/include/llvm/TableGen/DirectiveEmitter.h
+++ b/llvm/include/llvm/TableGen/DirectiveEmitter.h
@@ -55,6 +55,10 @@ class DirectiveLanguage {
     return Records.getAllDerivedDefinitions("Association");
   }
 
+  std::vector<Record *> getCategories() const {
+    return Records.getAllDerivedDefinitions("Category");
+  }
+
   std::vector<Record *> getDirectives() const {
     return Records.getAllDerivedDefinitions("Directive");
   }
@@ -131,6 +135,8 @@ class Directive : public BaseRecord {
   }
 
   Record *getAssociation() const { return Def->getValueAsDef("association"); }
+
+  Record *getCategory() const { return Def->getValueAsDef("category"); }
 };
 
 // Wrapper class that contains Clause's information defined in DirectiveBase.td
diff --git a/llvm/test/TableGen/directive1.td b/llvm/test/TableGen/directive1.td
index 56bce5bfb89c7..3af3b04dc0093 100644
--- a/llvm/test/TableGen/directive1.td
+++ b/llvm/test/TableGen/directive1.td
@@ -45,6 +45,7 @@ def TDL_DirA : Directive<"dira"> {
   ];
   let isDefault = 1;
   let association = AS_None;
+  let category = CA_Executable;
 }
 
 // CHECK:       #ifndef LLVM_Tdl_INC
@@ -71,6 +72,17 @@ def TDL_DirA : Directive<"dira"> {
 // CHECK-EMPTY:
 // CHECK-NEXT:  static constexpr std::size_t Association_enumSize = 6;
 // CHECK-EMPTY:
+// CHECK-NEXT:  enum class Category {
+// CHECK-NEXT:    Declarative,
+// CHECK-NEXT:    Executable,
+// CHECK-NEXT:    Informational,
+// CHECK-NEXT:    Meta,
+// CHECK-NEXT:    Subsidiary,
+// CHECK-NEXT:    Utility,
+// CHECK-NEXT:  };
+// CHECK-EMPTY:
+// CHECK-NEXT:  static constexpr std::size_t Category_enumSize = 6;
+// CHECK-EMPTY:
 // CHECK-NEXT:  enum class Directive {
 // CHECK-NEXT:    TDLD_dira,
 // CHECK-NEXT:  };
@@ -115,6 +127,7 @@ def TDL_DirA : Directive<"dira"> {
 // CHECK-EMPTY:
 // CHECK-NEXT:  constexpr std::size_t getMaxLeafCount() { return 0; }
 // CHECK-NEXT:  Association getDirectiveAssociation(Directive D);
+// CHECK-NEXT:  Category getDirectiveCategory(Directive D);
 // CHECK-NEXT:  AKind getAKind(StringRef);
 // CHECK-NEXT:  llvm::StringRef getTdlAKindName(AKind);
 // CHECK-EMPTY:
@@ -364,7 +377,15 @@ def TDL_DirA : Directive<"dira"> {
 // IMPL-NEXT:    switch (Dir) {
 // IMPL-NEXT:    case llvm::tdl::Directive::TDLD_dira:
 // IMPL-NEXT:      return llvm::tdl::Association::None;
-// IMPL-NEXT:    } // switch(Dir)
+// IMPL-NEXT:    } // switch (Dir)
+// IMPL-NEXT:    llvm_unreachable("Unexpected directive");
+// IMPL-NEXT:  }
+// IMPL-EMPTY:
+// IMPL-NEXT:  llvm::tdl::Category llvm::tdl::getDirectiveCategory(llvm::tdl::Directive Dir) {
+// IMPL-NEXT:    switch (Dir) {
+// IMPL-NEXT:    case llvm::tdl::TDLD_dira:
+// IMPL-NEXT:      return llvm::tdl::Category::Executable;
+// IMPL-NEXT:    } // switch (Dir)
 // IMPL-NEXT:    llvm_unreachable("Unexpected directive");
 // IMPL-NEXT:  }
 // IMPL-EMPTY:
diff --git a/llvm/test/TableGen/directive2.td b/llvm/test/TableGen/directive2.td
index 3c092113593b7..209901bb616f4 100644
--- a/llvm/test/TableGen/directive2.td
+++ b/llvm/test/TableGen/directive2.td
@@ -39,6 +39,7 @@ def TDL_DirA : Directive<"dira"> {
   ];
   let isDefault = 1;
   let association = AS_Block;
+  let category = CA_Declarative;
 }
 
 // CHECK:       #ifndef LLVM_Tdl_INC
@@ -62,6 +63,17 @@ def TDL_DirA : Directive<"dira"> {
 // CHECK-EMPTY:
 // CHECK-NEXT:  static constexpr std::size_t Association_enumSize = 6;
 // CHECK-EMPTY:
+// CHECK-NEXT:  enum class Category {
+// CHECK-NEXT:    Declarative,
+// CHECK-NEXT:    Executable,
+// CHECK-NEXT:    Informational,
+// CHECK-NEXT:    Meta,
+// CHECK-NEXT:    Subsidiary,
+// CHECK-NEXT:    Utility,
+// CHECK-NEXT:  };
+// CHECK-EMPTY:
+// CHECK-NEXT:  static constexpr std::size_t Category_enumSize = 6;
+// CHECK-EMPTY:
 // CHECK-NEXT:  enum class Directive {
 // CHECK-NEXT:    TDLD_dira,
 // CHECK-NEXT:  };
@@ -91,6 +103,7 @@ def TDL_DirA : Directive<"dira"> {
 // CHECK-EMPTY:
 // CHECK-NEXT:  constexpr std::size_t getMaxLeafCount() { return 0; }
 // CHECK-NEXT:  Association getDirectiveAssociation(Directive D);
+// CHECK-NEXT:  Category getDirectiveCategory(Directive D);
 // CHECK-NEXT:  } // namespace tdl
 // CHECK-NEXT:  } // namespace llvm
 // CHECK-NEXT:  #endif // LLVM_Tdl_INC
@@ -295,7 +308,15 @@ def TDL_DirA : Directive<"dira"> {
 // IMPL-NEXT:    switch (Dir) {
 // IMPL-NEXT:    case llvm::tdl::Directive::TDLD_dira:
 // IMPL-NEXT:      return llvm::tdl::Association::Block;
-// IMPL-NEXT:    } // switch(Dir)
+// IMPL-NEXT:    } // switch (Dir)
+// IMPL-NEXT:    llvm_unreachable("Unexpected directive");
+// IMPL-NEXT:  }
+// IMPL-EMPTY:
+// IMPL-NEXT:  llvm::tdl::Category llvm::tdl::getDirectiveCategory(llvm::tdl::Directive Dir) {
+// IMPL-NEXT:    switch (Dir) {
+// IMPL-NEXT:    case llvm::tdl::TDLD_dira:
+// IMPL-NEXT:      return llvm::tdl::Category::Declarative;
+// IMPL-NEXT:    } // switch (Dir)
 // IMPL-NEXT:    llvm_unreachable("Unexpected directive");
 // IMPL-NEXT:  }
 // IMPL-EMPTY:
diff --git a/llvm/utils/TableGen/DirectiveEmitter.cpp b/llvm/utils/TableGen/DirectiveEmitter.cpp
index 8bc3f026853cc..581bc09d5e053 100644
--- a/llvm/utils/TableGen/DirectiveEmitter.cpp
+++ b/llvm/utils/TableGen/DirectiveEmitter.cpp
@@ -228,6 +228,9 @@ static void EmitDirectivesDecl(RecordKeeper &Records, raw_ostream &OS) {
   GenerateEnumClass(associations, OS, "Association",
                     /*Prefix=*/"", DirLang, /*ExportEnums=*/false);
 
+  GenerateEnumClass(DirLang.getCategories(), OS, "Category", /*Prefix=*/"",
+                    DirLang, /*ExportEnums=*/false);
+
   // Emit Directive enumeration
   GenerateEnumClass(DirLang.getDirectives(), OS, "Directive",
                     DirLang.getDirectivePrefix(), DirLang,
@@ -264,6 +267,7 @@ static void EmitDirectivesDecl(RecordKeeper &Records, raw_ostream &OS) {
   OS << "constexpr std::size_t getMaxLeafCount() { return "
      << GetMaxLeafCount(DirLang) << "; }\n";
   OS << "Association getDirectiveAssociation(Directive D);\n";
+  OS << "Category getDirectiveCategory(Directive D);\n";
   if (EnumHelperFuncs.length() > 0) {
     OS << EnumHelperFuncs;
     OS << "\n";
@@ -743,7 +747,29 @@ static void GenerateGetDirectiveAssociation(const DirectiveLanguage &DirLang,
          << "::" << getAssocName(F->second) << ";\n";
     }
   }
-  OS << "  } // switch(Dir)\n";
+  OS << "  } // switch (Dir)\n";
+  OS << "  llvm_unreachable(\"Unexpected directive\");\n";
+  OS << "}\n";
+}
+
+static void GenerateGetDirectiveCategory(const DirectiveLanguage &DirLang,
+                                         raw_ostream &OS) {
+  std::string LangNamespace = "llvm::" + DirLang.getCppNamespace().str();
+  std::string CategoryTypeName = LangNamespace + "::Category";
+  std::string CategoryNamespace = CategoryTypeName + "::";
+
+  OS << '\n';
+  OS << CategoryTypeName << ' ' << LangNamespace << "::getDirectiveCategory("
+     << GetDirectiveType(DirLang) << " Dir) {\n";
+  OS << "  switch (Dir) {\n";
+
+  for (Record *R : DirLang.getDirectives()) {
+    Directive D{R};
+    OS << "  case " << GetDirectiveName(DirLang, R) << ":\n";
+    OS << "    return " << CategoryNamespace
+       << D.getCategory()->getValueAsString("name") << ";\n";
+  }
+  OS << "  } // switch (Dir)\n";
   OS << "  llvm_unreachable(\"Unexpected directive\");\n";
   OS << "}\n";
 }
@@ -1196,6 +1222,9 @@ void EmitDirectivesBasicImpl(const DirectiveLanguage &DirLang,
   // getDirectiveAssociation(Directive D)
   GenerateGetDirectiveAssociation(DirLang, OS);
 
+  // getDirectiveCategory(Directive D)
+  GenerateGetDirectiveCategory(DirLang, OS);
+
   // Leaf table for getLeafConstructs, etc.
   EmitLeafTable(DirLang, OS, "LeafConstructTable");
 }

>From 950ad6a14687f5eab41bf8cc8ed64d07d8ad0a3d Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Thu, 6 Jun 2024 15:52:31 -0500
Subject: [PATCH 03/10] [clang][OpenMP] Shorten directive classification in
 ParseOpenMP

Use directive categories to simplify long lists of `case` statements
in the OpenMP parser. This is a step towards avoiding dependence on
explicitly specified sets of directives that can be expressed more
generically.
The upcoming OpenMP 6.0 will introduce many new combined directives,
and the more generically we handle directives, the easier the
introduction of the new standard will be.
---
 clang/include/clang/Parse/Parser.h |  13 +
 clang/lib/Parse/ParseOpenMP.cpp    | 526 ++++++++++++-----------------
 2 files changed, 230 insertions(+), 309 deletions(-)

diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index d054b8cf0d240..88571a4a46f2c 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -3509,6 +3509,19 @@ class Parser : public CodeCompletionHandler {
   /// metadirective and therefore ends on the closing paren.
   StmtResult ParseOpenMPDeclarativeOrExecutableDirective(
       ParsedStmtContext StmtCtx, bool ReadDirectiveWithinMetadirective = false);
+
+  /// Parses executable directive.
+  ///
+  /// \param StmtCtx The context in which we're parsing the directive.
+  /// \param DKind The kind of the executable directive.
+  /// \param Loc Source location of the beginning of the directive.
+  /// \param ReadDirectiveWithinMetadirective true if directive is within a
+  /// metadirective and therefore ends on the closing paren.
+  StmtResult
+  ParseOpenMPExecutableDirective(ParsedStmtContext StmtCtx,
+                                 OpenMPDirectiveKind DKind, SourceLocation Loc,
+                                 bool ReadDirectiveWithinMetadirective);
+
   /// Parses clause of kind \a CKind for directive of a kind \a Kind.
   ///
   /// \param DKind Kind of current directive.
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 50a872fedebf7..a10bb009ec835 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -2374,86 +2374,209 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
   case OMPD_unknown:
     Diag(Tok, diag::err_omp_unknown_directive);
     break;
-  case OMPD_parallel:
-  case OMPD_simd:
-  case OMPD_tile:
-  case OMPD_unroll:
-  case OMPD_task:
-  case OMPD_taskyield:
+  default:
+    switch (getDirectiveCategory(DKind)) {
+    case Category::Executable:
+    case Category::Meta:
+    case Category::Subsidiary:
+    case Category::Utility:
+      Diag(Tok, diag::err_omp_unexpected_directive)
+          << 1 << getOpenMPDirectiveName(DKind);
+      break;
+    default:
+      break;
+    }
+  }
+  while (Tok.isNot(tok::annot_pragma_openmp_end))
+    ConsumeAnyToken();
+  ConsumeAnyToken();
+  return nullptr;
+}
+
+StmtResult
+Parser::ParseOpenMPExecutableDirective(ParsedStmtContext StmtCtx,
+                                       OpenMPDirectiveKind DKind,
+                                       SourceLocation Loc,
+                                       bool ReadDirectiveWithinMetadirective) {
+  bool HasAssociatedStatement = true;
+
+  switch (DKind) {
   case OMPD_barrier:
-  case OMPD_taskwait:
-  case OMPD_taskgroup:
-  case OMPD_flush:
+  case OMPD_cancel:
+  case OMPD_cancellation_point:
   case OMPD_depobj:
+  case OMPD_error:
+  case OMPD_flush:
+  case OMPD_interop:
   case OMPD_scan:
-  case OMPD_for:
-  case OMPD_for_simd:
-  case OMPD_sections:
-  case OMPD_section:
-  case OMPD_single:
-  case OMPD_master:
-  case OMPD_ordered:
-  case OMPD_critical:
-  case OMPD_parallel_for:
-  case OMPD_parallel_for_simd:
-  case OMPD_parallel_sections:
-  case OMPD_parallel_master:
-  case OMPD_parallel_masked:
-  case OMPD_atomic:
-  case OMPD_target:
-  case OMPD_teams:
-  case OMPD_cancellation_point:
-  case OMPD_cancel:
-  case OMPD_target_data:
   case OMPD_target_enter_data:
   case OMPD_target_exit_data:
-  case OMPD_target_parallel:
-  case OMPD_target_parallel_for:
-  case OMPD_taskloop:
-  case OMPD_taskloop_simd:
-  case OMPD_master_taskloop:
-  case OMPD_master_taskloop_simd:
-  case OMPD_parallel_master_taskloop:
-  case OMPD_parallel_master_taskloop_simd:
-  case OMPD_masked_taskloop:
-  case OMPD_masked_taskloop_simd:
-  case OMPD_parallel_masked_taskloop:
-  case OMPD_parallel_masked_taskloop_simd:
-  case OMPD_distribute:
   case OMPD_target_update:
-  case OMPD_distribute_parallel_for:
-  case OMPD_distribute_parallel_for_simd:
-  case OMPD_distribute_simd:
-  case OMPD_target_parallel_for_simd:
-  case OMPD_target_simd:
-  case OMPD_scope:
-  case OMPD_teams_distribute:
-  case OMPD_teams_distribute_simd:
-  case OMPD_teams_distribute_parallel_for_simd:
-  case OMPD_teams_distribute_parallel_for:
-  case OMPD_target_teams:
-  case OMPD_target_teams_distribute:
-  case OMPD_target_teams_distribute_parallel_for:
-  case OMPD_target_teams_distribute_parallel_for_simd:
-  case OMPD_target_teams_distribute_simd:
-  case OMPD_dispatch:
-  case OMPD_masked:
-  case OMPD_metadirective:
-  case OMPD_loop:
-  case OMPD_teams_loop:
-  case OMPD_target_teams_loop:
-  case OMPD_parallel_loop:
-  case OMPD_target_parallel_loop:
-    Diag(Tok, diag::err_omp_unexpected_directive)
-        << 1 << getOpenMPDirectiveName(DKind);
-    break;
-  default:
+  case OMPD_taskwait:
+  case OMPD_taskyield:
+    if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
+        ParsedStmtContext()) {
+      Diag(Tok, diag::err_omp_immediate_directive)
+          << getOpenMPDirectiveName(DKind) << 0;
+      if (DKind == OMPD_error) {
+        SkipUntil(tok::annot_pragma_openmp_end);
+        return StmtError();
+      }
+    }
+    HasAssociatedStatement = false;
     break;
   }
-  while (Tok.isNot(tok::annot_pragma_openmp_end))
-    ConsumeAnyToken();
-  ConsumeAnyToken();
-  return nullptr;
+
+  SourceLocation EndLoc;
+  SmallVector<OMPClause *, 5> Clauses;
+  std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
+  DeclarationNameInfo DirName;
+  OpenMPDirectiveKind CancelRegion = OMPD_unknown;
+  unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
+                        Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
+
+  // Special processing for flush and depobj clauses.
+  Token ImplicitTok;
+  bool ImplicitClauseAllowed = false;
+  if (DKind == OMPD_flush || DKind == OMPD_depobj) {
+    ImplicitTok = Tok;
+    ImplicitClauseAllowed = true;
+  }
+  ConsumeToken();
+  // Parse directive name of the 'critical' directive if any.
+  if (DKind == OMPD_critical) {
+    BalancedDelimiterTracker T(*this, tok::l_paren,
+                               tok::annot_pragma_openmp_end);
+    if (!T.consumeOpen()) {
+      if (Tok.isAnyIdentifier()) {
+        DirName =
+            DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
+        ConsumeAnyToken();
+      } else {
+        Diag(Tok, diag::err_omp_expected_identifier_for_critical);
+      }
+      T.consumeClose();
+    }
+  } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
+    CancelRegion = parseOpenMPDirectiveKind(*this);
+    if (Tok.isNot(tok::annot_pragma_openmp_end))
+      ConsumeToken();
+  }
+
+  if (isOpenMPLoopDirective(DKind))
+    ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
+  if (isOpenMPSimdDirective(DKind))
+    ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
+  ParseScope OMPDirectiveScope(this, ScopeFlags);
+  Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(),
+                                       Loc);
+
+  while (Tok.isNot(tok::annot_pragma_openmp_end)) {
+    // If we are parsing for a directive within a metadirective, the directive
+    // ends with a ')'.
+    if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
+      while (Tok.isNot(tok::annot_pragma_openmp_end))
+        ConsumeAnyToken();
+      break;
+    }
+    bool HasImplicitClause = false;
+    if (ImplicitClauseAllowed && Tok.is(tok::l_paren)) {
+      HasImplicitClause = true;
+      // Push copy of the current token back to stream to properly parse
+      // pseudo-clause OMPFlushClause or OMPDepobjClause.
+      PP.EnterToken(Tok, /*IsReinject*/ true);
+      PP.EnterToken(ImplicitTok, /*IsReinject*/ true);
+      ConsumeAnyToken();
+    }
+    OpenMPClauseKind CKind = Tok.isAnnotation()
+                                 ? OMPC_unknown
+                                 : getOpenMPClauseKind(PP.getSpelling(Tok));
+    if (HasImplicitClause) {
+      assert(CKind == OMPC_unknown && "Must be unknown implicit clause.");
+      if (DKind == OMPD_flush) {
+        CKind = OMPC_flush;
+      } else {
+        assert(DKind == OMPD_depobj && "Expected flush or depobj directives.");
+        CKind = OMPC_depobj;
+      }
+    }
+    // No more implicit clauses allowed.
+    ImplicitClauseAllowed = false;
+    Actions.OpenMP().StartOpenMPClause(CKind);
+    HasImplicitClause = false;
+    OMPClause *Clause =
+        ParseOpenMPClause(DKind, CKind, !SeenClauses[unsigned(CKind)]);
+    SeenClauses[unsigned(CKind)] = true;
+    if (Clause)
+      Clauses.push_back(Clause);
+
+    // Skip ',' if any.
+    if (Tok.is(tok::comma))
+      ConsumeToken();
+    Actions.OpenMP().EndOpenMPClause();
+  }
+  // End location of the directive.
+  EndLoc = Tok.getLocation();
+  // Consume final annot_pragma_openmp_end.
+  ConsumeAnnotationToken();
+
+  if (DKind == OMPD_ordered) {
+    // If the depend or doacross clause is specified, the ordered construct
+    // is a stand-alone directive.
+    for (auto CK : {OMPC_depend, OMPC_doacross}) {
+      if (SeenClauses[unsigned(CK)]) {
+        if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
+            ParsedStmtContext()) {
+          Diag(Loc, diag::err_omp_immediate_directive)
+              << getOpenMPDirectiveName(DKind) << 1 << getOpenMPClauseName(CK);
+        }
+        HasAssociatedStatement = false;
+      }
+    }
+  }
+
+  if (DKind == OMPD_tile && !SeenClauses[unsigned(OMPC_sizes)]) {
+    Diag(Loc, diag::err_omp_required_clause)
+        << getOpenMPDirectiveName(OMPD_tile) << "sizes";
+  }
+
+  StmtResult AssociatedStmt;
+  if (HasAssociatedStatement) {
+    // The body is a block scope like in Lambdas and Blocks.
+    Actions.OpenMP().ActOnOpenMPRegionStart(DKind, getCurScope());
+    // FIXME: We create a bogus CompoundStmt scope to hold the contents of
+    // the captured region. Code elsewhere assumes that any FunctionScopeInfo
+    // should have at least one compound statement scope within it.
+    ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false);
+    {
+      Sema::CompoundScopeRAII Scope(Actions);
+      AssociatedStmt = ParseStatement();
+
+      if (AssociatedStmt.isUsable() && isOpenMPLoopDirective(DKind) &&
+          getLangOpts().OpenMPIRBuilder)
+        AssociatedStmt =
+            Actions.OpenMP().ActOnOpenMPLoopnest(AssociatedStmt.get());
+    }
+    AssociatedStmt =
+        Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
+  } else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
+             DKind == OMPD_target_exit_data) {
+    Actions.OpenMP().ActOnOpenMPRegionStart(DKind, getCurScope());
+    AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
+                      Actions.ActOnCompoundStmt(Loc, Loc, std::nullopt,
+                                                /*isStmtExpr=*/false));
+    AssociatedStmt =
+        Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
+  }
+
+  StmtResult Directive = Actions.OpenMP().ActOnOpenMPExecutableDirective(
+      DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc, EndLoc);
+
+  // Exit scope.
+  Actions.OpenMP().EndOpenMPDSABlock(Directive.get());
+  OMPDirectiveScope.Exit();
+
+  return Directive;
 }
 
 /// Parsing of declarative or executable OpenMP directives.
@@ -2503,24 +2626,36 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
            "Not an OpenMP directive!");
   ParsingOpenMPDirectiveRAII DirScope(*this);
   ParenBraceBracketBalancer BalancerRAIIObj(*this);
-  SmallVector<OMPClause *, 5> Clauses;
-  std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
-  unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
-                        Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
   SourceLocation Loc = ReadDirectiveWithinMetadirective
                            ? Tok.getLocation()
-                           : ConsumeAnnotationToken(),
-                 EndLoc;
+                           : ConsumeAnnotationToken();
   OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
   if (ReadDirectiveWithinMetadirective && DKind == OMPD_unknown) {
     Diag(Tok, diag::err_omp_unknown_directive);
     return StmtError();
   }
-  OpenMPDirectiveKind CancelRegion = OMPD_unknown;
-  // Name of critical directive.
-  DeclarationNameInfo DirName;
+
   StmtResult Directive = StmtError();
-  bool HasAssociatedStatement = true;
+
+  bool IsExecutable = [&]() {
+    if (DKind == OMPD_error)  // OMPD_error is handled as executable
+      return true;
+    switch (getDirectiveCategory(DKind)) {
+    case Category::Executable:
+    case Category::Subsidiary:
+      return true;
+    default:
+      break;
+    }
+    return false;
+  }();
+
+  if (IsExecutable) {
+    Directive = ParseOpenMPExecutableDirective(
+        StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective);
+    assert(!Directive.isUnset());
+    return Directive;
+  }
 
   switch (DKind) {
   case OMPD_nothing:
@@ -2763,233 +2898,6 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
     }
     break;
   }
-  case OMPD_flush:
-  case OMPD_depobj:
-  case OMPD_scan:
-  case OMPD_taskyield:
-  case OMPD_error:
-  case OMPD_barrier:
-  case OMPD_taskwait:
-  case OMPD_cancellation_point:
-  case OMPD_cancel:
-  case OMPD_target_enter_data:
-  case OMPD_target_exit_data:
-  case OMPD_target_update:
-  case OMPD_interop:
-    if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
-        ParsedStmtContext()) {
-      Diag(Tok, diag::err_omp_immediate_directive)
-          << getOpenMPDirectiveName(DKind) << 0;
-      if (DKind == OMPD_error) {
-        SkipUntil(tok::annot_pragma_openmp_end);
-        break;
-      }
-    }
-    HasAssociatedStatement = false;
-    // Fall through for further analysis.
-    [[fallthrough]];
-  case OMPD_parallel:
-  case OMPD_simd:
-  case OMPD_tile:
-  case OMPD_unroll:
-  case OMPD_for:
-  case OMPD_for_simd:
-  case OMPD_sections:
-  case OMPD_single:
-  case OMPD_section:
-  case OMPD_master:
-  case OMPD_critical:
-  case OMPD_parallel_for:
-  case OMPD_parallel_for_simd:
-  case OMPD_parallel_sections:
-  case OMPD_parallel_master:
-  case OMPD_parallel_masked:
-  case OMPD_task:
-  case OMPD_ordered:
-  case OMPD_atomic:
-  case OMPD_target:
-  case OMPD_teams:
-  case OMPD_taskgroup:
-  case OMPD_target_data:
-  case OMPD_target_parallel:
-  case OMPD_target_parallel_for:
-  case OMPD_loop:
-  case OMPD_teams_loop:
-  case OMPD_target_teams_loop:
-  case OMPD_parallel_loop:
-  case OMPD_target_parallel_loop:
-  case OMPD_scope:
-  case OMPD_taskloop:
-  case OMPD_taskloop_simd:
-  case OMPD_master_taskloop:
-  case OMPD_masked_taskloop:
-  case OMPD_master_taskloop_simd:
-  case OMPD_masked_taskloop_simd:
-  case OMPD_parallel_master_taskloop:
-  case OMPD_parallel_masked_taskloop:
-  case OMPD_parallel_master_taskloop_simd:
-  case OMPD_parallel_masked_taskloop_simd:
-  case OMPD_distribute:
-  case OMPD_distribute_parallel_for:
-  case OMPD_distribute_parallel_for_simd:
-  case OMPD_distribute_simd:
-  case OMPD_target_parallel_for_simd:
-  case OMPD_target_simd:
-  case OMPD_teams_distribute:
-  case OMPD_teams_distribute_simd:
-  case OMPD_teams_distribute_parallel_for_simd:
-  case OMPD_teams_distribute_parallel_for:
-  case OMPD_target_teams:
-  case OMPD_target_teams_distribute:
-  case OMPD_target_teams_distribute_parallel_for:
-  case OMPD_target_teams_distribute_parallel_for_simd:
-  case OMPD_target_teams_distribute_simd:
-  case OMPD_dispatch:
-  case OMPD_masked: {
-    // Special processing for flush and depobj clauses.
-    Token ImplicitTok;
-    bool ImplicitClauseAllowed = false;
-    if (DKind == OMPD_flush || DKind == OMPD_depobj) {
-      ImplicitTok = Tok;
-      ImplicitClauseAllowed = true;
-    }
-    ConsumeToken();
-    // Parse directive name of the 'critical' directive if any.
-    if (DKind == OMPD_critical) {
-      BalancedDelimiterTracker T(*this, tok::l_paren,
-                                 tok::annot_pragma_openmp_end);
-      if (!T.consumeOpen()) {
-        if (Tok.isAnyIdentifier()) {
-          DirName =
-              DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
-          ConsumeAnyToken();
-        } else {
-          Diag(Tok, diag::err_omp_expected_identifier_for_critical);
-        }
-        T.consumeClose();
-      }
-    } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
-      CancelRegion = parseOpenMPDirectiveKind(*this);
-      if (Tok.isNot(tok::annot_pragma_openmp_end))
-        ConsumeToken();
-    }
-
-    if (isOpenMPLoopDirective(DKind))
-      ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
-    if (isOpenMPSimdDirective(DKind))
-      ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
-    ParseScope OMPDirectiveScope(this, ScopeFlags);
-    Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(),
-                                         Loc);
-
-    while (Tok.isNot(tok::annot_pragma_openmp_end)) {
-      // If we are parsing for a directive within a metadirective, the directive
-      // ends with a ')'.
-      if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
-        while (Tok.isNot(tok::annot_pragma_openmp_end))
-          ConsumeAnyToken();
-        break;
-      }
-      bool HasImplicitClause = false;
-      if (ImplicitClauseAllowed && Tok.is(tok::l_paren)) {
-        HasImplicitClause = true;
-        // Push copy of the current token back to stream to properly parse
-        // pseudo-clause OMPFlushClause or OMPDepobjClause.
-        PP.EnterToken(Tok, /*IsReinject*/ true);
-        PP.EnterToken(ImplicitTok, /*IsReinject*/ true);
-        ConsumeAnyToken();
-      }
-      OpenMPClauseKind CKind = Tok.isAnnotation()
-                                   ? OMPC_unknown
-                                   : getOpenMPClauseKind(PP.getSpelling(Tok));
-      if (HasImplicitClause) {
-        assert(CKind == OMPC_unknown && "Must be unknown implicit clause.");
-        if (DKind == OMPD_flush) {
-          CKind = OMPC_flush;
-        } else {
-          assert(DKind == OMPD_depobj &&
-                 "Expected flush or depobj directives.");
-          CKind = OMPC_depobj;
-        }
-      }
-      // No more implicit clauses allowed.
-      ImplicitClauseAllowed = false;
-      Actions.OpenMP().StartOpenMPClause(CKind);
-      HasImplicitClause = false;
-      OMPClause *Clause =
-          ParseOpenMPClause(DKind, CKind, !SeenClauses[unsigned(CKind)]);
-      SeenClauses[unsigned(CKind)] = true;
-      if (Clause)
-        Clauses.push_back(Clause);
-
-      // Skip ',' if any.
-      if (Tok.is(tok::comma))
-        ConsumeToken();
-      Actions.OpenMP().EndOpenMPClause();
-    }
-    // End location of the directive.
-    EndLoc = Tok.getLocation();
-    // Consume final annot_pragma_openmp_end.
-    ConsumeAnnotationToken();
-
-    if (DKind == OMPD_ordered) {
-      // If the depend or doacross clause is specified, the ordered construct
-      // is a stand-alone directive.
-      for (auto CK : {OMPC_depend, OMPC_doacross}) {
-        if (SeenClauses[unsigned(CK)]) {
-          if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
-              ParsedStmtContext()) {
-            Diag(Loc, diag::err_omp_immediate_directive)
-                << getOpenMPDirectiveName(DKind) << 1
-                << getOpenMPClauseName(CK);
-          }
-          HasAssociatedStatement = false;
-        }
-      }
-    }
-
-    if (DKind == OMPD_tile && !SeenClauses[unsigned(OMPC_sizes)]) {
-      Diag(Loc, diag::err_omp_required_clause)
-          << getOpenMPDirectiveName(OMPD_tile) << "sizes";
-    }
-
-    StmtResult AssociatedStmt;
-    if (HasAssociatedStatement) {
-      // The body is a block scope like in Lambdas and Blocks.
-      Actions.OpenMP().ActOnOpenMPRegionStart(DKind, getCurScope());
-      // FIXME: We create a bogus CompoundStmt scope to hold the contents of
-      // the captured region. Code elsewhere assumes that any FunctionScopeInfo
-      // should have at least one compound statement scope within it.
-      ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false);
-      {
-        Sema::CompoundScopeRAII Scope(Actions);
-        AssociatedStmt = ParseStatement();
-
-        if (AssociatedStmt.isUsable() && isOpenMPLoopDirective(DKind) &&
-            getLangOpts().OpenMPIRBuilder)
-          AssociatedStmt =
-              Actions.OpenMP().ActOnOpenMPLoopnest(AssociatedStmt.get());
-      }
-      AssociatedStmt =
-          Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
-    } else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
-               DKind == OMPD_target_exit_data) {
-      Actions.OpenMP().ActOnOpenMPRegionStart(DKind, getCurScope());
-      AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
-                        Actions.ActOnCompoundStmt(Loc, Loc, std::nullopt,
-                                                  /*isStmtExpr=*/false));
-      AssociatedStmt =
-          Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
-    }
-    Directive = Actions.OpenMP().ActOnOpenMPExecutableDirective(
-        DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
-        EndLoc);
-
-    // Exit scope.
-    Actions.OpenMP().EndOpenMPDSABlock(Directive.get());
-    OMPDirectiveScope.Exit();
-    break;
-  }
   case OMPD_declare_target: {
     SourceLocation DTLoc = ConsumeAnyToken();
     bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);

>From 3f41eb7f6aa8c8c6e538e42bc8151477432c0a52 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Mon, 10 Jun 2024 09:00:14 -0500
Subject: [PATCH 04/10] clang-format

---
 clang/lib/Parse/ParseOpenMP.cpp | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index a10bb009ec835..a8c9cc4551271 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -2393,11 +2393,9 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
   return nullptr;
 }
 
-StmtResult
-Parser::ParseOpenMPExecutableDirective(ParsedStmtContext StmtCtx,
-                                       OpenMPDirectiveKind DKind,
-                                       SourceLocation Loc,
-                                       bool ReadDirectiveWithinMetadirective) {
+StmtResult Parser::ParseOpenMPExecutableDirective(
+    ParsedStmtContext StmtCtx, OpenMPDirectiveKind DKind, SourceLocation Loc,
+    bool ReadDirectiveWithinMetadirective) {
   bool HasAssociatedStatement = true;
 
   switch (DKind) {
@@ -2638,7 +2636,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
   StmtResult Directive = StmtError();
 
   bool IsExecutable = [&]() {
-    if (DKind == OMPD_error)  // OMPD_error is handled as executable
+    if (DKind == OMPD_error) // OMPD_error is handled as executable
       return true;
     switch (getDirectiveCategory(DKind)) {
     case Category::Executable:

>From b1d6cfc1dc955a9c1f68daa13b60051e338e5d9c Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Mon, 10 Jun 2024 15:11:45 -0500
Subject: [PATCH 05/10] Add 'default' to switch statement

---
 clang/lib/Parse/ParseOpenMP.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index a8c9cc4551271..d76e432b49b31 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -2423,6 +2423,8 @@ StmtResult Parser::ParseOpenMPExecutableDirective(
     }
     HasAssociatedStatement = false;
     break;
+  default:
+    break;
   }
 
   SourceLocation EndLoc;

>From d56a62205279f802e6dd62fe0e7ce000b4be8f20 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Tue, 25 Jun 2024 10:04:26 -0500
Subject: [PATCH 06/10] Add remaining "case Category::..." to switch instead
 "default"

---
 clang/lib/Parse/ParseOpenMP.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index b7b43d9854709..e2b1edc489d70 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -2383,7 +2383,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
       Diag(Tok, diag::err_omp_unexpected_directive)
           << 1 << getOpenMPDirectiveName(DKind);
       break;
-    default:
+    case Category::Declarative:
+    case Category::Informational:
       break;
     }
   }

>From 77e882b1fde8620e76133b0a10068f52438fb3aa Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Tue, 25 Jun 2024 10:05:30 -0500
Subject: [PATCH 07/10] Replace switch in ParseOpenMPExecutableDirective with
 association check

---
 clang/lib/Parse/ParseOpenMP.cpp | 30 ++++++++++++------------------
 1 file changed, 12 insertions(+), 18 deletions(-)

diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index e2b1edc489d70..9e8bb1a82cc6c 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -2397,22 +2397,19 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
 StmtResult Parser::ParseOpenMPExecutableDirective(
     ParsedStmtContext StmtCtx, OpenMPDirectiveKind DKind, SourceLocation Loc,
     bool ReadDirectiveWithinMetadirective) {
+  assert((DKind == OMPD_error ||
+          getDirectiveCategory(DKind) == Category::Executable ||
+          getDirectiveCategory(DKind) == Category::Subsidiary) &&
+         "Directive with an unexpected category");
   bool HasAssociatedStatement = true;
-
-  switch (DKind) {
-  case OMPD_barrier:
-  case OMPD_cancel:
-  case OMPD_cancellation_point:
-  case OMPD_depobj:
-  case OMPD_error:
-  case OMPD_flush:
-  case OMPD_interop:
-  case OMPD_scan:
-  case OMPD_target_enter_data:
-  case OMPD_target_exit_data:
-  case OMPD_target_update:
-  case OMPD_taskwait:
-  case OMPD_taskyield:
+  Association Assoc = getDirectiveAssociation(DKind);
+
+  // OMPD_ordered has None as association, but it comes in two variants,
+  // the second of which is associated with a block.
+  // OMPD_scan and OMPD_section are both "separating", but section is treated
+  // as if it was associated with a statement, while scan is not.
+  if (DKind != OMPD_ordered && DKind != OMPD_section &&
+      (Assoc == Association::None || Assoc == Association::Separating)) {
     if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
         ParsedStmtContext()) {
       Diag(Tok, diag::err_omp_immediate_directive)
@@ -2423,9 +2420,6 @@ StmtResult Parser::ParseOpenMPExecutableDirective(
       }
     }
     HasAssociatedStatement = false;
-    break;
-  default:
-    break;
   }
 
   SourceLocation EndLoc;

>From 08e073240fc79fd27cedb8b4dbaa65460ed60674 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Tue, 25 Jun 2024 10:49:18 -0500
Subject: [PATCH 08/10] Update clang/lib/Parse/ParseOpenMP.cpp

Co-authored-by: Alexey Bataev <a.bataev at outlook.com>
---
 clang/lib/Parse/ParseOpenMP.cpp | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 9e8bb1a82cc6c..03f79fc7cf241 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -2635,14 +2635,8 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
   bool IsExecutable = [&]() {
     if (DKind == OMPD_error) // OMPD_error is handled as executable
       return true;
-    switch (getDirectiveCategory(DKind)) {
-    case Category::Executable:
-    case Category::Subsidiary:
-      return true;
-    default:
-      break;
-    }
-    return false;
+    auto Res = getDirectiveCategory(DKind);
+    return Res == Category::Executable || Res == Category::Subsidiary;
   }();
 
   if (IsExecutable) {

>From d24e5615c648285a1906f0a3fa38bcb936b00795 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Tue, 25 Jun 2024 11:03:08 -0500
Subject: [PATCH 09/10] Replace std::bitset with llvm::SmallBitVector

---
 clang/lib/Parse/ParseOpenMP.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 03f79fc7cf241..4dfdae18e9f20 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -24,10 +24,10 @@
 #include "clang/Sema/SemaAMDGPU.h"
 #include "clang/Sema/SemaCodeCompletion.h"
 #include "clang/Sema/SemaOpenMP.h"
+#include "llvm/ADT/SmallBitVector.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Frontend/OpenMP/OMPAssume.h"
 #include "llvm/Frontend/OpenMP/OMPContext.h"
-#include <bitset>
 #include <optional>
 
 using namespace clang;
@@ -2146,7 +2146,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
   case OMPD_requires: {
     SourceLocation StartLoc = ConsumeToken();
     SmallVector<OMPClause *, 5> Clauses;
-    std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
+    llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
     if (Tok.is(tok::annot_pragma_openmp_end)) {
       Diag(Tok, diag::err_omp_expected_clause)
           << getOpenMPDirectiveName(OMPD_requires);
@@ -2424,7 +2424,7 @@ StmtResult Parser::ParseOpenMPExecutableDirective(
 
   SourceLocation EndLoc;
   SmallVector<OMPClause *, 5> Clauses;
-  std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
+  llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
   DeclarationNameInfo DirName;
   OpenMPDirectiveKind CancelRegion = OMPD_unknown;
   unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
@@ -2833,7 +2833,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
                                   /*AllowScopeSpecifier=*/false)) {
       SmallVector<OMPClause *, 1> Clauses;
       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
-        std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
+        llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
         while (Tok.isNot(tok::annot_pragma_openmp_end)) {
           OpenMPClauseKind CKind =
               Tok.isAnnotation() ? OMPC_unknown

>From 6f07e62e025d8c9c229a3d9f5882f544d5ce9bdf Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Tue, 25 Jun 2024 11:08:53 -0500
Subject: [PATCH 10/10] Add assertion message

---
 clang/lib/Parse/ParseOpenMP.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 4dfdae18e9f20..00f9ebb65d876 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -2642,7 +2642,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
   if (IsExecutable) {
     Directive = ParseOpenMPExecutableDirective(
         StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective);
-    assert(!Directive.isUnset());
+    assert(!Directive.isUnset() && "Executable directive remained unprocessed");
     return Directive;
   }
 



More information about the llvm-commits mailing list