[llvm-branch-commits] [flang] [flang][OpenMP] Make all block constructs share the same structure (PR #150956)

Krzysztof Parzyszek via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Jul 28 07:15:00 PDT 2025


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

The structure is
- OmpBeginDirective (aka OmpDirectiveSpecification)
- Block
- optional<OmpEndDirective> (aka optional<OmpDirectiveSpecification>)

The OmpBeginDirective and OmpEndDirective are effectively different names for OmpDirectiveSpecification. They exist to allow the semantic analyses to distinguish between the beginning and the ending of a block construct without maintaining additional context.

The actual changes are in the parser: parse-tree.h and openmp-parser.cpp in particular. The rest is simply changing the way the directive/clause information is accessed (typically for the simpler).

All standalone and block constructs now use OmpDirectiveSpecification to store the directive/clause information.

>From cd3a5b91a2715367a4fcd1b3a92c8fef72c6938f Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Thu, 17 Jul 2025 08:28:34 -0500
Subject: [PATCH] [flang][OpenMP] Make all block constructs share the same
 structure

The structure is
- OmpBeginDirective (aka OmpDirectiveSpecification)
- Block
- optional<OmpEndDirective> (aka optional<OmpDirectiveSpecification>)

The OmpBeginDirective and OmpEndDirective are effectively different
names for OmpDirectiveSpecification. They exist to allow the semantic
analyses to distinguish between the beginning and the ending of a block
construct without maintaining additional context.

The actual changes are in the parser: parse-tree.h and openmp-parser.cpp
in particular. The rest is simply changing the way the directive/clause
information is accessed (typically for the simpler).

All standalone and block constructs now use OmpDirectiveSpecification
to store the directive/clause information.
---
 flang/examples/FeatureList/FeatureList.cpp    |   5 +-
 flang/include/flang/Parser/dump-parse-tree.h  |   5 +-
 flang/include/flang/Parser/openmp-utils.h     |  11 +-
 flang/include/flang/Parser/parse-tree.h       |  83 ++++----
 flang/lib/Lower/OpenMP/Atomic.cpp             |   2 +-
 flang/lib/Lower/OpenMP/OpenMP.cpp             |  49 ++---
 flang/lib/Parser/openmp-parsers.cpp           | 192 +++++++++---------
 flang/lib/Parser/parse-tree.cpp               |   6 +-
 flang/lib/Parser/unparse.cpp                  | 100 ++-------
 flang/lib/Semantics/check-omp-atomic.cpp      |   8 +-
 flang/lib/Semantics/check-omp-loop.cpp        |  14 +-
 flang/lib/Semantics/check-omp-structure.cpp   | 115 +++++------
 flang/lib/Semantics/check-omp-structure.h     |   6 +-
 flang/lib/Semantics/resolve-directives.cpp    |  34 ++--
 flang/lib/Semantics/resolve-names.cpp         |  12 +-
 flang/test/Parser/OpenMP/affinity-clause.f90  |  12 +-
 .../test/Parser/OpenMP/allocators-unparse.f90 |   8 +-
 flang/test/Parser/OpenMP/atomic-compare.f90   |  18 +-
 flang/test/Parser/OpenMP/atomic-end.f90       |   8 +-
 flang/test/Parser/OpenMP/block-construct.f90  |  20 +-
 .../OpenMP/construct-prefix-conflict.f90      |  40 ++--
 .../test/Parser/OpenMP/defaultmap-clause.f90  |  24 +--
 .../test/Parser/OpenMP/defaultmap-unparse.f90 |  36 ++--
 flang/test/Parser/OpenMP/dispatch.f90         |   8 +-
 flang/test/Parser/OpenMP/if-clause.f90        |   4 +-
 .../Parser/OpenMP/in-reduction-clause.f90     |  12 +-
 .../test/Parser/OpenMP/map-modifiers-v60.f90  |  20 +-
 flang/test/Parser/OpenMP/map-modifiers.f90    |  46 ++---
 flang/test/Parser/OpenMP/masked-unparse.f90   |  12 +-
 flang/test/Parser/OpenMP/master-unparse.f90   |   8 +-
 .../OpenMP/openmp6-directive-spellings.f90    |  12 +-
 flang/test/Parser/OpenMP/proc-bind.f90        |   4 +-
 flang/test/Parser/OpenMP/scope.f90            |   8 +-
 .../Parser/OpenMP/target_device_parse.f90     |  64 +++---
 .../Parser/OpenMP/task-reduction-clause.f90   |   4 +-
 flang/test/Parser/OpenMP/task.f90             |   2 +-
 .../Semantics/OpenMP/clause-validity01.f90    |   3 +-
 flang/test/Semantics/OpenMP/symbol08.f90      |   3 +-
 38 files changed, 461 insertions(+), 557 deletions(-)

diff --git a/flang/examples/FeatureList/FeatureList.cpp b/flang/examples/FeatureList/FeatureList.cpp
index 64b57b633feaf..0b8066e36312b 100644
--- a/flang/examples/FeatureList/FeatureList.cpp
+++ b/flang/examples/FeatureList/FeatureList.cpp
@@ -445,10 +445,9 @@ struct NodeVisitor {
   READ_FEATURE(ObjectDecl)
   READ_FEATURE(OldParameterStmt)
   READ_FEATURE(OmpAlignedClause)
-  READ_FEATURE(OmpBeginBlockDirective)
+  READ_FEATURE(OmpBeginDirective)
   READ_FEATURE(OmpBeginLoopDirective)
   READ_FEATURE(OmpBeginSectionsDirective)
-  READ_FEATURE(OmpBlockDirective)
   READ_FEATURE(OmpClause)
   READ_FEATURE(OmpClauseList)
   READ_FEATURE(OmpCriticalDirective)
@@ -472,7 +471,7 @@ struct NodeVisitor {
   READ_FEATURE(OmpIteration)
   READ_FEATURE(OmpIterationOffset)
   READ_FEATURE(OmpIterationVector)
-  READ_FEATURE(OmpEndBlockDirective)
+  READ_FEATURE(OmpEndDirective)
   READ_FEATURE(OmpEndCriticalDirective)
   READ_FEATURE(OmpEndLoopDirective)
   READ_FEATURE(OmpEndSectionsDirective)
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index ebac54f6e29ba..b09dd32a90b98 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -534,10 +534,8 @@ class ParseTreeDumper {
   NODE(parser, OmpAtClause)
   NODE_ENUM(OmpAtClause, ActionTime)
   NODE_ENUM(OmpSeverityClause, Severity)
-  NODE(parser, OmpBeginBlockDirective)
   NODE(parser, OmpBeginLoopDirective)
   NODE(parser, OmpBeginSectionsDirective)
-  NODE(parser, OmpBlockDirective)
   static std::string GetNodeName(const llvm::omp::Directive &x) {
     return llvm::Twine("llvm::omp::Directive = ",
         llvm::omp::getOpenMPDirectiveName(x, llvm::omp::FallbackVersion))
@@ -584,7 +582,6 @@ class ParseTreeDumper {
   NODE(parser, OmpDetachClause)
   NODE(parser, OmpDoacrossClause)
   NODE(parser, OmpDestroyClause)
-  NODE(parser, OmpEndBlockDirective)
   NODE(parser, OmpEndCriticalDirective)
   NODE(parser, OmpEndLoopDirective)
   NODE(parser, OmpEndSectionsDirective)
@@ -704,6 +701,8 @@ class ParseTreeDumper {
   NODE(parser, OpenMPDeclarativeAssumes)
   NODE(parser, OmpAssumeDirective)
   NODE(parser, OmpEndAssumeDirective)
+  NODE(parser, OmpBeginDirective)
+  NODE(parser, OmpEndDirective)
   NODE(parser, OpenMPAtomicConstruct)
   NODE(parser, OpenMPBlockConstruct)
   NODE(parser, OpenMPCancelConstruct)
diff --git a/flang/include/flang/Parser/openmp-utils.h b/flang/include/flang/Parser/openmp-utils.h
index 41c04424e91c6..fa0f7656cd5d8 100644
--- a/flang/include/flang/Parser/openmp-utils.h
+++ b/flang/include/flang/Parser/openmp-utils.h
@@ -68,11 +68,6 @@ struct DirectiveNameScope {
     return MakeName(x.source, llvm::omp::Directive::OMPD_nothing);
   }
 
-  static OmpDirectiveName GetOmpDirectiveName(const OmpBeginBlockDirective &x) {
-    auto &dir{std::get<OmpBlockDirective>(x.t)};
-    return MakeName(dir.source, dir.v);
-  }
-
   static OmpDirectiveName GetOmpDirectiveName(const OmpBeginLoopDirective &x) {
     auto &dir{std::get<OmpLoopDirective>(x.t)};
     return MakeName(dir.source, dir.v);
@@ -106,10 +101,8 @@ struct DirectiveNameScope {
         return GetOmpDirectiveName(x.v);
       }
     } else if constexpr (TupleTrait<T>) {
-      if constexpr (std::is_same_v<T, OpenMPAllocatorsConstruct> ||
-          std::is_same_v<T, OpenMPAtomicConstruct> ||
-          std::is_same_v<T, OpenMPDispatchConstruct>) {
-        return std::get<OmpDirectiveSpecification>(x.t).DirName();
+      if constexpr (std::is_base_of_v<OmpBlockConstruct, T>) {
+        return std::get<OmpBeginDirective>(x.t).DirName();
       } else if constexpr (std::is_same_v<T, OmpAssumeDirective> ||
           std::is_same_v<T, OmpCriticalDirective> ||
           std::is_same_v<T, OmpDeclareVariantDirective> ||
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index da0a3632b8a63..7ba5fe964f7a1 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3469,6 +3469,13 @@ WRAPPER_CLASS(PauseStmt, std::optional<StopCode>);
 
 // --- Common definitions
 
+#define INHERITED_TUPLE_CLASS_BOILERPLATE(classname, basename) \
+  template <typename... Ts, typename = common::NoLvalue<Ts...>> \
+  classname(Ts &&...args) : basename(std::move(args)...) {} \
+  classname(basename &&b) : basename(std::move(b)) {} \
+  using TupleTrait = std::true_type; \
+  BOILERPLATE(classname)
+
 #define INHERITED_WRAPPER_CLASS_BOILERPLATE(classname, basename) \
   BOILERPLATE(classname); \
   classname(decltype(basename::v) &&x) : basename(std::move(x)) {} \
@@ -4729,6 +4736,33 @@ struct OmpDirectiveSpecification {
       t;
 };
 
+// OmpBeginDirective and OmpEndDirective are needed for semantic analysis,
+// where some checks are done specifically for either the begin or the end
+// directive. The structure of both is identical, but the diffent types
+// allow to distinguish them in the type-based parse-tree visitor.
+struct OmpBeginDirective : public OmpDirectiveSpecification {
+  INHERITED_TUPLE_CLASS_BOILERPLATE(
+      OmpBeginDirective, OmpDirectiveSpecification);
+};
+
+struct OmpEndDirective : public OmpDirectiveSpecification {
+  INHERITED_TUPLE_CLASS_BOILERPLATE(OmpEndDirective, OmpDirectiveSpecification);
+};
+
+// Common base class for block-associated constructs.
+struct OmpBlockConstruct {
+  TUPLE_CLASS_BOILERPLATE(OmpBlockConstruct);
+  const OmpBeginDirective &BeginDir() const {
+    return std::get<OmpBeginDirective>(t);
+  }
+  const std::optional<OmpEndDirective> &EndDir() const {
+    return std::get<std::optional<OmpEndDirective>>(t);
+  }
+
+  CharBlock source;
+  std::tuple<OmpBeginDirective, Block, std::optional<OmpEndDirective>> t;
+};
+
 struct OmpMetadirectiveDirective {
   TUPLE_CLASS_BOILERPLATE(OmpMetadirectiveDirective);
   std::tuple<Verbatim, OmpClauseList> t;
@@ -4833,12 +4867,6 @@ struct OpenMPSectionsConstruct {
       t;
 };
 
-// OpenMP directive beginning or ending a block
-struct OmpBlockDirective {
-  WRAPPER_CLASS_BOILERPLATE(OmpBlockDirective, llvm::omp::Directive);
-  CharBlock source;
-};
-
 struct OmpDeclareVariantDirective {
   TUPLE_CLASS_BOILERPLATE(OmpDeclareVariantDirective);
   CharBlock source;
@@ -4963,12 +4991,9 @@ struct OpenMPExecutableAllocate {
 //    ALLOCATORS [allocate-clause...]
 //    block
 //    [END ALLOCATORS]
-struct OpenMPAllocatorsConstruct {
-  TUPLE_CLASS_BOILERPLATE(OpenMPAllocatorsConstruct);
-  CharBlock source;
-  std::tuple<OmpDirectiveSpecification, Block,
-      std::optional<OmpDirectiveSpecification>>
-      t;
+struct OpenMPAllocatorsConstruct : public OmpBlockConstruct {
+  INHERITED_TUPLE_CLASS_BOILERPLATE(
+      OpenMPAllocatorsConstruct, OmpBlockConstruct);
 };
 
 // 2.17.7 Atomic construct/2.17.8 Flush construct [OpenMP 5.0]
@@ -4982,15 +5007,11 @@ struct OmpMemoryOrderClause {
   CharBlock source;
 };
 
-struct OpenMPAtomicConstruct {
+struct OpenMPAtomicConstruct : public OmpBlockConstruct {
   llvm::omp::Clause GetKind() const;
   bool IsCapture() const;
   bool IsCompare() const;
-  TUPLE_CLASS_BOILERPLATE(OpenMPAtomicConstruct);
-  CharBlock source;
-  std::tuple<OmpDirectiveSpecification, Block,
-      std::optional<OmpDirectiveSpecification>>
-      t;
+  INHERITED_TUPLE_CLASS_BOILERPLATE(OpenMPAtomicConstruct, OmpBlockConstruct);
 
   // Information filled out during semantic checks to avoid duplication
   // of analyses.
@@ -5054,12 +5075,8 @@ struct OpenMPDepobjConstruct {
 //                    nocontext-clause |
 //                    novariants-clause |
 //                    nowait-clause
-struct OpenMPDispatchConstruct {
-  TUPLE_CLASS_BOILERPLATE(OpenMPDispatchConstruct);
-  CharBlock source;
-  std::tuple<OmpDirectiveSpecification, Block,
-      std::optional<OmpDirectiveSpecification>>
-      t;
+struct OpenMPDispatchConstruct : public OmpBlockConstruct {
+  INHERITED_TUPLE_CLASS_BOILERPLATE(OpenMPDispatchConstruct, OmpBlockConstruct);
 };
 
 // [4.5:162-165], [5.0:242-246], [5.1:275-279], [5.2:315-316], [6.0:498-500]
@@ -5114,22 +5131,8 @@ struct OmpEndLoopDirective {
   CharBlock source;
 };
 
-struct OmpBeginBlockDirective {
-  TUPLE_CLASS_BOILERPLATE(OmpBeginBlockDirective);
-  std::tuple<OmpBlockDirective, OmpClauseList> t;
-  CharBlock source;
-};
-
-struct OmpEndBlockDirective {
-  TUPLE_CLASS_BOILERPLATE(OmpEndBlockDirective);
-  std::tuple<OmpBlockDirective, OmpClauseList> t;
-  CharBlock source;
-};
-
-struct OpenMPBlockConstruct {
-  TUPLE_CLASS_BOILERPLATE(OpenMPBlockConstruct);
-  std::tuple<OmpBeginBlockDirective, Block, std::optional<OmpEndBlockDirective>>
-      t;
+struct OpenMPBlockConstruct : public OmpBlockConstruct {
+  INHERITED_TUPLE_CLASS_BOILERPLATE(OpenMPBlockConstruct, OmpBlockConstruct);
 };
 
 // OpenMP directives enclosing do loop
diff --git a/flang/lib/Lower/OpenMP/Atomic.cpp b/flang/lib/Lower/OpenMP/Atomic.cpp
index 9a233d2d8cb08..623a9370aa00d 100644
--- a/flang/lib/Lower/OpenMP/Atomic.cpp
+++ b/flang/lib/Lower/OpenMP/Atomic.cpp
@@ -699,7 +699,7 @@ void Fortran::lower::omp::lowerAtomic(
   };
 
   fir::FirOpBuilder &builder = converter.getFirOpBuilder();
-  auto &dirSpec = std::get<parser::OmpDirectiveSpecification>(construct.t);
+  const parser::OmpDirectiveSpecification &dirSpec = construct.BeginDir();
   omp::List<omp::Clause> clauses = makeClauses(dirSpec.Clauses(), semaCtx);
   lower::StatementContext stmtCtx;
 
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 6dd4b16a1fb55..68ebb66309f99 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -407,16 +407,9 @@ static void processHostEvalClauses(lower::AbstractConverter &converter,
     common::visit(
         common::visitors{
             [&](const parser::OpenMPBlockConstruct &ompConstruct) {
-              const auto &beginDirective =
-                  std::get<parser::OmpBeginBlockDirective>(ompConstruct.t);
-              beginClauseList =
-                  &std::get<parser::OmpClauseList>(beginDirective.t);
-              if (auto &endDirective =
-                      std::get<std::optional<parser::OmpEndBlockDirective>>(
-                          ompConstruct.t)) {
-                endClauseList =
-                    &std::get<parser::OmpClauseList>(endDirective->t);
-              }
+              beginClauseList = &ompConstruct.BeginDir().Clauses();
+              if (auto &endSpec = ompConstruct.EndDir())
+                endClauseList = &endSpec->Clauses();
             },
             [&](const parser::OpenMPLoopConstruct &ompConstruct) {
               const auto &beginDirective =
@@ -3716,25 +3709,16 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
                    semantics::SemanticsContext &semaCtx,
                    lower::pft::Evaluation &eval,
                    const parser::OpenMPBlockConstruct &blockConstruct) {
-  const auto &beginBlockDirective =
-      std::get<parser::OmpBeginBlockDirective>(blockConstruct.t);
-  mlir::Location currentLocation =
-      converter.genLocation(beginBlockDirective.source);
-  const auto origDirective =
-      std::get<parser::OmpBlockDirective>(beginBlockDirective.t).v;
-  List<Clause> clauses = makeClauses(
-      std::get<parser::OmpClauseList>(beginBlockDirective.t), semaCtx);
-
-  if (const auto &endBlockDirective =
-          std::get<std::optional<parser::OmpEndBlockDirective>>(
-              blockConstruct.t)) {
-    clauses.append(makeClauses(
-        std::get<parser::OmpClauseList>(endBlockDirective->t), semaCtx));
-  }
-
-  assert(llvm::omp::blockConstructSet.test(origDirective) &&
+  const parser::OmpDirectiveSpecification &beginSpec =
+      blockConstruct.BeginDir();
+  List<Clause> clauses = makeClauses(beginSpec.Clauses(), semaCtx);
+  if (auto &endSpec = blockConstruct.EndDir())
+    clauses.append(makeClauses(endSpec->Clauses(), semaCtx));
+
+  llvm::omp::Directive directive = beginSpec.DirId();
+  assert(llvm::omp::blockConstructSet.test(directive) &&
          "Expected block construct");
-  (void)origDirective;
+  mlir::Location currentLocation = converter.genLocation(beginSpec.source);
 
   for (const Clause &clause : clauses) {
     mlir::Location clauseLocation = converter.genLocation(clause.source);
@@ -3777,13 +3761,9 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
     }
   }
 
-  llvm::omp::Directive directive =
-      std::get<parser::OmpBlockDirective>(beginBlockDirective.t).v;
-  const parser::CharBlock &source =
-      std::get<parser::OmpBlockDirective>(beginBlockDirective.t).source;
   ConstructQueue queue{
       buildConstructQueue(converter.getFirOpBuilder().getModule(), semaCtx,
-                          eval, source, directive, clauses)};
+                          eval, beginSpec.source, directive, clauses)};
   genOMPDispatch(converter, symTable, semaCtx, eval, currentLocation, queue,
                  queue.begin());
 }
@@ -4071,8 +4051,7 @@ bool Fortran::lower::isOpenMPTargetConstruct(
     const parser::OpenMPConstruct &omp) {
   llvm::omp::Directive dir = llvm::omp::Directive::OMPD_unknown;
   if (const auto *block = std::get_if<parser::OpenMPBlockConstruct>(&omp.u)) {
-    const auto &begin = std::get<parser::OmpBeginBlockDirective>(block->t);
-    dir = std::get<parser::OmpBlockDirective>(begin.t).v;
+    dir = block->BeginDir().DirId();
   } else if (const auto *loop =
                  std::get_if<parser::OpenMPLoopConstruct>(&omp.u)) {
     const auto &begin = std::get<parser::OmpBeginLoopDirective>(loop->t);
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 8c780388b9cb1..c2c1921f446c7 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1371,16 +1371,41 @@ TYPE_PARSER(sourced(construct<OmpLoopDirective>(first(
 TYPE_PARSER(sourced(construct<OmpBeginLoopDirective>(
     sourced(Parser<OmpLoopDirective>{}), Parser<OmpClauseList>{})))
 
+static inline constexpr auto IsDirective(llvm::omp::Directive dir) {
+  return [dir](const OmpDirectiveName &name) -> bool { return dir == name.v; };
+}
+
+struct OmpBeginDirectiveParser {
+  using resultType = OmpDirectiveSpecification;
+
+  constexpr OmpBeginDirectiveParser(llvm::omp::Directive dir) : dir_(dir) {}
+
+  std::optional<resultType> Parse(ParseState &state) const {
+    auto &&p{predicated(Parser<OmpDirectiveName>{}, IsDirective(dir_)) >=
+        Parser<OmpDirectiveSpecification>{}};
+    return p.Parse(state);
+  }
+
+private:
+  llvm::omp::Directive dir_;
+};
+
 struct OmpEndDirectiveParser {
   using resultType = OmpDirectiveSpecification;
 
   constexpr OmpEndDirectiveParser(llvm::omp::Directive dir) : dir_(dir) {}
 
   std::optional<resultType> Parse(ParseState &state) const {
-    if ((startOmpLine >> "END"_sptok).Parse(state)) {
-      auto &&dirSpec{Parser<OmpDirectiveSpecification>{}.Parse(state)};
-      if (dirSpec && dirSpec->DirId() == dir_) {
-        return std::move(dirSpec);
+    if (startOmpLine.Parse(state)) {
+      if (auto endToken{verbatim("END"_sptok).Parse(state)}) {
+        if (auto &&dirSpec{OmpBeginDirectiveParser(dir_).Parse(state)}) {
+          // Extend the "source" on both the OmpDirectiveName and the
+          // OmpDirectiveNameSpecification.
+          CharBlock &nameSource{std::get<OmpDirectiveName>(dirSpec->t).source};
+          nameSource.ExtendToCover(endToken->source);
+          dirSpec->source.ExtendToCover(endToken->source);
+          return std::move(*dirSpec);
+        }
       }
     }
     return std::nullopt;
@@ -1390,57 +1415,67 @@ struct OmpEndDirectiveParser {
   llvm::omp::Directive dir_;
 };
 
-struct OmpAllocatorsConstructParser {
-  using resultType = OpenMPAllocatorsConstruct;
+struct OmpStatementConstructParser {
+  using resultType = OmpBlockConstruct;
+
+  constexpr OmpStatementConstructParser(llvm::omp::Directive dir) : dir_(dir) {}
 
   std::optional<resultType> Parse(ParseState &state) const {
-    auto dirSpec{Parser<OmpDirectiveSpecification>{}.Parse(state)};
-    if (!dirSpec || dirSpec->DirId() != llvm::omp::Directive::OMPD_allocators) {
-      return std::nullopt;
-    }
+    if (auto begin{OmpBeginDirectiveParser(dir_).Parse(state)}) {
+      Block body;
+      if (auto stmt{attempt(Parser<ExecutionPartConstruct>{}).Parse(state)}) {
+        body.emplace_back(std::move(*stmt));
+      }
+      // Allow empty block. Check for this in semantics.
 
-    // This should be an allocate-stmt. That will be checked in semantics.
-    Block block;
-    if (auto stmt{attempt(Parser<ExecutionPartConstruct>{}).Parse(state)}) {
-      block.emplace_back(std::move(*stmt));
+      auto end{maybe(OmpEndDirectiveParser{dir_}).Parse(state)};
+      return OmpBlockConstruct{OmpBeginDirective(std::move(*begin)),
+          std::move(body),
+          llvm::transformOptional(std::move(*end),
+              [](auto &&s) { return OmpEndDirective(std::move(s)); })};
     }
-    // Allow empty block. Check for this in semantics.
-
-    auto end{OmpEndDirectiveParser{llvm::omp::Directive::OMPD_allocators}};
-    return OpenMPAllocatorsConstruct{
-        std::move(*dirSpec), std::move(block), *maybe(end).Parse(state)};
+    return std::nullopt;
   }
+
+private:
+  llvm::omp::Directive dir_;
 };
 
-TYPE_PARSER(sourced( //
-    construct<OpenMPAllocatorsConstruct>(
-        "ALLOCATORS"_tok >= OmpAllocatorsConstructParser{})))
+struct OmpBlockConstructParser {
+  using resultType = OmpBlockConstruct;
 
-struct OmpDispatchConstructParser {
-  using resultType = OpenMPDispatchConstruct;
+  constexpr OmpBlockConstructParser(llvm::omp::Directive dir) : dir_(dir) {}
 
   std::optional<resultType> Parse(ParseState &state) const {
-    auto dirSpec{Parser<OmpDirectiveSpecification>{}.Parse(state)};
-    if (!dirSpec || dirSpec->DirId() != llvm::omp::Directive::OMPD_dispatch) {
-      return std::nullopt;
-    }
-
-    // This should be a function call. That will be checked in semantics.
-    Block block;
-    if (auto stmt{attempt(Parser<ExecutionPartConstruct>{}).Parse(state)}) {
-      block.emplace_back(std::move(*stmt));
+    if (auto &&begin{OmpBeginDirectiveParser(dir_).Parse(state)}) {
+      if (auto &&body{attempt(StrictlyStructuredBlockParser{}).Parse(state)}) {
+        // Try strictly-structured block with an optional end-directive
+        auto end{maybe(OmpEndDirectiveParser{dir_}).Parse(state)};
+        return OmpBlockConstruct{OmpBeginDirective(std::move(*begin)),
+            std::move(*body),
+            llvm::transformOptional(std::move(*end),
+                [](auto &&s) { return OmpEndDirective(std::move(s)); })};
+      } else if (auto &&body{
+                     attempt(LooselyStructuredBlockParser{}).Parse(state)}) {
+        // Try loosely-structured block with a mandatory end-directive
+        if (auto end{OmpEndDirectiveParser{dir_}.Parse(state)}) {
+          return OmpBlockConstruct{OmpBeginDirective(std::move(*begin)),
+              std::move(*body), OmpEndDirective{std::move(*end)}};
+        }
+      }
     }
-    // Allow empty block. Check for this in semantics.
-
-    auto end{OmpEndDirectiveParser{llvm::omp::Directive::OMPD_dispatch}};
-    return OpenMPDispatchConstruct{
-        std::move(*dirSpec), std::move(block), *maybe(end).Parse(state)};
+    return std::nullopt;
   }
+
+private:
+  llvm::omp::Directive dir_;
 };
 
-TYPE_PARSER(sourced( //
-    construct<OpenMPDispatchConstruct>(
-        "DISPATCH"_tok >= OmpDispatchConstructParser{})))
+TYPE_PARSER(sourced(construct<OpenMPAllocatorsConstruct>(
+    OmpStatementConstructParser{llvm::omp::Directive::OMPD_allocators})))
+
+TYPE_PARSER(sourced(construct<OpenMPDispatchConstruct>(
+    OmpStatementConstructParser{llvm::omp::Directive::OMPD_dispatch})))
 
 // Parser for an arbitrary OpenMP ATOMIC construct.
 //
@@ -1505,8 +1540,10 @@ struct OmpAtomicConstructParser {
         }
       }
       recursing_ = false;
-      return OpenMPAtomicConstruct{
-          std::move(*dirSpec), std::move(tail.first), std::move(tail.second)};
+      return OpenMPAtomicConstruct{OmpBeginDirective(std::move(*dirSpec)),
+          std::move(tail.first),
+          llvm::transformOptional(std::move(tail.second),
+              [](auto &&s) { return OmpEndDirective(std::move(s)); })};
     }
 
     recursing_ = false;
@@ -1607,10 +1644,6 @@ TYPE_PARSER(sourced( //
         predicated(OmpDirectiveNameParser{}, IsSimpleStandalone) >=
         Parser<OmpDirectiveSpecification>{})))
 
-static inline constexpr auto IsDirective(llvm::omp::Directive dir) {
-  return [dir](const OmpDirectiveName &name) -> bool { return dir == name.v; };
-}
-
 TYPE_PARSER(sourced( //
     construct<OpenMPFlushConstruct>(
         predicated(OmpDirectiveNameParser{},
@@ -1661,40 +1694,6 @@ TYPE_PARSER(
             Parser<OpenMPInteropConstruct>{})) /
     endOfLine)
 
-// Directive names (of non-block constructs) whose prefix is a name of
-// a block-associated construct. We need to exclude them from the block
-// directive parser below to avoid parsing parts of them.
-static constexpr auto StandaloneDirectiveLookahead{//
-    "TARGET ENTER DATA"_sptok || "TARGET_ENTER_DATA"_sptok || //
-    "TARGET EXIT DATA"_sptok || "TARGET_EXIT"_sptok || //
-    "TARGET UPDATE"_sptok || "TARGET_UPDATE"_sptok};
-
-// Directives enclosing structured-block
-TYPE_PARSER((!StandaloneDirectiveLookahead) >=
-    construct<OmpBlockDirective>(first(
-        "MASKED" >> pure(llvm::omp::Directive::OMPD_masked),
-        "MASTER" >> pure(llvm::omp::Directive::OMPD_master),
-        "ORDERED" >> pure(llvm::omp::Directive::OMPD_ordered),
-        "PARALLEL MASKED" >> pure(llvm::omp::Directive::OMPD_parallel_masked),
-        "PARALLEL MASTER" >> pure(llvm::omp::Directive::OMPD_parallel_master),
-        "PARALLEL WORKSHARE" >>
-            pure(llvm::omp::Directive::OMPD_parallel_workshare),
-        "PARALLEL" >> pure(llvm::omp::Directive::OMPD_parallel),
-        "SCOPE" >> pure(llvm::omp::Directive::OMPD_scope),
-        "SINGLE" >> pure(llvm::omp::Directive::OMPD_single),
-        "TARGET DATA" >> pure(llvm::omp::Directive::OMPD_target_data),
-        "TARGET_DATA" >> pure(llvm::omp::Directive::OMPD_target_data),
-        "TARGET PARALLEL" >> pure(llvm::omp::Directive::OMPD_target_parallel),
-        "TARGET TEAMS" >> pure(llvm::omp::Directive::OMPD_target_teams),
-        "TARGET" >> pure(llvm::omp::Directive::OMPD_target),
-        "TASK"_id >> pure(llvm::omp::Directive::OMPD_task),
-        "TASKGROUP" >> pure(llvm::omp::Directive::OMPD_taskgroup),
-        "TEAMS" >> pure(llvm::omp::Directive::OMPD_teams),
-        "WORKSHARE" >> pure(llvm::omp::Directive::OMPD_workshare))))
-
-TYPE_PARSER(sourced(construct<OmpBeginBlockDirective>(
-    sourced(Parser<OmpBlockDirective>{}), Parser<OmpClauseList>{})))
-
 TYPE_PARSER(construct<OmpInitializerProc>(Parser<ProcedureDesignator>{},
     parenthesized(many(maybe(","_tok) >> Parser<ActualArgSpec>{}))))
 
@@ -1844,12 +1843,27 @@ TYPE_PARSER(sourced(
         block, maybe(Parser<OmpEndAssumeDirective>{} / endOmpLine))))
 
 // Block Construct
+#define MakeBlockConstruct(dir) \
+  construct<OpenMPBlockConstruct>(OmpBlockConstructParser{dir})
 TYPE_PARSER( //
-    construct<OpenMPBlockConstruct>(Parser<OmpBeginBlockDirective>{},
-        StrictlyStructuredBlockParser{},
-        maybe(Parser<OmpEndBlockDirective>{})) ||
-    construct<OpenMPBlockConstruct>(Parser<OmpBeginBlockDirective>{},
-        LooselyStructuredBlockParser{}, Parser<OmpEndBlockDirective>{}))
+    MakeBlockConstruct(llvm::omp::Directive::OMPD_masked) ||
+    MakeBlockConstruct(llvm::omp::Directive::OMPD_master) ||
+    MakeBlockConstruct(llvm::omp::Directive::OMPD_ordered) ||
+    MakeBlockConstruct(llvm::omp::Directive::OMPD_parallel_masked) ||
+    MakeBlockConstruct(llvm::omp::Directive::OMPD_parallel_master) ||
+    MakeBlockConstruct(llvm::omp::Directive::OMPD_parallel_workshare) ||
+    MakeBlockConstruct(llvm::omp::Directive::OMPD_parallel) ||
+    MakeBlockConstruct(llvm::omp::Directive::OMPD_scope) ||
+    MakeBlockConstruct(llvm::omp::Directive::OMPD_single) ||
+    MakeBlockConstruct(llvm::omp::Directive::OMPD_target_data) ||
+    MakeBlockConstruct(llvm::omp::Directive::OMPD_target_parallel) ||
+    MakeBlockConstruct(llvm::omp::Directive::OMPD_target_teams) ||
+    MakeBlockConstruct(llvm::omp::Directive::OMPD_target) ||
+    MakeBlockConstruct(llvm::omp::Directive::OMPD_task) ||
+    MakeBlockConstruct(llvm::omp::Directive::OMPD_taskgroup) ||
+    MakeBlockConstruct(llvm::omp::Directive::OMPD_teams) ||
+    MakeBlockConstruct(llvm::omp::Directive::OMPD_workshare))
+#undef MakeBlockConstruct
 
 // OMP SECTIONS Directive
 TYPE_PARSER(construct<OmpSectionsDirective>(first(
@@ -1904,12 +1918,6 @@ TYPE_CONTEXT_PARSER("OpenMP construct"_en_US,
                 construct<OpenMPConstruct>(Parser<OpenMPAssumeConstruct>{}),
                 construct<OpenMPConstruct>(Parser<OpenMPCriticalConstruct>{}))))
 
-// END OMP Block directives
-TYPE_PARSER(
-    startOmpLine >> sourced(construct<OmpEndBlockDirective>(
-                        sourced("END"_tok >> Parser<OmpBlockDirective>{}),
-                        Parser<OmpClauseList>{})))
-
 // END OMP Loop directives
 TYPE_PARSER(
     startOmpLine >> sourced(construct<OmpEndLoopDirective>(
diff --git a/flang/lib/Parser/parse-tree.cpp b/flang/lib/Parser/parse-tree.cpp
index 7b46c9f469b06..cb3093954cbe4 100644
--- a/flang/lib/Parser/parse-tree.cpp
+++ b/flang/lib/Parser/parse-tree.cpp
@@ -322,7 +322,7 @@ std::string OmpTraitSetSelectorName::ToString() const {
 }
 
 llvm::omp::Clause OpenMPAtomicConstruct::GetKind() const {
-  auto &dirSpec{std::get<OmpDirectiveSpecification>(t)};
+  const OmpDirectiveSpecification &dirSpec{std::get<OmpBeginDirective>(t)};
   for (auto &clause : dirSpec.Clauses().v) {
     switch (clause.Id()) {
     case llvm::omp::Clause::OMPC_read:
@@ -337,14 +337,14 @@ llvm::omp::Clause OpenMPAtomicConstruct::GetKind() const {
 }
 
 bool OpenMPAtomicConstruct::IsCapture() const {
-  auto &dirSpec{std::get<OmpDirectiveSpecification>(t)};
+  const OmpDirectiveSpecification &dirSpec{std::get<OmpBeginDirective>(t)};
   return llvm::any_of(dirSpec.Clauses().v, [](auto &clause) {
     return clause.Id() == llvm::omp::Clause::OMPC_capture;
   });
 }
 
 bool OpenMPAtomicConstruct::IsCompare() const {
-  auto &dirSpec{std::get<OmpDirectiveSpecification>(t)};
+  const OmpDirectiveSpecification &dirSpec{std::get<OmpBeginDirective>(t)};
   return llvm::any_of(dirSpec.Clauses().v, [](auto &clause) {
     return clause.Id() == llvm::omp::Clause::OMPC_compare;
   });
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 1d4d53de1491d..029ca4e74c7a1 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2508,87 +2508,39 @@ class UnparseVisitor {
     }
   }
   void Unparse(const OmpObjectList &x) { Walk(x.v, ","); }
-  void Unparse(const OmpBlockDirective &x) {
-    switch (x.v) {
-    case llvm::omp::Directive::OMPD_masked:
-      Word("MASKED");
-      break;
-    case llvm::omp::Directive::OMPD_master:
-      Word("MASTER");
-      break;
-    case llvm::omp::Directive::OMPD_ordered:
-      Word("ORDERED ");
-      break;
-    case llvm::omp::Directive::OMPD_parallel_masked:
-      Word("PARALLEL MASKED");
-      break;
-    case llvm::omp::Directive::OMPD_parallel_master:
-      Word("PARALLEL MASTER");
-      break;
-    case llvm::omp::Directive::OMPD_parallel_workshare:
-      Word("PARALLEL WORKSHARE ");
-      break;
-    case llvm::omp::Directive::OMPD_parallel:
-      Word("PARALLEL ");
-      break;
-    case llvm::omp::Directive::OMPD_scope:
-      Word("SCOPE ");
-      break;
-    case llvm::omp::Directive::OMPD_single:
-      Word("SINGLE ");
-      break;
-    case llvm::omp::Directive::OMPD_target_data:
-      Word("TARGET DATA ");
-      break;
-    case llvm::omp::Directive::OMPD_target_parallel:
-      Word("TARGET PARALLEL ");
-      break;
-    case llvm::omp::Directive::OMPD_target_teams:
-      Word("TARGET TEAMS ");
-      break;
-    case llvm::omp::Directive::OMPD_target:
-      Word("TARGET ");
-      break;
-    case llvm::omp::Directive::OMPD_taskgroup:
-      Word("TASKGROUP ");
-      break;
-    case llvm::omp::Directive::OMPD_task:
-      Word("TASK ");
-      break;
-    case llvm::omp::Directive::OMPD_teams:
-      Word("TEAMS ");
-      break;
-    case llvm::omp::Directive::OMPD_workshare:
-      Word("WORKSHARE ");
-      break;
-    default:
-      // Nothing to be done
-      break;
-    }
-  }
 
   void Unparse(const common::OmpMemoryOrderType &x) {
     Word(ToUpperCaseLetters(common::EnumToString(x)));
   }
 
-  template <typename Construct> void UnparseBlockConstruct(const Construct &x) {
+  void Unparse(const OmpBeginDirective &x) {
     BeginOpenMP();
     Word("!$OMP ");
-    Walk(std::get<OmpDirectiveSpecification>(x.t));
+    Walk(static_cast<const OmpDirectiveSpecification &>(x));
     Put("\n");
     EndOpenMP();
+  }
+
+  void Unparse(const OmpEndDirective &x) {
+    BeginOpenMP();
+    Word("!$OMP END ");
+    Walk(static_cast<const OmpDirectiveSpecification &>(x));
+    Put("\n");
+    EndOpenMP();
+  }
+
+  void Unparse(const OmpBlockConstruct &x) {
+    Walk(std::get<OmpBeginDirective>(x.t));
     Walk(std::get<Block>(x.t), "");
-    if (auto &end{std::get<std::optional<OmpDirectiveSpecification>>(x.t)}) {
-      BeginOpenMP();
-      Word("!$OMP END ");
+    if (auto &end{std::get<std::optional<OmpEndDirective>>(x.t)}) {
       Walk(*end);
+    } else {
       Put("\n");
-      EndOpenMP();
     }
   }
 
   void Unparse(const OpenMPAtomicConstruct &x) { //
-    UnparseBlockConstruct(x);
+    Unparse(static_cast<const OmpBlockConstruct &>(x));
   }
 
   void Unparse(const OpenMPExecutableAllocate &x) {
@@ -2619,7 +2571,7 @@ class UnparseVisitor {
     EndOpenMP();
   }
   void Unparse(const OpenMPAllocatorsConstruct &x) { //
-    UnparseBlockConstruct(x);
+    Unparse(static_cast<const OmpBlockConstruct &>(x));
   }
   void Unparse(const OmpAssumeDirective &x) {
     BeginOpenMP();
@@ -2759,7 +2711,7 @@ class UnparseVisitor {
     EndOpenMP();
   }
   void Unparse(const OpenMPDispatchConstruct &x) { //
-    UnparseBlockConstruct(x);
+    Unparse(static_cast<const OmpBlockConstruct &>(x));
   }
   void Unparse(const OpenMPRequiresConstruct &y) {
     BeginOpenMP();
@@ -2892,19 +2844,7 @@ class UnparseVisitor {
     EndOpenMP();
   }
   void Unparse(const OpenMPBlockConstruct &x) {
-    BeginOpenMP();
-    Word("!$OMP ");
-    Walk(std::get<OmpBeginBlockDirective>(x.t));
-    Put("\n");
-    EndOpenMP();
-    Walk(std::get<Block>(x.t), "");
-    if (auto &&end{std::get<std::optional<OmpEndBlockDirective>>(x.t)}) {
-      BeginOpenMP();
-      Word("!$OMP END ");
-      Walk(*end);
-      Put("\n");
-      EndOpenMP();
-    }
+    Unparse(static_cast<const OmpBlockConstruct &>(x));
   }
   void Unparse(const OpenMPLoopConstruct &x) {
     BeginOpenMP();
diff --git a/flang/lib/Semantics/check-omp-atomic.cpp b/flang/lib/Semantics/check-omp-atomic.cpp
index c5ed8796f0c34..fae38672ef396 100644
--- a/flang/lib/Semantics/check-omp-atomic.cpp
+++ b/flang/lib/Semantics/check-omp-atomic.cpp
@@ -1105,12 +1105,11 @@ void OmpStructureChecker::CheckAtomicRead(
   // of the following forms:
   //   v = x
   //   v => x
-  auto &dirSpec{std::get<parser::OmpDirectiveSpecification>(x.t)};
   auto &block{std::get<parser::Block>(x.t)};
 
   // Read cannot be conditional or have a capture statement.
   if (x.IsCompare() || x.IsCapture()) {
-    context_.Say(dirSpec.source,
+    context_.Say(x.BeginDir().source,
         "ATOMIC READ cannot have COMPARE or CAPTURE clauses"_err_en_US);
     return;
   }
@@ -1141,12 +1140,11 @@ void OmpStructureChecker::CheckAtomicRead(
 
 void OmpStructureChecker::CheckAtomicWrite(
     const parser::OpenMPAtomicConstruct &x) {
-  auto &dirSpec{std::get<parser::OmpDirectiveSpecification>(x.t)};
   auto &block{std::get<parser::Block>(x.t)};
 
   // Write cannot be conditional or have a capture statement.
   if (x.IsCompare() || x.IsCapture()) {
-    context_.Say(dirSpec.source,
+    context_.Say(x.BeginDir().source,
         "ATOMIC WRITE cannot have COMPARE or CAPTURE clauses"_err_en_US);
     return;
   }
@@ -1234,7 +1232,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPAtomicConstruct &x) {
     }
   }};
 
-  auto &dirSpec{std::get<parser::OmpDirectiveSpecification>(x.t)};
+  const parser::OmpDirectiveSpecification &dirSpec{x.BeginDir()};
   auto &dir{std::get<parser::OmpDirectiveName>(dirSpec.t)};
   PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_atomic);
   llvm::omp::Clause kind{x.GetKind()};
diff --git a/flang/lib/Semantics/check-omp-loop.cpp b/flang/lib/Semantics/check-omp-loop.cpp
index b82e2f7342d85..59d57a2ec7cfb 100644
--- a/flang/lib/Semantics/check-omp-loop.cpp
+++ b/flang/lib/Semantics/check-omp-loop.cpp
@@ -18,6 +18,7 @@
 #include "flang/Common/idioms.h"
 #include "flang/Common/visit.h"
 #include "flang/Parser/char-block.h"
+#include "flang/Parser/openmp-utils.h"
 #include "flang/Parser/parse-tree-visitor.h"
 #include "flang/Parser/parse-tree.h"
 #include "flang/Parser/tools.h"
@@ -196,14 +197,9 @@ void OmpStructureChecker::CheckSIMDNest(const parser::OpenMPConstruct &c) {
       common::visitors{
           // Allow `!$OMP ORDERED SIMD`
           [&](const parser::OpenMPBlockConstruct &c) {
-            const auto &beginBlockDir{
-                std::get<parser::OmpBeginBlockDirective>(c.t)};
-            const auto &beginDir{
-                std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
-            if (beginDir.v == llvm::omp::Directive::OMPD_ordered) {
-              const auto &clauses{
-                  std::get<parser::OmpClauseList>(beginBlockDir.t)};
-              for (const auto &clause : clauses.v) {
+            const parser::OmpDirectiveSpecification &beginSpec{c.BeginDir()};
+            if (beginSpec.DirId() == llvm::omp::Directive::OMPD_ordered) {
+              for (const auto &clause : beginSpec.Clauses().v) {
                 if (std::get_if<parser::OmpClause::Simd>(&clause.u)) {
                   eligibleSIMD = true;
                   break;
@@ -247,7 +243,7 @@ void OmpStructureChecker::CheckSIMDNest(const parser::OpenMPConstruct &c) {
       },
       c.u);
   if (!eligibleSIMD) {
-    context_.Say(parser::FindSourceLocation(c),
+    context_.Say(parser::omp::GetOmpDirectiveName(c).source,
         "The only OpenMP constructs that can be encountered during execution "
         "of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, "
         "the `SIMD` construct, the `SCAN` construct and the `ORDERED` "
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index c191ad8d088d3..d45993e8edf2f 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -498,7 +498,7 @@ template <typename Checker> struct DirectiveSpellingVisitor {
   template <typename... Ts>
   static const parser::OmpDirectiveName &GetDirName(
       const std::tuple<Ts...> &t) {
-    return std::get<parser::OmpDirectiveSpecification>(t).DirName();
+    return std::get<parser::OmpBeginDirective>(t).DirName();
   }
 
   bool Pre(const parser::OmpSectionsDirective &x) {
@@ -588,12 +588,14 @@ template <typename Checker> struct DirectiveSpellingVisitor {
     checker_(std::get<parser::Verbatim>(x.t).source, Directive::OMPD_requires);
     return false;
   }
-
-  bool Pre(const parser::OmpBlockDirective &x) {
-    checker_(x.source, x.v);
+  bool Pre(const parser::OmpBeginDirective &x) {
+    checker_(x.DirName().source, x.DirId());
+    return false;
+  }
+  bool Pre(const parser::OmpEndDirective &x) {
+    checker_(x.DirName().source, x.DirId());
     return false;
   }
-
   bool Pre(const parser::OmpLoopDirective &x) {
     checker_(x.source, x.v);
     return false;
@@ -726,22 +728,22 @@ void OmpStructureChecker::CheckTargetNest(const parser::OpenMPConstruct &c) {
   // 2.12.5 Target Construct Restriction
   bool eligibleTarget{true};
   llvm::omp::Directive ineligibleTargetDir;
+  parser::CharBlock source;
   common::visit(
       common::visitors{
           [&](const parser::OpenMPBlockConstruct &c) {
-            const auto &beginBlockDir{
-                std::get<parser::OmpBeginBlockDirective>(c.t)};
-            const auto &beginDir{
-                std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
-            if (beginDir.v == llvm::omp::Directive::OMPD_target_data) {
+            const parser::OmpDirectiveSpecification &beginSpec{c.BeginDir()};
+            source = beginSpec.DirName().source;
+            if (beginSpec.DirId() == llvm::omp::Directive::OMPD_target_data) {
               eligibleTarget = false;
-              ineligibleTargetDir = beginDir.v;
+              ineligibleTargetDir = beginSpec.DirId();
             }
           },
           [&](const parser::OpenMPStandaloneConstruct &c) {
             common::visit(
                 common::visitors{
                     [&](const parser::OpenMPSimpleStandaloneConstruct &c) {
+                      source = c.v.DirName().source;
                       switch (llvm::omp::Directive dirId{c.v.DirId()}) {
                       case llvm::omp::Directive::OMPD_target_update:
                       case llvm::omp::Directive::OMPD_target_enter_data:
@@ -762,6 +764,7 @@ void OmpStructureChecker::CheckTargetNest(const parser::OpenMPConstruct &c) {
                 std::get<parser::OmpBeginLoopDirective>(c.t)};
             const auto &beginDir{
                 std::get<parser::OmpLoopDirective>(beginLoopDir.t)};
+            source = beginLoopDir.source;
             if (llvm::omp::allTargetSet.test(beginDir.v)) {
               eligibleTarget = false;
               ineligibleTargetDir = beginDir.v;
@@ -771,8 +774,7 @@ void OmpStructureChecker::CheckTargetNest(const parser::OpenMPConstruct &c) {
       },
       c.u);
   if (!eligibleTarget) {
-    context_.Warn(common::UsageWarning::OpenMPUsage,
-        parser::FindSourceLocation(c),
+    context_.Warn(common::UsageWarning::OpenMPUsage, source,
         "If %s directive is nested inside TARGET region, the behaviour is unspecified"_port_en_US,
         parser::ToUpperCaseLetters(
             getDirectiveName(ineligibleTargetDir).str()));
@@ -780,25 +782,18 @@ void OmpStructureChecker::CheckTargetNest(const parser::OpenMPConstruct &c) {
 }
 
 void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
-  const auto &beginBlockDir{std::get<parser::OmpBeginBlockDirective>(x.t)};
-  const auto &endBlockDir{
-      std::get<std::optional<parser::OmpEndBlockDirective>>(x.t)};
-  const auto &beginDir{std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
+  const parser::OmpDirectiveSpecification &beginSpec{x.BeginDir()};
+  const std::optional<parser::OmpEndDirective> &endSpec{x.EndDir()};
   const parser::Block &block{std::get<parser::Block>(x.t)};
 
-  if (endBlockDir) {
-    const auto &endDir{std::get<parser::OmpBlockDirective>(endBlockDir->t)};
-    CheckMatching<parser::OmpBlockDirective>(beginDir, endDir);
-  }
-
-  PushContextAndClauseSets(beginDir.source, beginDir.v);
+  PushContextAndClauseSets(beginSpec.DirName().source, beginSpec.DirId());
   if (llvm::omp::allTargetSet.test(GetContext().directive)) {
     EnterDirectiveNest(TargetNest);
   }
 
   if (CurrentDirectiveIsNested()) {
     if (llvm::omp::bottomTeamsSet.test(GetContextParent().directive)) {
-      HasInvalidTeamsNesting(beginDir.v, beginDir.source);
+      HasInvalidTeamsNesting(beginSpec.DirId(), beginSpec.source);
     }
     if (GetContext().directive == llvm::omp::Directive::OMPD_master) {
       CheckMasterNesting(x);
@@ -807,7 +802,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
     // region or a target region.
     if (GetContext().directive == llvm::omp::Directive::OMPD_teams &&
         GetContextParent().directive != llvm::omp::Directive::OMPD_target) {
-      context_.Say(parser::FindSourceLocation(x),
+      context_.Say(x.BeginDir().DirName().source,
           "%s region can only be strictly nested within the implicit parallel "
           "region or TARGET region"_err_en_US,
           ContextDirectiveAsFortran());
@@ -824,12 +819,12 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
     }
   }
 
-  CheckNoBranching(block, beginDir.v, beginDir.source);
+  CheckNoBranching(block, beginSpec.DirId(), beginSpec.source);
 
   // Target block constructs are target device constructs. Keep track of
   // whether any such construct has been visited to later check that REQUIRES
   // directives for target-related options don't appear after them.
-  if (llvm::omp::allTargetSet.test(beginDir.v)) {
+  if (llvm::omp::allTargetSet.test(beginSpec.DirId())) {
     deviceConstructFound_ = true;
   }
 
@@ -839,8 +834,8 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
     bool foundNowait{false};
     parser::CharBlock NowaitSource;
 
-    auto catchCopyPrivateNowaitClauses = [&](const auto &dir, bool isEnd) {
-      for (auto &clause : std::get<parser::OmpClauseList>(dir.t).v) {
+    auto catchCopyPrivateNowaitClauses = [&](const auto &dirSpec, bool isEnd) {
+      for (auto &clause : dirSpec.Clauses().v) {
         if (clause.Id() == llvm::omp::Clause::OMPC_copyprivate) {
           for (const auto &ompObject : GetOmpObjectList(clause)->v) {
             const auto *name{parser::Unwrap<parser::Name>(ompObject)};
@@ -881,9 +876,9 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
         }
       }
     };
-    catchCopyPrivateNowaitClauses(beginBlockDir, false);
-    if (endBlockDir) {
-      catchCopyPrivateNowaitClauses(*endBlockDir, true);
+    catchCopyPrivateNowaitClauses(beginSpec, false);
+    if (endSpec) {
+      catchCopyPrivateNowaitClauses(*endSpec, true);
     }
     unsigned version{context_.langOptions().OpenMPVersion};
     if (version <= 52 && NowaitSource.ToString().size() &&
@@ -893,7 +888,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
     }
   }
 
-  switch (beginDir.v) {
+  switch (beginSpec.DirId()) {
   case llvm::omp::Directive::OMPD_target:
     if (CheckTargetBlockOnlyTeams(block)) {
       EnterDirectiveNest(TargetBlockOnlyTeams);
@@ -901,27 +896,25 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
     break;
   case llvm::omp::OMPD_workshare:
   case llvm::omp::OMPD_parallel_workshare:
-    CheckWorkshareBlockStmts(block, beginDir.source);
+    CheckWorkshareBlockStmts(block, beginSpec.source);
     HasInvalidWorksharingNesting(
-        beginDir.source, llvm::omp::nestedWorkshareErrSet);
+        beginSpec.source, llvm::omp::nestedWorkshareErrSet);
     break;
   case llvm::omp::Directive::OMPD_scope:
   case llvm::omp::Directive::OMPD_single:
     // TODO: This check needs to be extended while implementing nesting of
     // regions checks.
     HasInvalidWorksharingNesting(
-        beginDir.source, llvm::omp::nestedWorkshareErrSet);
+        beginSpec.source, llvm::omp::nestedWorkshareErrSet);
     break;
-  case llvm::omp::Directive::OMPD_task: {
-    const auto &clauses{std::get<parser::OmpClauseList>(beginBlockDir.t)};
-    for (const auto &clause : clauses.v) {
+  case llvm::omp::Directive::OMPD_task:
+    for (const auto &clause : beginSpec.Clauses().v) {
       if (std::get_if<parser::OmpClause::Untied>(&clause.u)) {
         OmpUnitedTaskDesignatorChecker check{context_};
         parser::Walk(block, check);
       }
     }
     break;
-  }
   default:
     break;
   }
@@ -934,7 +927,7 @@ void OmpStructureChecker::CheckMasterNesting(
   // TODO:  Expand the check to include `LOOP` construct as well when it is
   // supported.
   if (IsCloselyNestedRegion(llvm::omp::nestedMasterErrSet)) {
-    context_.Say(parser::FindSourceLocation(x),
+    context_.Say(x.BeginDir().source,
         "`MASTER` region may not be closely nested inside of `WORKSHARING`, "
         "`LOOP`, `TASK`, `TASKLOOP`,"
         " or `ATOMIC` region."_err_en_US);
@@ -1034,7 +1027,7 @@ void OmpStructureChecker::ChecksOnOrderedAsBlock() {
   }
 }
 
-void OmpStructureChecker::Leave(const parser::OmpBeginBlockDirective &) {
+void OmpStructureChecker::Leave(const parser::OmpBeginDirective &) {
   switch (GetContext().directive) {
   case llvm::omp::Directive::OMPD_ordered:
     // [5.1] 2.19.9 Ordered Construct Restriction
@@ -1600,7 +1593,7 @@ void OmpStructureChecker::Enter(const parser::OmpErrorDirective &x) {
 }
 
 void OmpStructureChecker::Enter(const parser::OpenMPDispatchConstruct &x) {
-  auto &dirSpec{std::get<parser::OmpDirectiveSpecification>(x.t)};
+  const parser::OmpDirectiveSpecification &dirSpec{x.BeginDir()};
   const auto &block{std::get<parser::Block>(x.t)};
   PushContextAndClauseSets(
       dirSpec.DirName().source, llvm::omp::Directive::OMPD_dispatch);
@@ -1671,7 +1664,7 @@ void OmpStructureChecker::Leave(const parser::OpenMPExecutableAllocate &x) {
 void OmpStructureChecker::Enter(const parser::OpenMPAllocatorsConstruct &x) {
   isPredefinedAllocator = true;
 
-  auto &dirSpec{std::get<parser::OmpDirectiveSpecification>(x.t)};
+  const parser::OmpDirectiveSpecification &dirSpec{x.BeginDir()};
   auto &block{std::get<parser::Block>(x.t)};
   PushContextAndClauseSets(
       dirSpec.DirName().source, llvm::omp::Directive::OMPD_allocators);
@@ -1702,7 +1695,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPAllocatorsConstruct &x) {
 }
 
 void OmpStructureChecker::Leave(const parser::OpenMPAllocatorsConstruct &x) {
-  auto &dirSpec{std::get<parser::OmpDirectiveSpecification>(x.t)};
+  const parser::OmpDirectiveSpecification &dirSpec{x.BeginDir()};
 
   for (const auto &clause : dirSpec.Clauses().v) {
     if (const auto *allocClause{
@@ -1736,7 +1729,7 @@ void OmpStructureChecker::CheckBarrierNesting(
   // TODO:  Expand the check to include `LOOP` construct as well when it is
   // supported.
   if (IsCloselyNestedRegion(llvm::omp::nestedBarrierErrSet)) {
-    context_.Say(parser::FindSourceLocation(x),
+    context_.Say(x.v.DirName().source,
         "`BARRIER` region may not be closely nested inside of `WORKSHARING`, "
         "`LOOP`, `TASK`, `TASKLOOP`,"
         "`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region."_err_en_US);
@@ -2276,22 +2269,21 @@ void OmpStructureChecker::CheckCancellationNest(
   }
 }
 
-void OmpStructureChecker::Enter(const parser::OmpEndBlockDirective &x) {
-  const auto &dir{std::get<parser::OmpBlockDirective>(x.t)};
-  ResetPartialContext(dir.source);
-  switch (dir.v) {
+void OmpStructureChecker::Enter(const parser::OmpEndDirective &x) {
+  parser::CharBlock source{x.DirName().source};
+  ResetPartialContext(source);
+  switch (x.DirId()) {
   case llvm::omp::Directive::OMPD_scope:
-    PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_end_scope);
+    PushContextAndClauseSets(source, llvm::omp::Directive::OMPD_end_scope);
     break;
   // 2.7.3 end-single-clause -> copyprivate-clause |
   //                            nowait-clause
   case llvm::omp::Directive::OMPD_single:
-    PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_end_single);
+    PushContextAndClauseSets(source, llvm::omp::Directive::OMPD_end_single);
     break;
   // 2.7.4 end-workshare -> END WORKSHARE [nowait-clause]
   case llvm::omp::Directive::OMPD_workshare:
-    PushContextAndClauseSets(
-        dir.source, llvm::omp::Directive::OMPD_end_workshare);
+    PushContextAndClauseSets(source, llvm::omp::Directive::OMPD_end_workshare);
     break;
   default:
     // no clauses are allowed
@@ -2304,7 +2296,7 @@ void OmpStructureChecker::Enter(const parser::OmpEndBlockDirective &x) {
 // constructs unless a nowait clause is specified. Only OMPD_end_single and
 // end_workshareare popped as they are pushed while entering the
 // EndBlockDirective.
-void OmpStructureChecker::Leave(const parser::OmpEndBlockDirective &x) {
+void OmpStructureChecker::Leave(const parser::OmpEndDirective &x) {
   if ((GetContext().directive == llvm::omp::Directive::OMPD_end_scope) ||
       (GetContext().directive == llvm::omp::Directive::OMPD_end_single) ||
       (GetContext().directive == llvm::omp::Directive::OMPD_end_workshare)) {
@@ -4353,11 +4345,8 @@ bool OmpStructureChecker::CheckTargetBlockOnlyTeams(
             parser::Unwrap<parser::OpenMPConstruct>(*it)}) {
       if (const auto *ompBlockConstruct{
               std::get_if<parser::OpenMPBlockConstruct>(&ompConstruct->u)}) {
-        const auto &beginBlockDir{
-            std::get<parser::OmpBeginBlockDirective>(ompBlockConstruct->t)};
-        const auto &beginDir{
-            std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
-        if (beginDir.v == llvm::omp::Directive::OMPD_teams) {
+        llvm::omp::Directive dirId{ompBlockConstruct->BeginDir().DirId()};
+        if (dirId == llvm::omp::Directive::OMPD_teams) {
           nestedTeams = true;
         }
       }
@@ -4403,11 +4392,7 @@ void OmpStructureChecker::CheckWorkshareBlockStmts(
         auto currentDir{llvm::omp::Directive::OMPD_unknown};
         if (const auto *ompBlockConstruct{
                 std::get_if<parser::OpenMPBlockConstruct>(&ompConstruct->u)}) {
-          const auto &beginBlockDir{
-              std::get<parser::OmpBeginBlockDirective>(ompBlockConstruct->t)};
-          const auto &beginDir{
-              std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
-          currentDir = beginDir.v;
+          currentDir = ompBlockConstruct->BeginDir().DirId();
         } else if (const auto *ompLoopConstruct{
                        std::get_if<parser::OpenMPLoopConstruct>(
                            &ompConstruct->u)}) {
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index f4a291dc255c8..6b33ca6ab583f 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -90,9 +90,9 @@ class OmpStructureChecker
   void Leave(const parser::OpenMPDeclarativeAssumes &);
   void Enter(const parser::OpenMPBlockConstruct &);
   void Leave(const parser::OpenMPBlockConstruct &);
-  void Leave(const parser::OmpBeginBlockDirective &);
-  void Enter(const parser::OmpEndBlockDirective &);
-  void Leave(const parser::OmpEndBlockDirective &);
+  void Leave(const parser::OmpBeginDirective &);
+  void Enter(const parser::OmpEndDirective &);
+  void Leave(const parser::OmpEndDirective &);
 
   void Enter(const parser::OpenMPSectionsConstruct &);
   void Leave(const parser::OpenMPSectionsConstruct &);
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 4c3e509b5a36d..580c9cdbfc695 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -378,7 +378,7 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
   bool Pre(const parser::OpenMPBlockConstruct &);
   void Post(const parser::OpenMPBlockConstruct &);
 
-  void Post(const parser::OmpBeginBlockDirective &) {
+  void Post(const parser::OmpBeginDirective &x) {
     GetContext().withinConstruct = true;
   }
 
@@ -519,6 +519,9 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
   bool Pre(const parser::OpenMPDeclarativeAllocate &);
   void Post(const parser::OpenMPDeclarativeAllocate &) { PopContext(); }
 
+  bool Pre(const parser::OpenMPAtomicConstruct &);
+  void Post(const parser::OpenMPAtomicConstruct &) { PopContext(); }
+
   bool Pre(const parser::OpenMPDispatchConstruct &);
   void Post(const parser::OpenMPDispatchConstruct &) { PopContext(); }
 
@@ -1698,9 +1701,9 @@ static std::string ScopeSourcePos(const Fortran::semantics::Scope &scope);
 #endif
 
 bool OmpAttributeVisitor::Pre(const parser::OpenMPBlockConstruct &x) {
-  const auto &beginBlockDir{std::get<parser::OmpBeginBlockDirective>(x.t)};
-  const auto &beginDir{std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
-  switch (beginDir.v) {
+  const parser::OmpDirectiveSpecification &dirSpec{x.BeginDir()};
+  llvm::omp::Directive dirId{dirSpec.DirId()};
+  switch (dirId) {
   case llvm::omp::Directive::OMPD_masked:
   case llvm::omp::Directive::OMPD_parallel_masked:
   case llvm::omp::Directive::OMPD_master:
@@ -1718,15 +1721,15 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPBlockConstruct &x) {
   case llvm::omp::Directive::OMPD_parallel_workshare:
   case llvm::omp::Directive::OMPD_target_teams:
   case llvm::omp::Directive::OMPD_target_parallel:
-    PushContext(beginDir.source, beginDir.v);
+    PushContext(dirSpec.source, dirId);
     break;
   default:
     // TODO others
     break;
   }
-  if (beginDir.v == llvm::omp::Directive::OMPD_master ||
-      beginDir.v == llvm::omp::Directive::OMPD_parallel_master)
-    IssueNonConformanceWarning(beginDir.v, beginDir.source, 52);
+  if (dirId == llvm::omp::Directive::OMPD_master ||
+      dirId == llvm::omp::Directive::OMPD_parallel_master)
+    IssueNonConformanceWarning(dirId, dirSpec.source, 52);
   ClearDataSharingAttributeObjects();
   ClearPrivateDataSharingAttributeObjects();
   ClearAllocateNames();
@@ -1734,9 +1737,9 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPBlockConstruct &x) {
 }
 
 void OmpAttributeVisitor::Post(const parser::OpenMPBlockConstruct &x) {
-  const auto &beginBlockDir{std::get<parser::OmpBeginBlockDirective>(x.t)};
-  const auto &beginDir{std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
-  switch (beginDir.v) {
+  const parser::OmpDirectiveSpecification &dirSpec{x.BeginDir()};
+  llvm::omp::Directive dirId{dirSpec.DirId()};
+  switch (dirId) {
   case llvm::omp::Directive::OMPD_masked:
   case llvm::omp::Directive::OMPD_master:
   case llvm::omp::Directive::OMPD_parallel_masked:
@@ -2184,6 +2187,11 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPDeclarativeAllocate &x) {
   return false;
 }
 
+bool OmpAttributeVisitor::Pre(const parser::OpenMPAtomicConstruct &x) {
+  PushContext(x.source, llvm::omp::Directive::OMPD_atomic);
+  return true;
+}
+
 bool OmpAttributeVisitor::Pre(const parser::OpenMPDispatchConstruct &x) {
   PushContext(x.source, llvm::omp::Directive::OMPD_dispatch);
   return true;
@@ -2201,7 +2209,7 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPExecutableAllocate &x) {
 }
 
 bool OmpAttributeVisitor::Pre(const parser::OpenMPAllocatorsConstruct &x) {
-  auto &dirSpec{std::get<parser::OmpDirectiveSpecification>(x.t)};
+  const parser::OmpDirectiveSpecification &dirSpec{x.BeginDir()};
   PushContext(x.source, dirSpec.DirId());
 
   for (const auto &clause : dirSpec.Clauses().v) {
@@ -2287,7 +2295,7 @@ void OmpAttributeVisitor::Post(const parser::OpenMPExecutableAllocate &x) {
 }
 
 void OmpAttributeVisitor::Post(const parser::OpenMPAllocatorsConstruct &x) {
-  auto &dirSpec{std::get<parser::OmpDirectiveSpecification>(x.t)};
+  const parser::OmpDirectiveSpecification &dirSpec{x.BeginDir()};
   auto &block{std::get<parser::Block>(x.t)};
 
   omp::SourcedActionStmt action{omp::GetActionStmt(block)};
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index d08c669377cb2..6d3872c2198a5 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1484,18 +1484,18 @@ class OmpVisitor : public virtual DeclarationVisitor {
   }
   bool Pre(const parser::OpenMPBlockConstruct &);
   void Post(const parser::OpenMPBlockConstruct &);
-  bool Pre(const parser::OmpBeginBlockDirective &x) {
+  bool Pre(const parser::OmpBeginDirective &x) {
     AddOmpSourceRange(x.source);
     return true;
   }
-  void Post(const parser::OmpBeginBlockDirective &) {
+  void Post(const parser::OmpBeginDirective &) {
     messageHandler().set_currStmtSource(std::nullopt);
   }
-  bool Pre(const parser::OmpEndBlockDirective &x) {
+  bool Pre(const parser::OmpEndDirective &x) {
     AddOmpSourceRange(x.source);
     return true;
   }
-  void Post(const parser::OmpEndBlockDirective &) {
+  void Post(const parser::OmpEndDirective &) {
     messageHandler().set_currStmtSource(std::nullopt);
   }
 
@@ -1724,9 +1724,7 @@ class OmpVisitor : public virtual DeclarationVisitor {
 };
 
 bool OmpVisitor::NeedsScope(const parser::OpenMPBlockConstruct &x) {
-  const auto &beginBlockDir{std::get<parser::OmpBeginBlockDirective>(x.t)};
-  const auto &beginDir{std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
-  switch (beginDir.v) {
+  switch (x.BeginDir().DirId()) {
   case llvm::omp::Directive::OMPD_master:
   case llvm::omp::Directive::OMPD_ordered:
     return false;
diff --git a/flang/test/Parser/OpenMP/affinity-clause.f90 b/flang/test/Parser/OpenMP/affinity-clause.f90
index 642af6aeb7e49..0b96cae9e74a8 100644
--- a/flang/test/Parser/OpenMP/affinity-clause.f90
+++ b/flang/test/Parser/OpenMP/affinity-clause.f90
@@ -15,8 +15,8 @@ subroutine f00(x)
 !UNPARSE: !$OMP END TASK
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = task
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = task
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Affinity -> OmpAffinityClause
 !PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
 
@@ -34,8 +34,8 @@ subroutine f01(x)
 !UNPARSE: !$OMP END TASK
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = task
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = task
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Affinity -> OmpAffinityClause
 !PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> ArrayElement
 !PARSE-TREE: | | | DataRef -> Name = 'x'
@@ -60,8 +60,8 @@ subroutine f02(x)
 !UNPARSE: !$OMP END TASK
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = task
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = task
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Affinity -> OmpAffinityClause
 !PARSE-TREE: | | Modifier -> OmpIterator -> OmpIteratorSpecifier
 !PARSE-TREE: | | | TypeDeclarationStmt
diff --git a/flang/test/Parser/OpenMP/allocators-unparse.f90 b/flang/test/Parser/OpenMP/allocators-unparse.f90
index 70feb7a6b527e..079d6acf114d5 100644
--- a/flang/test/Parser/OpenMP/allocators-unparse.f90
+++ b/flang/test/Parser/OpenMP/allocators-unparse.f90
@@ -28,7 +28,7 @@ end subroutine allocate
 !CHECK-NEXT: ALLOCATE(arr2(5,3))
 
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAllocatorsConstruct
-!PARSE-TREE-NEXT: | OmpDirectiveSpecification
+!PARSE-TREE-NEXT: | OmpBeginDirective
 !PARSE-TREE-NEXT: | | OmpDirectiveName -> llvm::omp::Directive = allocators
 !PARSE-TREE-NEXT: | | OmpClauseList -> OmpClause -> Allocate -> OmpAllocateClause
 !PARSE-TREE-NEXT: | | | Modifier -> OmpAllocatorSimpleModifier -> Scalar -> Integer -> Expr -> Designator -> DataRef -> Name = 'omp_default_mem_alloc'
@@ -40,7 +40,7 @@ end subroutine allocate
 !PARSE-TREE-NEXT: | | | | AllocateObject -> Name = 'arr1'
 
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAllocatorsConstruct
-!PARSE-TREE-NEXT: | OmpDirectiveSpecification
+!PARSE-TREE-NEXT: | OmpBeginDirective
 !PARSE-TREE-NEXT: | | OmpDirectiveName -> llvm::omp::Directive = allocators
 !PARSE-TREE-NEXT: | | OmpClauseList -> OmpClause -> Allocate -> OmpAllocateClause
 !PARSE-TREE-NEXT: | | | Modifier -> OmpAllocatorComplexModifier -> Scalar -> Integer -> Expr -> Designator -> DataRef -> Name = 'omp_default_mem_alloc'
@@ -56,7 +56,7 @@ end subroutine allocate
 !PARSE-TREE-NEXT: | | | | AllocateObject -> Name = 'arr1'
 
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAllocatorsConstruct
-!PARSE-TREE-NEXT: | OmpDirectiveSpecification
+!PARSE-TREE-NEXT: | OmpBeginDirective
 !PARSE-TREE-NEXT: | | OmpDirectiveName -> llvm::omp::Directive = allocators
 !PARSE-TREE-NEXT: | | OmpClauseList -> OmpClause -> Allocate -> OmpAllocateClause
 !PARSE-TREE-NEXT: | | | Modifier -> OmpAlignModifier -> Scalar -> Integer -> Expr -> LiteralConstant -> IntLiteralConstant = '32'
@@ -70,7 +70,7 @@ end subroutine allocate
 !PARSE-TREE-NEXT: | | | | | Scalar -> Integer -> Expr -> LiteralConstant -> IntLiteralConstant = '5'
 !PARSE-TREE-NEXT: | | | | AllocateShapeSpec
 !PARSE-TREE-NEXT: | | | | | Scalar -> Integer -> Expr -> LiteralConstant -> IntLiteralConstant = '3'
-!PARSE-TREE-NEXT: | OmpDirectiveSpecification
+!PARSE-TREE-NEXT: | OmpEndDirective
 !PARSE-TREE-NEXT: | | OmpDirectiveName -> llvm::omp::Directive = allocators
 !PARSE-TREE-NEXT: | | OmpClauseList ->
 !PARSE-TREE-NEXT: | | Flags = None
diff --git a/flang/test/Parser/OpenMP/atomic-compare.f90 b/flang/test/Parser/OpenMP/atomic-compare.f90
index e09da4a359fcc..9b9c4f02df9c1 100644
--- a/flang/test/Parser/OpenMP/atomic-compare.f90
+++ b/flang/test/Parser/OpenMP/atomic-compare.f90
@@ -16,7 +16,7 @@ subroutine f00(a, b)
 !UNPARSE: END SUBROUTINE
 
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAtomicConstruct
-!PARSE-TREE: | OmpDirectiveSpecification
+!PARSE-TREE: | OmpBeginDirective
 !PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = atomic
 !PARSE-TREE: | | OmpClauseList -> OmpClause -> Update ->
 !PARSE-TREE: | | OmpClause -> Compare
@@ -54,7 +54,7 @@ subroutine f01(a, b)
 !UNPARSE: END SUBROUTINE
 
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAtomicConstruct
-!PARSE-TREE: | OmpDirectiveSpecification
+!PARSE-TREE: | OmpBeginDirective
 !PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = atomic
 !PARSE-TREE: | | OmpClauseList -> OmpClause -> Update ->
 !PARSE-TREE: | | OmpClause -> Compare
@@ -108,7 +108,7 @@ subroutine f02(a, b)
 !PARSE-TREE: | | | Expr = 'a'
 !PARSE-TREE: | | | | Designator -> DataRef -> Name = 'a'
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAtomicConstruct
-!PARSE-TREE: | OmpDirectiveSpecification
+!PARSE-TREE: | OmpBeginDirective
 !PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = atomic
 !PARSE-TREE: | | OmpClauseList -> OmpClause -> Update ->
 !PARSE-TREE: | | OmpClause -> Compare
@@ -145,7 +145,7 @@ subroutine g00(a, b)
 !UNPARSE: END SUBROUTINE
 
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAtomicConstruct
-!PARSE-TREE: | OmpDirectiveSpecification
+!PARSE-TREE: | OmpBeginDirective
 !PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = atomic
 !PARSE-TREE: | | OmpClauseList -> OmpClause -> Update ->
 !PARSE-TREE: | | OmpClause -> Capture
@@ -169,7 +169,7 @@ subroutine g00(a, b)
 !PARSE-TREE: | | | | | Designator -> DataRef -> Name = 'x'
 !PARSE-TREE: | | | | Expr = 'b'
 !PARSE-TREE: | | | | | Designator -> DataRef -> Name = 'b'
-!PARSE-TREE: | OmpDirectiveSpecification
+!PARSE-TREE: | OmpEndDirective
 !PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = atomic
 !PARSE-TREE: | | OmpClauseList ->
 !PARSE-TREE: | | Flags = None
@@ -197,7 +197,7 @@ subroutine g01(a, b)
 !UNPARSE: END SUBROUTINE
 
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAtomicConstruct
-!PARSE-TREE: | OmpDirectiveSpecification
+!PARSE-TREE: | OmpBeginDirective
 !PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = atomic
 !PARSE-TREE: | | OmpClauseList -> OmpClause -> Update ->
 !PARSE-TREE: | | OmpClause -> Capture
@@ -224,7 +224,7 @@ subroutine g01(a, b)
 !PARSE-TREE: | | | | | Expr = 'b'
 !PARSE-TREE: | | | | | | Designator -> DataRef -> Name = 'b'
 !PARSE-TREE: | | | EndIfStmt ->
-!PARSE-TREE: | OmpDirectiveSpecification
+!PARSE-TREE: | OmpEndDirective
 !PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = atomic
 !PARSE-TREE: | | OmpClauseList ->
 !PARSE-TREE: | | Flags = None
@@ -254,7 +254,7 @@ subroutine g02(a, b)
 !UNPARSE: END SUBROUTINE
 
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAtomicConstruct
-!PARSE-TREE: | OmpDirectiveSpecification
+!PARSE-TREE: | OmpBeginDirective
 !PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = atomic
 !PARSE-TREE: | | OmpClauseList -> OmpClause -> Update ->
 !PARSE-TREE: | | OmpClause -> Capture
@@ -284,7 +284,7 @@ subroutine g02(a, b)
 !PARSE-TREE: | | | | | | Expr = 'x'
 !PARSE-TREE: | | | | | | | Designator -> DataRef -> Name = 'x'
 !PARSE-TREE: | | | EndIfStmt ->
-!PARSE-TREE: | OmpDirectiveSpecification
+!PARSE-TREE: | OmpEndDirective
 !PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = atomic
 !PARSE-TREE: | | OmpClauseList ->
 !PARSE-TREE: | | Flags = None
diff --git a/flang/test/Parser/OpenMP/atomic-end.f90 b/flang/test/Parser/OpenMP/atomic-end.f90
index e5eac87517b1e..b971bb6f3d1da 100644
--- a/flang/test/Parser/OpenMP/atomic-end.f90
+++ b/flang/test/Parser/OpenMP/atomic-end.f90
@@ -16,7 +16,7 @@ subroutine f00
 !UNPARSE: END SUBROUTINE
 
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAtomicConstruct
-!PARSE-TREE: | OmpDirectiveSpecification
+!PARSE-TREE: | OmpBeginDirective
 !PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = atomic
 !PARSE-TREE: | | OmpClauseList -> OmpClause -> Read
 !PARSE-TREE: | | Flags = None
@@ -26,7 +26,7 @@ subroutine f00
 !PARSE-TREE: | | | | Designator -> DataRef -> Name = 'v'
 !PARSE-TREE: | | | Expr = 'x'
 !PARSE-TREE: | | | | Designator -> DataRef -> Name = 'x'
-!PARSE-TREE: | OmpDirectiveSpecification
+!PARSE-TREE: | OmpEndDirective
 !PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = atomic
 !PARSE-TREE: | | OmpClauseList ->
 !PARSE-TREE: | | Flags = None
@@ -47,7 +47,7 @@ subroutine f01
 !UNPARSE: END SUBROUTINE
 
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAtomicConstruct
-!PARSE-TREE: | OmpDirectiveSpecification
+!PARSE-TREE: | OmpBeginDirective
 !PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = atomic
 !PARSE-TREE: | | OmpClauseList -> OmpClause -> Read
 !PARSE-TREE: | | Flags = None
@@ -57,7 +57,7 @@ subroutine f01
 !PARSE-TREE: | | | | Designator -> DataRef -> Name = 'v'
 !PARSE-TREE: | | | Expr = 'x'
 !PARSE-TREE: | | | | Designator -> DataRef -> Name = 'x'
-!PARSE-TREE: | OmpDirectiveSpecification
+!PARSE-TREE: | OmpEndDirective
 !PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = atomic
 !PARSE-TREE: | | OmpClauseList ->
 !PARSE-TREE: | | Flags = None
diff --git a/flang/test/Parser/OpenMP/block-construct.f90 b/flang/test/Parser/OpenMP/block-construct.f90
index 83f0f7f276631..ea425544a5530 100644
--- a/flang/test/Parser/OpenMP/block-construct.f90
+++ b/flang/test/Parser/OpenMP/block-construct.f90
@@ -20,8 +20,8 @@ subroutine f00(x, y)
 !UNPARSE: END SUBROUTINE
 
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPBlockConstruct
-!PARSE-TREE: | OmpBeginBlockDirective
-!PARSE-TREE: | | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: | OmpBeginDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | | OmpClauseList -> OmpClause -> Map -> OmpMapClause
 !PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
 !PARSE-TREE: | | | OmpObject -> Designator -> DataRef -> Name = 'y'
@@ -45,8 +45,8 @@ subroutine f00(x, y)
 !PARSE-TREE: | | | | | | LiteralConstant -> IntLiteralConstant = '2'
 !PARSE-TREE: | | | | | Expr = 'x'
 !PARSE-TREE: | | | | | | Designator -> DataRef -> Name = 'x'
-!PARSE-TREE: | OmpEndBlockDirective
-!PARSE-TREE: | | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: | OmpEndDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | | OmpClauseList ->
 
 
@@ -72,8 +72,8 @@ subroutine f01(x, y)
 !UNPARSE: END SUBROUTINE
 
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPBlockConstruct
-!PARSE-TREE: | OmpBeginBlockDirective
-!PARSE-TREE: | | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: | OmpBeginDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | | OmpClauseList -> OmpClause -> Map -> OmpMapClause
 !PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
 !PARSE-TREE: | | | OmpObject -> Designator -> DataRef -> Name = 'y'
@@ -129,8 +129,8 @@ subroutine f02(x, y)
 !UNPARSE: END SUBROUTINE
 
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPBlockConstruct
-!PARSE-TREE: | OmpBeginBlockDirective
-!PARSE-TREE: | | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: | OmpBeginDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | | OmpClauseList -> OmpClause -> Map -> OmpMapClause
 !PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
 !PARSE-TREE: | | | OmpObject -> Designator -> DataRef -> Name = 'y'
@@ -160,6 +160,6 @@ subroutine f02(x, y)
 !PARSE-TREE: | | | | | | | Expr = 'x'
 !PARSE-TREE: | | | | | | | | Designator -> DataRef -> Name = 'x'
 !PARSE-TREE: | | | EndBlockStmt ->
-!PARSE-TREE: | OmpEndBlockDirective
-!PARSE-TREE: | | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: | OmpEndDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | | OmpClauseList ->
diff --git a/flang/test/Parser/OpenMP/construct-prefix-conflict.f90 b/flang/test/Parser/OpenMP/construct-prefix-conflict.f90
index 678942afe1953..d6f5152b021f0 100644
--- a/flang/test/Parser/OpenMP/construct-prefix-conflict.f90
+++ b/flang/test/Parser/OpenMP/construct-prefix-conflict.f90
@@ -27,13 +27,13 @@ subroutine f00(x)
 !UNPARSE: END SUBROUTINE
 
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPBlockConstruct
-!PARSE-TREE: | OmpBeginBlockDirective
-!PARSE-TREE: | | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: | OmpBeginDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | | OmpClauseList ->
 !PARSE-TREE: | Block
 !PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPBlockConstruct
-!PARSE-TREE: | | | OmpBeginBlockDirective
-!PARSE-TREE: | | | | OmpBlockDirective -> llvm::omp::Directive = target data
+!PARSE-TREE: | | | OmpBeginDirective
+!PARSE-TREE: | | | | OmpDirectiveName -> llvm::omp::Directive = target data
 !PARSE-TREE: | | | | OmpClauseList -> OmpClause -> Map -> OmpMapClause
 !PARSE-TREE: | | | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
 !PARSE-TREE: | | | | | bool = 'true'
@@ -43,11 +43,11 @@ subroutine f00(x)
 !PARSE-TREE: | | | | | Expr -> Add
 !PARSE-TREE: | | | | | | Expr -> Designator -> DataRef -> Name = 'x'
 !PARSE-TREE: | | | | | | Expr -> LiteralConstant -> IntLiteralConstant = '1'
-!PARSE-TREE: | | | OmpEndBlockDirective
-!PARSE-TREE: | | | | OmpBlockDirective -> llvm::omp::Directive = target data
+!PARSE-TREE: | | | OmpEndDirective
+!PARSE-TREE: | | | | OmpDirectiveName -> llvm::omp::Directive = target data
 !PARSE-TREE: | | | | OmpClauseList ->
-!PARSE-TREE: | OmpEndBlockDirective
-!PARSE-TREE: | | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: | OmpEndDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | | OmpClauseList ->
 
 
@@ -70,8 +70,8 @@ subroutine f01(x)
 !UNPARSE: END SUBROUTINE
 
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPBlockConstruct
-!PARSE-TREE: | OmpBeginBlockDirective
-!PARSE-TREE: | | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: | OmpBeginDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | | OmpClauseList ->
 !PARSE-TREE: | Block
 !PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPSimpleStandaloneConstruct -> OmpDirectiveSpecification
@@ -85,8 +85,8 @@ subroutine f01(x)
 !PARSE-TREE: | | | Expr -> Add
 !PARSE-TREE: | | | | Expr -> Designator -> DataRef -> Name = 'x'
 !PARSE-TREE: | | | | Expr -> LiteralConstant -> IntLiteralConstant = '1'
-!PARSE-TREE: | OmpEndBlockDirective
-!PARSE-TREE: | | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: | OmpEndDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | | OmpClauseList ->
 
 
@@ -109,8 +109,8 @@ subroutine f02(x)
 !UNPARSE: END SUBROUTINE
 
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPBlockConstruct
-!PARSE-TREE: | OmpBeginBlockDirective
-!PARSE-TREE: | | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: | OmpBeginDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | | OmpClauseList ->
 !PARSE-TREE: | Block
 !PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPSimpleStandaloneConstruct -> OmpDirectiveSpecification
@@ -124,8 +124,8 @@ subroutine f02(x)
 !PARSE-TREE: | | | Expr -> Add
 !PARSE-TREE: | | | | Expr -> Designator -> DataRef -> Name = 'x'
 !PARSE-TREE: | | | | Expr -> LiteralConstant -> IntLiteralConstant = '1'
-!PARSE-TREE: | OmpEndBlockDirective
-!PARSE-TREE: | | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: | OmpEndDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | | OmpClauseList ->
 
 
@@ -148,8 +148,8 @@ subroutine f03(x)
 !UNPARSE: END SUBROUTINE
 
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPBlockConstruct
-!PARSE-TREE: | OmpBeginBlockDirective
-!PARSE-TREE: | | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: | OmpBeginDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | | OmpClauseList ->
 !PARSE-TREE: | Block
 !PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPSimpleStandaloneConstruct -> OmpDirectiveSpecification
@@ -163,6 +163,6 @@ subroutine f03(x)
 !PARSE-TREE: | | | Expr -> Add
 !PARSE-TREE: | | | | Expr -> Designator -> DataRef -> Name = 'x'
 !PARSE-TREE: | | | | Expr -> LiteralConstant -> IntLiteralConstant = '1'
-!PARSE-TREE: | OmpEndBlockDirective
-!PARSE-TREE: | | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: | OmpEndDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | | OmpClauseList ->
diff --git a/flang/test/Parser/OpenMP/defaultmap-clause.f90 b/flang/test/Parser/OpenMP/defaultmap-clause.f90
index d908258fac763..e7825e5b7a532 100644
--- a/flang/test/Parser/OpenMP/defaultmap-clause.f90
+++ b/flang/test/Parser/OpenMP/defaultmap-clause.f90
@@ -11,8 +11,8 @@ subroutine f00
 !UNPARSE: !$OMP END TARGET
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Defaultmap -> OmpDefaultmapClause
 !PARSE-TREE: | | ImplicitBehavior = From
 !PARSE-TREE: Block
@@ -27,8 +27,8 @@ subroutine f01
 !UNPARSE: !$OMP END TARGET
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Defaultmap -> OmpDefaultmapClause
 !PARSE-TREE: | | ImplicitBehavior = Firstprivate
 !PARSE-TREE: | | Modifier -> OmpVariableCategory -> Value = Aggregate
@@ -43,8 +43,8 @@ subroutine f02
 !UNPARSE: !$OMP END TARGET
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Defaultmap -> OmpDefaultmapClause
 !PARSE-TREE: | | ImplicitBehavior = Alloc
 !PARSE-TREE: | | Modifier -> OmpVariableCategory -> Value = All
@@ -61,8 +61,8 @@ subroutine f03
 !UNPARSE: !$OMP END TARGET
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Defaultmap -> OmpDefaultmapClause
 !PARSE-TREE: | | ImplicitBehavior = Alloc
 !PARSE-TREE: | | Modifier -> OmpVariableCategory -> Value = Allocatable
@@ -77,8 +77,8 @@ subroutine f04
 !UNPARSE: !$OMP END TARGET
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Defaultmap -> OmpDefaultmapClause
 !PARSE-TREE: | | ImplicitBehavior = Tofrom
 !PARSE-TREE: | | Modifier -> OmpVariableCategory -> Value  = Scalar
@@ -93,8 +93,8 @@ subroutine f05
 !UNPARSE: !$OMP END TARGET
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Defaultmap -> OmpDefaultmapClause
 !PARSE-TREE: | | ImplicitBehavior = Present
 !PARSE-TREE: | | Modifier -> OmpVariableCategory -> Value  = Scalar
diff --git a/flang/test/Parser/OpenMP/defaultmap-unparse.f90 b/flang/test/Parser/OpenMP/defaultmap-unparse.f90
index bbbb6fc938326..fa0578014071f 100644
--- a/flang/test/Parser/OpenMP/defaultmap-unparse.f90
+++ b/flang/test/Parser/OpenMP/defaultmap-unparse.f90
@@ -34,8 +34,8 @@ program main
 !CHECK: !$omp end target
   !$omp end target
 
-!PARSE-TREE:      OmpBeginBlockDirective
-!PARSE-TREE:        OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE:      OmpBeginDirective
+!PARSE-TREE:        OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE:        OmpClauseList -> OmpClause -> Defaultmap -> OmpDefaultmapClause
 !PARSE-TREE:          ImplicitBehavior = Tofrom
 !PARSE-TREE:          Modifier -> OmpVariableCategory -> Value = Scalar
@@ -46,8 +46,8 @@ program main
 !CHECK: !$omp end target
   !$omp end target
 
-!PARSE-TREE:      OmpBeginBlockDirective
-!PARSE-TREE:        OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE:      OmpBeginDirective
+!PARSE-TREE:        OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE:        OmpClauseList -> OmpClause -> Defaultmap -> OmpDefaultmapClause
 !PARSE-TREE:          ImplicitBehavior = Alloc
 !PARSE-TREE:          Modifier -> OmpVariableCategory -> Value = Scalar
@@ -58,8 +58,8 @@ program main
 !CHECK: !$omp end target
   !$omp end target
 
-!PARSE-TREE:      OmpBeginBlockDirective
-!PARSE-TREE:        OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE:      OmpBeginDirective
+!PARSE-TREE:        OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE:        OmpClauseList -> OmpClause -> Defaultmap -> OmpDefaultmapClause
 !PARSE-TREE:          ImplicitBehavior = None
 
@@ -69,8 +69,8 @@ program main
 !CHECK: !$omp end target 
   !$omp end target
 
-!PARSE-TREE:      OmpBeginBlockDirective
-!PARSE-TREE:        OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE:      OmpBeginDirective
+!PARSE-TREE:        OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE:        OmpClauseList -> OmpClause -> Defaultmap -> OmpDefaultmapClause
 !PARSE-TREE:          ImplicitBehavior = None
 !PARSE-TREE:          Modifier -> OmpVariableCategory -> Value = Scalar
@@ -81,8 +81,8 @@ program main
 !CHECK: !$omp end target
   !$omp end target
 
-!PARSE-TREE:      OmpBeginBlockDirective
-!PARSE-TREE:        OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE:      OmpBeginDirective
+!PARSE-TREE:        OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE:        OmpClauseList -> OmpClause -> Defaultmap -> OmpDefaultmapClause
 !PARSE-TREE:          ImplicitBehavior = To
 !PARSE-TREE:          Modifier -> OmpVariableCategory -> Value = Scalar
@@ -93,8 +93,8 @@ program main
 !CHECK: !$omp end target
   !$omp end target
 
-!PARSE-TREE:      OmpBeginBlockDirective
-!PARSE-TREE:        OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE:      OmpBeginDirective
+!PARSE-TREE:        OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE:        OmpClauseList -> OmpClause -> Defaultmap -> OmpDefaultmapClause
 !PARSE-TREE:          ImplicitBehavior = Firstprivate
 !PARSE-TREE:          Modifier -> OmpVariableCategory -> Value = Scalar
@@ -108,8 +108,8 @@ program main
 !CHECK: !$omp end target
   !$omp end target
 
-!PARSE-TREE:      OmpBeginBlockDirective
-!PARSE-TREE:        OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE:      OmpBeginDirective
+!PARSE-TREE:        OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE:        OmpClauseList -> OmpClause -> Defaultmap -> OmpDefaultmapClause
 !PARSE-TREE:          ImplicitBehavior = Tofrom
 !PARSE-TREE:          Modifier -> OmpVariableCategory -> Value = Aggregate
@@ -120,8 +120,8 @@ program main
 !CHECK: !$omp end target
   !$omp end target
 
-!PARSE-TREE:      OmpBeginBlockDirective
-!PARSE-TREE:        OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE:      OmpBeginDirective
+!PARSE-TREE:        OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE:        OmpClauseList -> OmpClause -> Defaultmap -> OmpDefaultmapClause
 !PARSE-TREE:          ImplicitBehavior = Tofrom
 !PARSE-TREE:          Modifier -> OmpVariableCategory -> Value = Allocatable
@@ -134,8 +134,8 @@ program main
 !CHECK: !$omp end target
   !$omp end target 
 
-!PARSE-TREE:      OmpBeginBlockDirective
-!PARSE-TREE:        OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE:      OmpBeginDirective
+!PARSE-TREE:        OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE:        OmpClauseList -> OmpClause -> Defaultmap -> OmpDefaultmapClause
 !PARSE-TREE:          ImplicitBehavior = Default
 !PARSE-TREE:          Modifier -> OmpVariableCategory -> Value = Pointer
diff --git a/flang/test/Parser/OpenMP/dispatch.f90 b/flang/test/Parser/OpenMP/dispatch.f90
index 4076c00331225..131b4d1f9ddb6 100644
--- a/flang/test/Parser/OpenMP/dispatch.f90
+++ b/flang/test/Parser/OpenMP/dispatch.f90
@@ -18,7 +18,7 @@ subroutine sub(x)
 !UNPARSE: !$OMP END DISPATCH
 
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPDispatchConstruct
-!PARSE-TREE: | OmpDirectiveSpecification
+!PARSE-TREE: | OmpBeginDirective
 !PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = dispatch
 !PARSE-TREE: | | OmpClauseList -> OmpClause -> Device -> OmpDeviceClause
 !PARSE-TREE: | | | Scalar -> Integer -> Expr = '3_4'
@@ -37,7 +37,7 @@ subroutine sub(x)
 !PARSE-TREE: | Block
 !PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt
 ![...]
-!PARSE-TREE: | OmpDirectiveSpecification
+!PARSE-TREE: | OmpEndDirective
 !PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = dispatch
 !PARSE-TREE: | | OmpClauseList ->
 !PARSE-TREE: | | Flags = None
@@ -51,7 +51,7 @@ subroutine sub(x)
 !UNPARSE:   r=func(a+1_4,b+2_4,c+3_4)
 
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPDispatchConstruct
-!PARSE-TREE: | OmpDirectiveSpecification
+!PARSE-TREE: | OmpBeginDirective
 !PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = dispatch
 !PARSE-TREE: | | OmpClauseList -> OmpClause -> Device -> OmpDeviceClause
 !PARSE-TREE: | | | Scalar -> Integer -> Expr = '3_4'
@@ -60,7 +60,7 @@ subroutine sub(x)
 !PARSE-TREE: | | Flags = None
 !PARSE-TREE: | Block
 !PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt
-!PARSE-TREE-NOT: OmpDirectiveSpecification
+!PARSE-TREE-NOT: OmpEndDirective
 
   !$omp dispatch device(3) is_device_ptr(x)
   r = func(a+1, b+2, c+3)
diff --git a/flang/test/Parser/OpenMP/if-clause.f90 b/flang/test/Parser/OpenMP/if-clause.f90
index e47fbde2646d3..2bf80cb99f919 100644
--- a/flang/test/Parser/OpenMP/if-clause.f90
+++ b/flang/test/Parser/OpenMP/if-clause.f90
@@ -24,7 +24,7 @@ program openmp_parse_if
   ! CHECK-NEXT: OmpDirectiveName -> llvm::omp::Directive = target exit data
   !$omp target exit data map(from: i) if(target exit data: cond)
 
-  ! CHECK: OmpBlockDirective -> llvm::omp::Directive = target data
+  ! CHECK: OmpDirectiveName -> llvm::omp::Directive = target data
   ! CHECK: OmpClause -> If -> OmpIfClause
   ! CHECK-NEXT: OmpDirectiveName -> llvm::omp::Directive = target data
   !$omp target data map(tofrom: i) if(target data: cond)
@@ -45,7 +45,7 @@ program openmp_parse_if
   end do
   !$omp end target teams distribute parallel do simd
 
-  ! CHECK: OmpBlockDirective -> llvm::omp::Directive = task
+  ! CHECK: OmpDirectiveName -> llvm::omp::Directive = task
   ! CHECK-NEXT: OmpClause -> If -> OmpIfClause
   ! CHECK-NEXT: OmpDirectiveName -> llvm::omp::Directive = task
   !$omp task if(task: cond)
diff --git a/flang/test/Parser/OpenMP/in-reduction-clause.f90 b/flang/test/Parser/OpenMP/in-reduction-clause.f90
index bb3fadbc5088e..ee59069436a29 100644
--- a/flang/test/Parser/OpenMP/in-reduction-clause.f90
+++ b/flang/test/Parser/OpenMP/in-reduction-clause.f90
@@ -29,13 +29,13 @@ subroutine omp_in_reduction_taskgroup()
 end subroutine omp_in_reduction_taskgroup
 
 !PARSE-TREE: OpenMPConstruct -> OpenMPBlockConstruct
-!PARSE-TREE-NEXT: OmpBeginBlockDirective
-!PARSE-TREE-NEXT: OmpBlockDirective -> llvm::omp::Directive = taskgroup
+!PARSE-TREE-NEXT: OmpBeginDirective
+!PARSE-TREE-NEXT: OmpDirectiveName -> llvm::omp::Directive = taskgroup
 !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> TaskReduction -> OmpTaskReductionClause
 
 !PARSE-TREE: OpenMPConstruct -> OpenMPBlockConstruct
-!PARSE-TREE-NEXT: OmpBeginBlockDirective
-!PARSE-TREE-NEXT: OmpBlockDirective -> llvm::omp::Directive = task
+!PARSE-TREE-NEXT: OmpBeginDirective
+!PARSE-TREE-NEXT: OmpDirectiveName -> llvm::omp::Directive = task
 !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> InReduction -> OmpInReductionClause
 !PARSE-TREE-NEXT: OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add
 !PARSE-TREE-NEXT: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'z'
@@ -66,8 +66,8 @@ subroutine omp_in_reduction_parallel()
 end subroutine omp_in_reduction_parallel
 
 !PARSE-TREE: OpenMPConstruct -> OpenMPBlockConstruct
-!PARSE-TREE-NEXT: OmpBeginBlockDirective
-!PARSE-TREE-NEXT: OmpBlockDirective -> llvm::omp::Directive = parallel
+!PARSE-TREE-NEXT: OmpBeginDirective
+!PARSE-TREE-NEXT: OmpDirectiveName -> llvm::omp::Directive = parallel
 !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause
 
 !PARSE-TREE: OpenMPConstruct -> OpenMPLoopConstruct
diff --git a/flang/test/Parser/OpenMP/map-modifiers-v60.f90 b/flang/test/Parser/OpenMP/map-modifiers-v60.f90
index bc80886780d46..46d57a0700390 100644
--- a/flang/test/Parser/OpenMP/map-modifiers-v60.f90
+++ b/flang/test/Parser/OpenMP/map-modifiers-v60.f90
@@ -15,8 +15,8 @@ subroutine f00(x)
 !UNPARSE: !$OMP END TARGET
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
 !PARSE-TREE: | | Modifier -> OmpAlwaysModifier -> Value = Always
 !PARSE-TREE: | | Modifier -> OmpCloseModifier -> Value = Close
@@ -38,8 +38,8 @@ subroutine f01(x)
 !UNPARSE: !$OMP END TARGET
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
 !PARSE-TREE: | | Modifier -> OmpSelfModifier -> Value = Self
 !PARSE-TREE: | | Modifier -> OmpMapType -> Value = Storage
@@ -60,8 +60,8 @@ subroutine f02(x)
 !UNPARSE: !$OMP END TARGET
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
 !PARSE-TREE: | | Modifier -> OmpRefModifier -> Value = Ref_Ptr
 !PARSE-TREE: | | Modifier -> OmpMapType -> Value = To
@@ -82,8 +82,8 @@ subroutine f03(x)
 !UNPARSE: !$OMP END TARGET
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
 !PARSE-TREE: | | Modifier -> OmpRefModifier -> Value = Ref_Ptee
 !PARSE-TREE: | | Modifier -> OmpMapType -> Value = To
@@ -104,8 +104,8 @@ subroutine f04(x)
 !UNPARSE: !$OMP END TARGET
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
 !PARSE-TREE: | | Modifier -> OmpRefModifier -> Value = Ref_Ptr_Ptee
 !PARSE-TREE: | | Modifier -> OmpMapType -> Value = To
diff --git a/flang/test/Parser/OpenMP/map-modifiers.f90 b/flang/test/Parser/OpenMP/map-modifiers.f90
index 4e034e51352e4..83662b70f08f5 100644
--- a/flang/test/Parser/OpenMP/map-modifiers.f90
+++ b/flang/test/Parser/OpenMP/map-modifiers.f90
@@ -15,8 +15,8 @@ subroutine f00(x)
 !UNPARSE: !$OMP END TARGET
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
 !PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Ompx_Hold
 !PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Always
@@ -40,8 +40,8 @@ subroutine f01(x)
 !UNPARSE: !$OMP END TARGET
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
 !PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Ompx_Hold
 !PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Always
@@ -64,8 +64,8 @@ subroutine f02(x)
 !UNPARSE: !$OMP END TARGET
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
 !PARSE-TREE: | | Modifier -> OmpMapType -> Value = From
 !PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
@@ -85,8 +85,8 @@ subroutine f03(x)
 !UNPARSE: !$OMP END TARGET
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
 !PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
 !PARSE-TREE: | | bool = 'true'
@@ -105,8 +105,8 @@ subroutine f04(x)
 !UNPARSE: !$OMP END TARGET
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
 !PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Ompx_Hold
 !PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Always
@@ -130,8 +130,8 @@ subroutine f05(x)
 !UNPARSE: !$OMP END TARGET
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
 !PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Ompx_Hold
 !PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Always
@@ -155,8 +155,8 @@ subroutine f10(x)
 !UNPARSE: !$OMP END TARGET
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
 !PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Present
 !PARSE-TREE: | | Modifier -> OmpIterator -> OmpIteratorSpecifier
@@ -190,8 +190,8 @@ subroutine f11(x)
 !UNPARSE: !$OMP END TARGET
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
 !PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Present
 !PARSE-TREE: | | Modifier -> OmpIterator -> OmpIteratorSpecifier
@@ -225,8 +225,8 @@ subroutine f12(x)
 !UNPARSE: !$OMP END TARGET
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
 !PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Present
 !PARSE-TREE: | | Modifier -> OmpIterator -> OmpIteratorSpecifier
@@ -283,8 +283,8 @@ subroutine f20(x, y)
 !UNPARSE: !$OMP END TARGET
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
 !PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Present
 !PARSE-TREE: | | Modifier -> OmpIterator -> OmpIteratorSpecifier
@@ -334,8 +334,8 @@ subroutine f21(x, y)
 !UNPARSE: !$OMP END TARGET
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
 !PARSE-TREE: | | Modifier -> OmpMapper -> Name = 'xx'
 !PARSE-TREE: | | Modifier -> OmpMapType -> Value = From
@@ -355,7 +355,7 @@ subroutine f22(x)
 !UNPARSE: !$OMP END TARGET
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: OmpClauseList -> OmpClause -> Map -> OmpMapClause
 !PARSE-TREE: | Modifier -> OmpMapTypeModifier -> Value = Present
 !PARSE-TREE: | Modifier -> OmpIterator -> OmpIteratorSpecifier
diff --git a/flang/test/Parser/OpenMP/masked-unparse.f90 b/flang/test/Parser/OpenMP/masked-unparse.f90
index 16d7ca68e3e18..46ddd3722216a 100644
--- a/flang/test/Parser/OpenMP/masked-unparse.f90
+++ b/flang/test/Parser/OpenMP/masked-unparse.f90
@@ -6,14 +6,14 @@
 
 subroutine test_masked()
   integer :: c = 1
-  !PARSE-TREE: OmpBeginBlockDirective
-  !PARSE-TREE-NEXT: OmpBlockDirective -> llvm::omp::Directive = masked
+  !PARSE-TREE: OmpBeginDirective
+  !PARSE-TREE-NEXT: OmpDirectiveName -> llvm::omp::Directive = masked
   !CHECK: !$omp masked
   !$omp masked 
   c = c + 1
   !$omp end masked
-  !PARSE-TREE: OmpBeginBlockDirective
-  !PARSE-TREE-NEXT: OmpBlockDirective -> llvm::omp::Directive = masked
+  !PARSE-TREE: OmpBeginDirective
+  !PARSE-TREE-NEXT: OmpDirectiveName -> llvm::omp::Directive = masked
   !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Filter -> Scalar -> Integer -> Expr = '1_4'
   !PARSE-TREE-NEXT: LiteralConstant -> IntLiteralConstant = '1'
   !CHECK: !$omp masked filter(1_4)
@@ -51,8 +51,8 @@ subroutine test_masked_taskloop
 subroutine test_parallel_masked
   integer, parameter :: i = 1, j = 1
   integer :: c = 2
-  !PARSE-TREE: OmpBeginBlockDirective
-  !PARSE-TREE-NEXT: OmpBlockDirective -> llvm::omp::Directive = parallel masked
+  !PARSE-TREE: OmpBeginDirective
+  !PARSE-TREE-NEXT: OmpDirectiveName -> llvm::omp::Directive = parallel masked
   !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Filter -> Scalar -> Integer -> Expr = '2_4'
   !PARSE-TREE-NEXT: Add
   !PARSE-TREE-NEXT: Expr = '1_4'
diff --git a/flang/test/Parser/OpenMP/master-unparse.f90 b/flang/test/Parser/OpenMP/master-unparse.f90
index 30c293a521b5d..ec7a7d3845014 100644
--- a/flang/test/Parser/OpenMP/master-unparse.f90
+++ b/flang/test/Parser/OpenMP/master-unparse.f90
@@ -6,8 +6,8 @@
 
 subroutine test_master()
   integer :: c = 1
-  !PARSE-TREE: OmpBeginBlockDirective
-  !PARSE-TREE-NEXT: OmpBlockDirective -> llvm::omp::Directive = master
+  !PARSE-TREE: OmpBeginDirective
+  !PARSE-TREE-NEXT: OmpDirectiveName -> llvm::omp::Directive = master
   !CHECK: !$omp master
   !$omp master 
   c = c + 1
@@ -40,8 +40,8 @@ subroutine test_master_taskloop
 
 subroutine test_parallel_master
   integer :: c = 2
-  !PARSE-TREE: OmpBeginBlockDirective
-  !PARSE-TREE-NEXT: OmpBlockDirective -> llvm::omp::Directive = parallel master
+  !PARSE-TREE: OmpBeginDirective
+  !PARSE-TREE-NEXT: OmpDirectiveName -> llvm::omp::Directive = parallel master
   !CHECK: !$omp parallel master
   !$omp parallel master
   c = c + 2
diff --git a/flang/test/Parser/OpenMP/openmp6-directive-spellings.f90 b/flang/test/Parser/OpenMP/openmp6-directive-spellings.f90
index 6a1d565451220..69a0de656e4d5 100644
--- a/flang/test/Parser/OpenMP/openmp6-directive-spellings.f90
+++ b/flang/test/Parser/OpenMP/openmp6-directive-spellings.f90
@@ -170,14 +170,14 @@ subroutine f06
 !UNPARSE: SUBROUTINE f06
 !UNPARSE:  IMPLICIT NONE
 !UNPARSE:  INTEGER i
-!UNPARSE: !$OMP TARGET DATA  MAP(TOFROM: i)
+!UNPARSE: !$OMP TARGET_DATA MAP(TOFROM: i)
 !UNPARSE:   i=0_4
-!UNPARSE: !$OMP END TARGET DATA
+!UNPARSE: !$OMP END TARGET_DATA
 !UNPARSE: END SUBROUTINE
 
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPBlockConstruct
-!PARSE-TREE: | OmpBeginBlockDirective
-!PARSE-TREE: | | OmpBlockDirective -> llvm::omp::Directive = target data
+!PARSE-TREE: | OmpBeginDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = target data
 !PARSE-TREE: | | OmpClauseList -> OmpClause -> Map -> OmpMapClause
 !PARSE-TREE: | | | Modifier -> OmpMapType -> Value = Tofrom
 !PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'i'
@@ -188,8 +188,8 @@ subroutine f06
 !PARSE-TREE: | | | | Designator -> DataRef -> Name = 'i'
 !PARSE-TREE: | | | Expr = '0_4'
 !PARSE-TREE: | | | | LiteralConstant -> IntLiteralConstant = '0'
-!PARSE-TREE: | OmpEndBlockDirective
-!PARSE-TREE: | | OmpBlockDirective -> llvm::omp::Directive = target data
+!PARSE-TREE: | OmpEndDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = target data
 !PARSE-TREE: | | OmpClauseList ->
 
 subroutine f07
diff --git a/flang/test/Parser/OpenMP/proc-bind.f90 b/flang/test/Parser/OpenMP/proc-bind.f90
index 3115b3771f27d..98ce39e4db911 100644
--- a/flang/test/Parser/OpenMP/proc-bind.f90
+++ b/flang/test/Parser/OpenMP/proc-bind.f90
@@ -4,8 +4,8 @@
 ! CHECK: !$OMP PARALLEL  PROC_BIND(PRIMARY)
 
 ! PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPBlockConstruct
-! PARSE-TREE:  OmpBeginBlockDirective
-! PARSE-TREE:   OmpBlockDirective -> llvm::omp::Directive = parallel
+! PARSE-TREE:  OmpBeginDirective
+! PARSE-TREE:   OmpDirectiveName -> llvm::omp::Directive = parallel
 ! PARSE-TREE:   OmpClauseList -> OmpClause -> ProcBind -> OmpProcBindClause -> AffinityPolicy = Primary
 subroutine sb1
   !$omp parallel proc_bind(primary)
diff --git a/flang/test/Parser/OpenMP/scope.f90 b/flang/test/Parser/OpenMP/scope.f90
index 6574136311e71..9e046d69f351e 100644
--- a/flang/test/Parser/OpenMP/scope.f90
+++ b/flang/test/Parser/OpenMP/scope.f90
@@ -9,13 +9,13 @@ program omp_scope
 !CHECK: !$OMP END SCOPE
 
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPBlockConstruct
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = scope
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = scope
 !PARSE-TREE: OmpClauseList -> OmpClause -> Private -> OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'i'
 !PARSE-TREE: Block
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> PrintStmt
-!PARSE-TREE: OmpEndBlockDirective
-!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = scope
+!PARSE-TREE: OmpEndDirective
+!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = scope
 !PARSE-TREE: OmpClauseList -> OmpClause -> Nowait
 
   !$omp scope private(i)
diff --git a/flang/test/Parser/OpenMP/target_device_parse.f90 b/flang/test/Parser/OpenMP/target_device_parse.f90
index 7f5bee3793b2e..d3c9c692adcd4 100644
--- a/flang/test/Parser/OpenMP/target_device_parse.f90
+++ b/flang/test/Parser/OpenMP/target_device_parse.f90
@@ -20,13 +20,13 @@ PROGRAM main
 !CHECK: !$OMP END TARGET
 !$OMP END TARGET
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: OmpClauseList -> OmpClause -> Device -> OmpDeviceClause
 !PARSE-TREE: Scalar -> Integer -> Expr = '1_4'
 !PARSE-TREE: LiteralConstant -> IntLiteralConstant = '1'
-!PARSE-TREE: OmpEndBlockDirective
-!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpEndDirective
+!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: OmpClauseList ->
 
 !------------------------------------------------------
@@ -38,8 +38,8 @@ PROGRAM main
 !CHECK: !$OMP END TARGET
 !$OMP END TARGET
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: OmpClauseList -> OmpClause -> Device -> OmpDeviceClause
 !PARSE-TREE: Scalar -> Integer -> Expr = '1_4'
 !PARSE-TREE: Subtract
@@ -47,8 +47,8 @@ PROGRAM main
 !PARSE-TREE: LiteralConstant -> IntLiteralConstant = '2'
 !PARSE-TREE: Expr = '1_4'
 !PARSE-TREE: LiteralConstant -> IntLiteralConstant = '1'
-!PARSE-TREE: OmpEndBlockDirective
-!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpEndDirective
+!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: OmpClauseList ->
 
 
@@ -61,13 +61,13 @@ PROGRAM main
 !CHECK: !$OMP END TARGET
 !$OMP END TARGET
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: OmpClauseList -> OmpClause -> Device -> OmpDeviceClause
 !PARSE-TREE: Scalar -> Integer -> Expr = 'x'
 !PARSE-TREE: Designator -> DataRef -> Name = 'x'
-!PARSE-TREE: OmpEndBlockDirective
-!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpEndDirective
+!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: OmpClauseList ->
 
 
@@ -80,8 +80,8 @@ PROGRAM main
 !CHECK: !$OMP END TARGET
 !$OMP END TARGET
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: OmpClauseList -> OmpClause -> Device -> OmpDeviceClause
 !PARSE-TREE: Scalar -> Integer -> Expr = 'x+y'
 !PARSE-TREE: Add
@@ -89,8 +89,8 @@ PROGRAM main
 !PARSE-TREE: Designator -> DataRef -> Name = 'x'
 !PARSE-TREE: Expr = 'y'
 !PARSE-TREE: Designator -> DataRef -> Name = 'y'
-!PARSE-TREE: OmpEndBlockDirective
-!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpEndDirective
+!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: OmpClauseList ->
 
 !------------------------------------------------------
@@ -102,14 +102,14 @@ PROGRAM main
 !CHECK: !$OMP END TARGET
 !$OMP END TARGET
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: OmpClauseList -> OmpClause -> Device -> OmpDeviceClause
 !PARSE-TREE: OmpDeviceModifier -> Value = Ancestor
 !PARSE-TREE: Scalar -> Integer -> Expr = '1_4'
 !PARSE-TREE: LiteralConstant -> IntLiteralConstant = '1'
-!PARSE-TREE: OmpEndBlockDirective
-!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpEndDirective
+!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: OmpClauseList ->
 
 
@@ -122,14 +122,14 @@ PROGRAM main
 !CHECK: !$OMP END TARGET
 !$OMP END TARGET
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: OmpClauseList -> OmpClause -> Device -> OmpDeviceClause
 !PARSE-TREE: OmpDeviceModifier -> Value = Device_Num
 !PARSE-TREE: Scalar -> Integer -> Expr = '2_4'
 !PARSE-TREE: LiteralConstant -> IntLiteralConstant = '2'
-!PARSE-TREE: OmpEndBlockDirective
-!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpEndDirective
+!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: OmpClauseList ->
 
 
@@ -142,8 +142,8 @@ PROGRAM main
 !CHECK: !$OMP END TARGET
 !$OMP END TARGET
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: OmpClauseList -> OmpClause -> Device -> OmpDeviceClause
 !PARSE-TREE: OmpDeviceModifier -> Value = Ancestor
 !PARSE-TREE: Scalar -> Integer -> Expr = 'x+y'
@@ -152,8 +152,8 @@ PROGRAM main
 !PARSE-TREE: Designator -> DataRef -> Name = 'x'
 !PARSE-TREE: Expr = 'y'
 !PARSE-TREE: Designator -> DataRef -> Name = 'y'
-!PARSE-TREE: OmpEndBlockDirective
-!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpEndDirective
+!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: OmpClauseList ->
 
 
@@ -166,8 +166,8 @@ PROGRAM main
 !CHECK: !$OMP END TARGET
 !$OMP END TARGET
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = target
 !PARSE-TREE: OmpClauseList -> OmpClause -> Device -> OmpDeviceClause
 !PARSE-TREE: OmpDeviceModifier -> Value = Device_Num
 !PARSE-TREE: Scalar -> Integer -> Expr = 'x-y'
@@ -176,6 +176,6 @@ PROGRAM main
 !PARSE-TREE: Designator -> DataRef -> Name = 'x'
 !PARSE-TREE: Expr = 'y'
 !PARSE-TREE: Designator -> DataRef -> Name = 'y'
-!PARSE-TREE: OmpEndBlockDirective
-!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpEndDirective
+!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = target
 END PROGRAM
diff --git a/flang/test/Parser/OpenMP/task-reduction-clause.f90 b/flang/test/Parser/OpenMP/task-reduction-clause.f90
index 248ff7918dbe5..e3e6962462a63 100644
--- a/flang/test/Parser/OpenMP/task-reduction-clause.f90
+++ b/flang/test/Parser/OpenMP/task-reduction-clause.f90
@@ -15,8 +15,8 @@ subroutine f00
 !UNPARSE: !$OMP END TASKGROUP
 !UNPARSE: END SUBROUTINE
 
-!PARSE-TREE: OmpBeginBlockDirective
-!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = taskgroup
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = taskgroup
 !PARSE-TREE: | OmpClauseList -> OmpClause -> TaskReduction -> OmpTaskReductionClause
 !PARSE-TREE: | | Modifier -> OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add
 !PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
diff --git a/flang/test/Parser/OpenMP/task.f90 b/flang/test/Parser/OpenMP/task.f90
index 706deb3451f98..d6508df9e978a 100644
--- a/flang/test/Parser/OpenMP/task.f90
+++ b/flang/test/Parser/OpenMP/task.f90
@@ -2,7 +2,7 @@
 ! RUN: %flang_fc1 %openmp_flags -fdebug-dump-parse-tree -fopenmp -fopenmp-version=50  %s | FileCheck --ignore-case %s
 ! RUN: %flang_fc1 %openmp_flags -fdebug-unparse -fopenmp -fopenmp-version=50  %s | FileCheck --ignore-case --check-prefix="CHECK-UNPARSE" %s
 
-!CHECK: OmpBlockDirective -> llvm::omp::Directive = task
+!CHECK: OmpDirectiveName -> llvm::omp::Directive = task
 !CHECK: OmpClauseList -> OmpClause -> Detach -> OmpDetachClause -> OmpObject -> Designator -> DataRef -> Name = 'event'
 
 !CHECK-UNPARSE: INTEGER(KIND=8_4) event
diff --git a/flang/test/Semantics/OpenMP/clause-validity01.f90 b/flang/test/Semantics/OpenMP/clause-validity01.f90
index bc1371847b792..e725e2670e8dc 100644
--- a/flang/test/Semantics/OpenMP/clause-validity01.f90
+++ b/flang/test/Semantics/OpenMP/clause-validity01.f90
@@ -163,8 +163,7 @@
   !$omp parallel
   do i = 1, N
   enddo
-  !ERROR: Unmatched END TARGET directive
-  !$omp end target
+  !$omp end parallel
 
   ! OMP 5.0 - 2.6 Restriction point 1
   outofparallel: do k =1, 10
diff --git a/flang/test/Semantics/OpenMP/symbol08.f90 b/flang/test/Semantics/OpenMP/symbol08.f90
index 545bccc86b068..bf0f724669fa2 100644
--- a/flang/test/Semantics/OpenMP/symbol08.f90
+++ b/flang/test/Semantics/OpenMP/symbol08.f90
@@ -130,8 +130,7 @@ subroutine dotprod (b, c, n, block_size, num_teams, block_threads)
  !REF: /dotprod/sum
  sum = 0.0e0
 !$omp target  map(to:b,c)  map(tofrom:sum)
-!$omp teams  num_teams(num_teams) thread_limit(block_threads) reduction(+: sum&
-!$OMP&)
+!$omp teams num_teams(num_teams) thread_limit(block_threads) reduction(+: sum)
 !$omp distribute
  !DEF: /dotprod/OtherConstruct1/OtherConstruct1/OtherConstruct1/i0 (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
  !REF: /dotprod/n



More information about the llvm-branch-commits mailing list