[flang] [llvm] [FLANG][OpenMP]Add frontend support for ASSUME and ASSUMES (PR #120770)

Kiran Chandramohan via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 2 10:27:25 PST 2025


https://github.com/kiranchandramohan updated https://github.com/llvm/llvm-project/pull/120770

>From 3dcf7fc125bca5d3f846c30144376ead237034e2 Mon Sep 17 00:00:00 2001
From: Mats Petersson <mats.petersson at arm.com>
Date: Fri, 20 Dec 2024 16:04:59 +0000
Subject: [PATCH 1/6] [FLANG][OpenMP]Add frontend support for ASSUME and
 ASSUMES

Enough suport to parse correctly formed directives of !$OMP ASSUME
and !$OMP ASSUMES with teh related clauses that go with them:
ABSENT, CONTAINS, NO_OPENPP, NO_OPENMP_ROUTINES, NO_PARALLELISM
and HOLDS.

Tests added for unparsing and dump parse-tree.

Semantics support is very minimal and no specific tests added.

The lowering will hit a TODO, and there are tests in Lower/OpenMP/Todo
to make it clear that this is currently expected behaviour.
---
 .../FlangOmpReport/FlangOmpReportVisitor.cpp  |  4 +
 flang/include/flang/Parser/dump-parse-tree.h  | 12 +++
 flang/include/flang/Parser/parse-tree.h       | 85 ++++++++++++++++++-
 flang/lib/Lower/OpenMP/OpenMP.cpp             | 18 ++++
 flang/lib/Parser/openmp-parsers.cpp           | 38 ++++++++-
 flang/lib/Parser/unparse.cpp                  | 20 ++++-
 flang/lib/Semantics/check-omp-structure.cpp   | 17 ++++
 flang/lib/Semantics/check-omp-structure.h     |  4 +
 flang/test/Lower/OpenMP/Todo/assume.f90       |  6 ++
 flang/test/Lower/OpenMP/Todo/assumes.f90      |  9 ++
 flang/test/Parser/OpenMP/assumption.f90       | 66 ++++++++++++++
 llvm/include/llvm/Frontend/OpenMP/OMP.td      | 19 +++++
 12 files changed, 295 insertions(+), 3 deletions(-)
 create mode 100644 flang/test/Lower/OpenMP/Todo/assume.f90
 create mode 100644 flang/test/Lower/OpenMP/Todo/assumes.f90
 create mode 100644 flang/test/Parser/OpenMP/assumption.f90

diff --git a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp
index c78dd7f14e503d..934ab693c01919 100644
--- a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp
+++ b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp
@@ -139,6 +139,10 @@ std::string OpenMPCounterVisitor::getName(const OpenMPConstruct &c) {
             const CharBlock &source{std::get<0>(c.t).source};
             return normalize_construct_name(source.ToString());
           },
+          [&](const OpenMPAssumeConstruct &c) -> std::string {
+            const CharBlock &source{std::get<0>(c.t).source};
+            return normalize_construct_name(source.ToString());
+          },
           [&](const OpenMPAllocatorsConstruct &c) -> std::string {
             const CharBlock &source{std::get<0>(c.t).source};
             return normalize_construct_name(source.ToString());
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 87bb65fa5c4664..a0576c2325a989 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -503,6 +503,7 @@ class ParseTreeDumper {
   NODE_ENUM(OmpMapTypeModifier, Value)
   NODE(parser, OmpIteratorSpecifier)
   NODE(parser, OmpIterator)
+  NODE(parser, OmpAbsentClause)
   NODE(parser, OmpAffinityClause)
   NODE(OmpAffinityClause, Modifier)
   NODE(parser, OmpAlignment)
@@ -536,6 +537,7 @@ class ParseTreeDumper {
 #define GEN_FLANG_DUMP_PARSE_TREE_CLAUSES
 #include "llvm/Frontend/OpenMP/OMP.inc"
   NODE(parser, OmpClauseList)
+  NODE(parser, OmpContainsClause)
   NODE(parser, OmpCriticalDirective)
   NODE(parser, OmpErrorDirective)
   NODE(parser, OmpNothingDirective)
@@ -578,6 +580,8 @@ class ParseTreeDumper {
   NODE(parser, OmpExpectation)
   NODE_ENUM(OmpExpectation, Value)
   NODE(parser, OmpDirectiveNameModifier)
+  NODE(parser, OmpDirectiveNameEntry)
+  NODE(parser, OmpHoldsClause)
   NODE(parser, OmpIfClause)
   NODE(OmpIfClause, Modifier)
   NODE(parser, OmpLastprivateClause)
@@ -601,6 +605,9 @@ class ParseTreeDumper {
   }
   NODE(parser, OmpObject)
   NODE(parser, OmpObjectList)
+  NODE(parser, OmpNoOpenMPClause)
+  NODE(parser, OmpNoOpenMPRoutinesClause)
+  NODE(parser, OmpNoParallelismClause)
   NODE(parser, OmpOrderClause)
   NODE(OmpOrderClause, Modifier)
   NODE_ENUM(OmpOrderClause, Ordering)
@@ -666,6 +673,11 @@ class ParseTreeDumper {
   NODE(parser, OpenACCStandaloneDeclarativeConstruct)
   NODE(parser, OpenACCStandaloneConstruct)
   NODE(parser, OpenACCWaitConstruct)
+  NODE(parser, OpenMPAssumeConstruct)
+  NODE(parser, OpenMPAssumesConstruct)
+  NODE(parser, OpenMPAssumesPartConstruct)
+  NODE(parser, OmpAssumesDirective)
+  NODE(parser, OmpEndAssumesDirective)
   NODE(parser, OpenMPAtomicConstruct)
   NODE(parser, OpenMPBlockConstruct)
   NODE(parser, OpenMPCancelConstruct)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index be3b1fbde8c3cd..1675486f8c14e7 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3895,6 +3895,19 @@ using OmpContextSelector = traits::OmpContextSelectorSpecification;
 
 // --- Clauses
 
+struct OmpDirectiveNameEntry {
+  WRAPPER_CLASS_BOILERPLATE(OmpDirectiveNameEntry, llvm::omp::Directive);
+};
+using OmpDirectiveList = std::list<OmpDirectiveNameEntry>;
+
+// Ref: [5.2:214]
+//
+// absent-clause ->
+//   ABSENT(directive-name[, directive-name])
+struct OmpAbsentClause {
+  WRAPPER_CLASS_BOILERPLATE(OmpAbsentClause, OmpDirectiveList);
+};
+
 // Ref: [5.0:135-140], [5.1:161-166], [5.2:264-265]
 //
 // affinity-clause ->
@@ -3968,6 +3981,14 @@ struct OmpBindClause {
   WRAPPER_CLASS_BOILERPLATE(OmpBindClause, Binding);
 };
 
+// Ref: [5.2:214]
+//
+// contains-clause ->
+//   CONTAINS(directive-name[, directive-name])
+struct OmpContainsClause {
+  WRAPPER_CLASS_BOILERPLATE(OmpContainsClause, OmpDirectiveList);
+};
+
 // Ref: [4.5:46-50], [5.0:74-78], [5.1:92-96], [5.2:109]
 //
 // When used as a data-sharing clause:
@@ -4138,6 +4159,15 @@ struct OmpGrainsizeClause {
   std::tuple<MODIFIERS(), ScalarIntExpr> t;
 };
 
+// Ref: [5.2: 214]
+//
+// holds-clause ->
+//   HOLDS(expr[, expr])
+struct OmpHoldsClause {
+  using ExprList = std::list<common::Indirection<Expr>>;
+  WRAPPER_CLASS_BOILERPLATE(OmpHoldsClause, ExprList);
+};
+
 // Ref: [5.2:72-73], in 4.5-5.1 it's scattered over individual directives
 // that allow the IF clause.
 //
@@ -4219,6 +4249,21 @@ struct OmpMessageClause {
   WRAPPER_CLASS_BOILERPLATE(OmpMessageClause, Expr);
 };
 
+// Ref: [5.2: 214]
+//
+// no_openmp_clause -> NO_OPENMP
+EMPTY_CLASS(OmpNoOpenMPClause);
+
+// Ref: [5.2: 214]
+//
+// no_openmp_routines_clause -> NO_OPENMP_ROUTINES
+EMPTY_CLASS(OmpNoOpenMPRoutinesClause);
+
+// Ref: [5.2: 214]
+//
+// no_parallelism_clause -> NO_PARALELISM
+EMPTY_CLASS(OmpNoParallelismClause);
+
 // Ref: [4.5:87-91], [5.0:140-146], [5.1:166-171], [5.2:270]
 //
 // num-tasks-clause ->
@@ -4403,6 +4448,44 @@ struct OpenMPUtilityConstruct {
   std::variant<OmpErrorDirective, OmpNothingDirective> u;
 };
 
+// Ref: [5.2: 213-216]
+//
+// assume-construct ->
+//   ASSUME absent-clause | contains-clause | holds-clause | no-openmp-clause |
+//          no-openmp-routines-clause | no-parallelism-clause
+struct OpenMPAssumeConstruct {
+  TUPLE_CLASS_BOILERPLATE(OpenMPAssumeConstruct);
+  std::tuple<Verbatim, OmpClauseList> t;
+  CharBlock source;
+};
+
+struct OmpAssumesDirective {
+  TUPLE_CLASS_BOILERPLATE(OmpAssumesDirective);
+  std::tuple<Verbatim, OmpClauseList> t;
+  CharBlock source;
+};
+
+struct OmpEndAssumesDirective {
+  TUPLE_CLASS_BOILERPLATE(OmpEndAssumesDirective);
+  std::tuple<Verbatim> t;
+  CharBlock source;
+};
+
+//    structured-block
+// ...
+struct OpenMPAssumesPartConstruct {
+  WRAPPER_CLASS_BOILERPLATE(OpenMPAssumesPartConstruct, Block);
+  CharBlock source;
+};
+
+struct OpenMPAssumesConstruct {
+  TUPLE_CLASS_BOILERPLATE(OpenMPAssumesConstruct);
+  std::tuple<OmpAssumesDirective, OpenMPAssumesPartConstruct,
+      OmpEndAssumesDirective>
+      t;
+  CharBlock source;
+};
+
 // 2.7.2 SECTIONS
 // 2.11.2 PARALLEL SECTIONS
 struct OmpSectionsDirective {
@@ -4826,7 +4909,7 @@ struct OpenMPConstruct {
       OpenMPSectionConstruct, OpenMPLoopConstruct, OpenMPBlockConstruct,
       OpenMPAtomicConstruct, OpenMPDeclarativeAllocate, OpenMPDispatchConstruct,
       OpenMPUtilityConstruct, OpenMPExecutableAllocate,
-      OpenMPAllocatorsConstruct, OpenMPCriticalConstruct>
+      OpenMPAllocatorsConstruct,OpenMPAssumeConstruct, OpenMPAssumesConstruct, OpenMPCriticalConstruct>
       u;
 };
 
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 25595d2ea6c7d8..971448339b1abb 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -3374,6 +3374,24 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
                  queue.begin());
 }
 
+static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
+                   semantics::SemanticsContext &semaCtx,
+                   lower::pft::Evaluation &eval,
+                   const parser::OpenMPAssumeConstruct &assumeConstruct) {
+  const auto &verbatim = std::get<parser::Verbatim>(assumeConstruct.t);
+  mlir::Location clauseLocation = converter.genLocation(verbatim.source);
+  TODO(clauseLocation, "OpenMP ASSUME construct");
+}
+
+static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
+                   semantics::SemanticsContext &semaCtx,
+                   lower::pft::Evaluation &eval,
+                   const parser::OpenMPAssumesConstruct &assumesConstruct) {
+  mlir::Location clauseLocation =
+      converter.genLocation(assumesConstruct.source);
+  TODO(clauseLocation, "OpenMP ASSUMES construct");
+}
+
 static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
                    semantics::SemanticsContext &semaCtx,
                    lower::pft::Evaluation &eval,
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 43b4e9df97dbc3..2f5799ed7360cb 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -755,7 +755,14 @@ TYPE_PARSER(construct<OmpSeverityClause>(
 
 TYPE_PARSER(construct<OmpMessageClause>(expr))
 
-TYPE_PARSER(
+TYPE_PARSER(construct<OmpHoldsClause>(many(maybe(","_tok) >> indirect(expr))))
+TYPE_PARSER(construct<OmpAbsentClause>(many(maybe(","_tok) >>
+    construct<OmpDirectiveNameEntry>(OmpDirectiveNameParser{}))))
+TYPE_PARSER(construct<OmpContainsClause>(many(maybe(","_tok) >>
+    construct<OmpDirectiveNameEntry>(OmpDirectiveNameParser{}))))
+
+TYPE_PARSER("ABSENT" >> construct<OmpClause>(construct<OmpClause::Absent>(
+                            parenthesized(Parser<OmpAbsentClause>{}))) ||
     "ACQUIRE" >> construct<OmpClause>(construct<OmpClause::Acquire>()) ||
     "ACQ_REL" >> construct<OmpClause>(construct<OmpClause::AcqRel>()) ||
     "AFFINITY" >> construct<OmpClause>(construct<OmpClause::Affinity>(
@@ -777,6 +784,8 @@ TYPE_PARSER(
                   parenthesized(Parser<OmpBindClause>{}))) ||
     "COLLAPSE" >> construct<OmpClause>(construct<OmpClause::Collapse>(
                       parenthesized(scalarIntConstantExpr))) ||
+    "CONTAINS" >> construct<OmpClause>(construct<OmpClause::Contains>(
+                      parenthesized(Parser<OmpContainsClause>{}))) ||
     "COPYIN" >> construct<OmpClause>(construct<OmpClause::Copyin>(
                     parenthesized(Parser<OmpObjectList>{}))) ||
     "COPYPRIVATE" >> construct<OmpClause>(construct<OmpClause::Copyprivate>(
@@ -821,6 +830,8 @@ TYPE_PARSER(
             parenthesized(Parser<OmpObjectList>{}))) ||
     "HINT" >> construct<OmpClause>(
                   construct<OmpClause::Hint>(parenthesized(constantExpr))) ||
+    "HOLDS" >> construct<OmpClause>(construct<OmpClause::Holds>(
+                   parenthesized(Parser<OmpHoldsClause>{}))) ||
     "IF" >> construct<OmpClause>(construct<OmpClause::If>(
                 parenthesized(Parser<OmpIfClause>{}))) ||
     "INBRANCH" >> construct<OmpClause>(construct<OmpClause::Inbranch>()) ||
@@ -851,6 +862,11 @@ TYPE_PARSER(
     "NOVARIANTS" >> construct<OmpClause>(construct<OmpClause::Novariants>(
                         parenthesized(scalarLogicalExpr))) ||
     "NOWAIT" >> construct<OmpClause>(construct<OmpClause::Nowait>()) ||
+    "NO_OPENMP"_id >> construct<OmpClause>(construct<OmpClause::NoOpenmp>()) ||
+    "NO_OPENMP_ROUTINES" >>
+        construct<OmpClause>(construct<OmpClause::NoOpenmpRoutines>()) ||
+    "NO_PARALLELISM" >>
+        construct<OmpClause>(construct<OmpClause::NoParallelism>()) ||
     "NUM_TASKS" >> construct<OmpClause>(construct<OmpClause::NumTasks>(
                        parenthesized(Parser<OmpNumTasksClause>{}))) ||
     "NUM_TEAMS" >> construct<OmpClause>(construct<OmpClause::NumTeams>(
@@ -1300,6 +1316,24 @@ TYPE_PARSER(startOmpLine >>
                 Parser<OpenMPUtilityConstruct>{})) /
             endOmpLine))
 
+// Assume Construct
+TYPE_PARSER(sourced(construct<OpenMPAssumeConstruct>(
+                        verbatim("ASSUME"_tok), Parser<OmpClauseList>{}) /
+    endOmpLine))
+// Assumes Construct
+TYPE_PARSER(sourced(construct<OmpAssumesDirective>(
+    verbatim("ASSUMES"_tok), Parser<OmpClauseList>{})))
+
+TYPE_PARSER(sourced(construct<OmpEndAssumesDirective>(
+    verbatim(startOmpLine >> "END ASSUMES"_tok))))
+
+TYPE_PARSER(construct<OpenMPAssumesPartConstruct>(block))
+
+TYPE_PARSER(sourced(construct<OpenMPAssumesConstruct>(
+    maybe("BEGIN"_tok) >> Parser<OmpAssumesDirective>{} / endOmpLine,
+    Parser<OpenMPAssumesPartConstruct>{},
+    Parser<OmpEndAssumesDirective>{} / endOmpLine)))
+
 // Block Construct
 TYPE_PARSER(construct<OpenMPBlockConstruct>(
     Parser<OmpBeginBlockDirective>{} / endOmpLine, block,
@@ -1347,6 +1381,8 @@ TYPE_CONTEXT_PARSER("OpenMP construct"_en_US,
                 construct<OpenMPConstruct>(Parser<OpenMPExecutableAllocate>{}),
                 construct<OpenMPConstruct>(Parser<OpenMPAllocatorsConstruct>{}),
                 construct<OpenMPConstruct>(Parser<OpenMPDeclarativeAllocate>{}),
+                construct<OpenMPConstruct>(Parser<OpenMPAssumesConstruct>{}),
+                construct<OpenMPConstruct>(Parser<OpenMPAssumeConstruct>{}),
                 construct<OpenMPConstruct>(Parser<OpenMPCriticalConstruct>{}))))
 
 // END OMP Block directives
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 813dd652e1e9f7..e52f285085982d 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2118,6 +2118,9 @@ class UnparseVisitor {
   void Unparse(const OmpDirectiveNameModifier &x) {
     Word(llvm::omp::getOpenMPDirectiveName(x.v));
   }
+  void Unparse(const OmpDirectiveNameEntry &x) {
+    Word(llvm::omp::getOpenMPDirectiveName(x.v));
+  }
   void Unparse(const OmpIteratorSpecifier &x) {
     Walk(std::get<TypeDeclarationStmt>(x.t));
     Put(" = ");
@@ -2154,6 +2157,8 @@ class UnparseVisitor {
     Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
     Walk(std::get<ScalarIntExpr>(x.t));
   }
+  void Unparse(const OmpAbsentClause &x) { Walk("", x.v, ","); }
+  void Unparse(const OmpContainsClause &x) { Walk("", x.v, ","); }
   void Unparse(const OmpAffinityClause &x) {
     using Modifier = OmpAffinityClause::Modifier;
     Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
@@ -2636,6 +2641,13 @@ class UnparseVisitor {
       Walk(*end);
     }
   }
+  void Unparse(const OpenMPAssumeConstruct &x) {
+    BeginOpenMP();
+    Word("!$OMP ASSUME");
+    Walk(std::get<OmpClauseList>(x.t), ", ");
+    Put("\n");
+    EndOpenMP();
+  }
   void Unparse(const OmpCriticalDirective &x) {
     BeginOpenMP();
     Word("!$OMP CRITICAL");
@@ -2855,7 +2867,9 @@ class UnparseVisitor {
     Put("\n");
     EndOpenMP();
   }
-  void Unparse(const OmpClauseList &x) { Walk(" ", x.v, " "); }
+  void Unparse(const OmpClauseList &x, const char *sep = " ") {
+    Walk(" ", x.v, sep);
+  }
   void Unparse(const OpenMPSimpleStandaloneConstruct &x) {
     BeginOpenMP();
     Word("!$OMP ");
@@ -3117,6 +3131,10 @@ class UnparseVisitor {
     return Walk("", list, comma, suffix);
   }
 
+  void Walk(const OmpClauseList &x, const char *sep = " ") {
+    return Walk(" ", x.v, sep);
+  }
+
   // Traverse a std::tuple<>, with an optional separator.
   template <std::size_t J = 0, typename T>
   void WalkTupleElements(const T &tuple, const char *separator) {
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 035064ecf3a46e..c4fcb73f48fae2 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1251,6 +1251,23 @@ void OmpStructureChecker::CheckMasterNesting(
   }
 }
 
+void OmpStructureChecker::Enter(const parser::OpenMPAssumeConstruct &x) {
+  const auto &dir{std::get<parser::Verbatim>(x.t)};
+  PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_assume);
+}
+
+void OmpStructureChecker::Leave(const parser::OpenMPAssumeConstruct &) {
+  dirContext_.pop_back();
+}
+
+void OmpStructureChecker::Enter(const parser::OpenMPAssumesConstruct &x) {
+  PushContextAndClauseSets(x.source, llvm::omp::Directive::OMPD_assumes);
+}
+
+void OmpStructureChecker::Leave(const parser::OpenMPAssumesConstruct &) {
+  dirContext_.pop_back();
+}
+
 void OmpStructureChecker::Leave(const parser::OpenMPBlockConstruct &) {
   if (GetDirectiveNest(TargetBlockOnlyTeams)) {
     ExitDirectiveNest(TargetBlockOnlyTeams);
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 7412a2071d492f..833614cc83e8f0 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -81,6 +81,10 @@ class OmpStructureChecker
   void Enter(const parser::OmpEndLoopDirective &);
   void Leave(const parser::OmpEndLoopDirective &);
 
+  void Enter(const parser::OpenMPAssumeConstruct &);
+  void Leave(const parser::OpenMPAssumeConstruct &);
+  void Enter(const parser::OpenMPAssumesConstruct &);
+  void Leave(const parser::OpenMPAssumesConstruct &);
   void Enter(const parser::OpenMPBlockConstruct &);
   void Leave(const parser::OpenMPBlockConstruct &);
   void Leave(const parser::OmpBeginBlockDirective &);
diff --git a/flang/test/Lower/OpenMP/Todo/assume.f90 b/flang/test/Lower/OpenMP/Todo/assume.f90
new file mode 100644
index 00000000000000..6942c7774663ed
--- /dev/null
+++ b/flang/test/Lower/OpenMP/Todo/assume.f90
@@ -0,0 +1,6 @@
+! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1 | FileCheck %s
+
+! CHECK: not yet implemented: OpenMP ASSUME construct
+program p
+  !$omp assume no_openmp
+end program p
diff --git a/flang/test/Lower/OpenMP/Todo/assumes.f90 b/flang/test/Lower/OpenMP/Todo/assumes.f90
new file mode 100644
index 00000000000000..73ad1526e83cc4
--- /dev/null
+++ b/flang/test/Lower/OpenMP/Todo/assumes.f90
@@ -0,0 +1,9 @@
+! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1 | FileCheck %s
+
+! CHECK: not yet implemented: OpenMP ASSUMES construct
+program p
+  integer r
+  !$omp assumes no_openmp
+  print *,r
+  !$omp end assumes
+end program p
diff --git a/flang/test/Parser/OpenMP/assumption.f90 b/flang/test/Parser/OpenMP/assumption.f90
new file mode 100644
index 00000000000000..74c10126a76c61
--- /dev/null
+++ b/flang/test/Parser/OpenMP/assumption.f90
@@ -0,0 +1,66 @@
+! RUN: %flang_fc1  -fopenmp-version=51 -fopenmp -fdebug-unparse-no-sema %s 2>&1 | FileCheck %s
+!!! RUN: %flang_fc1  -fopenmp-version=51 -fopenmp -fdebug-dump-parse-tree-no-sema %s 2>&1 | FileCheck %s --check-prefix="PARSE-TREE"
+
+subroutine sub1
+  integer :: r
+!CHECK: !$OMP ASSUME NO_OPENMP
+!PARSE-TREE:   ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumeConstruct
+!PARSE-TREE:   Verbatim
+!PARSE-TREE:   OmpClauseList -> OmpClause -> NoOpenmp
+  !$omp assume no_openmp
+!CHECK: !$OMP ASSUME NO_PARALLELISM
+!PARSE-TREE:   ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumeConstruct
+!PARSE-TREE:   Verbatim
+!PARSE-TREE:   OmpClauseList -> OmpClause -> NoParallelism
+  !$omp assume no_parallelism
+!CHECK: !$OMP ASSUME NO_OPENMP_ROUTINES
+!PARSE-TREE:   ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumeConstruct
+!PARSE-TREE:   Verbatim
+!PARSE-TREE:   OmpClauseList -> OmpClause -> NoOpenmpRoutines  
+  !$omp assume no_openmp_routines
+!CHECK: !$OMP ASSUME ABSENT(ALLOCATE), CONTAINS(WORKSHARE,TASK)
+!PARSE-TREE:   ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumeConstruct
+!PARSE-TREE:   Verbatim
+!PARSE-TREE:   OmpClauseList -> OmpClause -> Absent -> OmpAbsentClause -> OmpDirectiveNameEntry -> llvm::omp::Directive = allocate
+!PARSE-TREE:   OmpClause -> Contains -> OmpContainsClause -> OmpDirectiveNameEntry -> llvm::omp::Directive = workshare
+!PARSE-TREE:   OmpDirectiveNameEntry -> llvm::omp::Directive = task
+ !$omp assume absent(allocate), contains(workshare, task)
+!CHECK: !$OMP ASSUME HOLDS(1==1)
+  !$omp assume holds(1.eq.1)
+  print *, r
+end subroutine sub1
+
+subroutine sub2
+  integer :: r
+!CHECK !$OMP ASSUMES NO_OPENMP
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumesConstruct
+!PARSE-TREE: OmpAssumesDirective
+!PARSE-TREE: Verbatim
+!PARSE-TREE: OmpClauseList -> OmpClause -> NoOpenmp
+!PARSE-TREE: OpenMPAssumesPartConstruct -> Block
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt
+!PARSE-TREE: Expr -> Add
+!PARSE-TREE: OmpEndAssumesDirective
+  !$omp assumes no_openmp
+  r = r + 1
+!CHECK !$OMP END ASSUMES
+  !$omp end assumes
+end subroutine sub2
+
+subroutine sub3
+  integer :: r
+!CHECK !$OMP ASSUMES NO_OPENMP
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumesConstruct
+!PARSE-TREE: OmpAssumesDirective
+!PARSE-TREE: Verbatim
+!PARSE-TREE: OmpClauseList -> OmpClause -> NoOpenmp
+!PARSE-TREE: OpenMPAssumesPartConstruct -> Block
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt
+!PARSE-TREE: Expr -> Add
+!PARSE-TREE: OmpEndAssumesDirective
+  !$omp begin assumes no_openmp
+  r = r + 1
+!CHECK !$OMP END ASSUMES
+  !$omp end assumes
+end subroutine sub3
+  
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index 1f2389987e18bc..208da3afcba137 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -34,6 +34,7 @@ def OpenMP : DirectiveLanguage {
 
 def OMPC_Absent : Clause<"absent"> {
   let clangClass = "OMPAbsentClause";
+  let flangClass = "OmpAbsentClause";
 }
 def OMPC_Acquire : Clause<"acquire"> {
   let clangClass = "OMPAcquireClause";
@@ -107,6 +108,7 @@ def OMPC_CancellationConstructType : Clause<"cancellation_construct_type"> {
 }
 def OMPC_Contains : Clause<"contains"> {
   let clangClass = "OMPContainsClause";
+  let flangClass = "OmpContainsClause";
 }
 def OMPC_Capture : Clause<"capture"> {
   let clangClass = "OMPCaptureClause";
@@ -225,6 +227,7 @@ def OMPC_Hint : Clause<"hint"> {
 }
 def OMPC_Holds : Clause<"holds"> {
   let clangClass = "OMPHoldsClause";
+  let flangClass = "OmpHoldsClause";
 }
 def OMPC_If : Clause<"if"> {
   let clangClass = "OMPIfClause";
@@ -559,6 +562,14 @@ def OMP_Allocators : Directive<"allocators"> {
 def OMP_Assumes : Directive<"assumes"> {
   let association = AS_None;
   let category = CA_Informational;
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_Absent, 51>,
+    VersionedClause<OMPC_Contains, 51>,
+    VersionedClause<OMPC_Holds, 51>,
+    VersionedClause<OMPC_NoOpenMP, 51>,
+    VersionedClause<OMPC_NoOpenMPRoutines, 51>,
+    VersionedClause<OMPC_NoParallelism, 51>,
+  ];
 }
 def OMP_EndAssumes : Directive<"end assumes"> {
   let association = AS_Delimited;
@@ -604,6 +615,14 @@ def OMP_Barrier : Directive<"barrier"> {
 def OMP_BeginAssumes : Directive<"begin assumes"> {
   let association = AS_Delimited;
   let category = CA_Informational;
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_Absent, 51>,
+    VersionedClause<OMPC_Contains, 51>,
+    VersionedClause<OMPC_Holds, 51>,
+    VersionedClause<OMPC_NoOpenMP, 51>,
+    VersionedClause<OMPC_NoOpenMPRoutines, 51>,
+    VersionedClause<OMPC_NoParallelism, 51>,
+  ];
 }
 def OMP_BeginDeclareTarget : Directive<"begin declare target"> {
   let allowedClauses = [

>From 6d4beb35426ce6c7a5a7eaa124c272b12f17b060 Mon Sep 17 00:00:00 2001
From: Mats Petersson <mats.petersson at arm.com>
Date: Tue, 24 Dec 2024 11:51:20 +0000
Subject: [PATCH 2/6] Review comments

---
 flang/include/flang/Parser/dump-parse-tree.h  |  4 +--
 flang/include/flang/Parser/parse-tree.h       | 33 ++++++++---------
 flang/lib/Lower/OpenMP/OpenMP.cpp             | 19 ++++++----
 flang/lib/Parser/openmp-parsers.cpp           | 27 ++++++++------
 flang/lib/Parser/unparse.cpp                  | 26 +++++++++++---
 flang/lib/Semantics/check-omp-structure.cpp   |  8 +++++
 flang/lib/Semantics/check-omp-structure.h     |  2 ++
 flang/test/Lower/OpenMP/Todo/assumes.f90      |  5 ++-
 .../test/Lower/OpenMP/Todo/begin-assumes.f90  |  9 +++++
 flang/test/Parser/OpenMP/assumption.f90       | 35 +++++++------------
 10 files changed, 105 insertions(+), 63 deletions(-)
 create mode 100644 flang/test/Lower/OpenMP/Todo/begin-assumes.f90

diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index a0576c2325a989..09bbea491b9a4a 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -580,7 +580,6 @@ class ParseTreeDumper {
   NODE(parser, OmpExpectation)
   NODE_ENUM(OmpExpectation, Value)
   NODE(parser, OmpDirectiveNameModifier)
-  NODE(parser, OmpDirectiveNameEntry)
   NODE(parser, OmpHoldsClause)
   NODE(parser, OmpIfClause)
   NODE(OmpIfClause, Modifier)
@@ -676,7 +675,8 @@ class ParseTreeDumper {
   NODE(parser, OpenMPAssumeConstruct)
   NODE(parser, OpenMPAssumesConstruct)
   NODE(parser, OpenMPAssumesPartConstruct)
-  NODE(parser, OmpAssumesDirective)
+  NODE(parser, OmpBeginAssumesDirective)
+  NODE(parser, OpenMPBeginAssumesConstruct)
   NODE(parser, OmpEndAssumesDirective)
   NODE(parser, OpenMPAtomicConstruct)
   NODE(parser, OpenMPBlockConstruct)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 1675486f8c14e7..d52a61089937a6 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3895,10 +3895,7 @@ using OmpContextSelector = traits::OmpContextSelectorSpecification;
 
 // --- Clauses
 
-struct OmpDirectiveNameEntry {
-  WRAPPER_CLASS_BOILERPLATE(OmpDirectiveNameEntry, llvm::omp::Directive);
-};
-using OmpDirectiveList = std::list<OmpDirectiveNameEntry>;
+using OmpDirectiveList = std::list<llvm::omp::Directive>;
 
 // Ref: [5.2:214]
 //
@@ -4162,10 +4159,9 @@ struct OmpGrainsizeClause {
 // Ref: [5.2: 214]
 //
 // holds-clause ->
-//   HOLDS(expr[, expr])
+//   HOLDS(expr)
 struct OmpHoldsClause {
-  using ExprList = std::list<common::Indirection<Expr>>;
-  WRAPPER_CLASS_BOILERPLATE(OmpHoldsClause, ExprList);
+  WRAPPER_CLASS_BOILERPLATE(OmpHoldsClause, common::Indirection<Expr>);
 };
 
 // Ref: [5.2:72-73], in 4.5-5.1 it's scattered over individual directives
@@ -4459,15 +4455,20 @@ struct OpenMPAssumeConstruct {
   CharBlock source;
 };
 
-struct OmpAssumesDirective {
-  TUPLE_CLASS_BOILERPLATE(OmpAssumesDirective);
+struct OpenMPAssumesConstruct {
+  TUPLE_CLASS_BOILERPLATE(OpenMPAssumesConstruct);
+  std::tuple<Verbatim, OmpClauseList> t;
+  CharBlock source;
+};
+
+struct OmpBeginAssumesDirective {
+  TUPLE_CLASS_BOILERPLATE(OmpBeginAssumesDirective);
   std::tuple<Verbatim, OmpClauseList> t;
   CharBlock source;
 };
 
 struct OmpEndAssumesDirective {
-  TUPLE_CLASS_BOILERPLATE(OmpEndAssumesDirective);
-  std::tuple<Verbatim> t;
+  WRAPPER_CLASS_BOILERPLATE(OmpEndAssumesDirective, Verbatim);
   CharBlock source;
 };
 
@@ -4478,9 +4479,9 @@ struct OpenMPAssumesPartConstruct {
   CharBlock source;
 };
 
-struct OpenMPAssumesConstruct {
-  TUPLE_CLASS_BOILERPLATE(OpenMPAssumesConstruct);
-  std::tuple<OmpAssumesDirective, OpenMPAssumesPartConstruct,
+struct OpenMPBeginAssumesConstruct {
+  TUPLE_CLASS_BOILERPLATE(OpenMPBeginAssumesConstruct);
+  std::tuple<OmpBeginAssumesDirective, OpenMPAssumesPartConstruct,
       OmpEndAssumesDirective>
       t;
   CharBlock source;
@@ -4619,7 +4620,7 @@ struct OpenMPDeclarativeAllocate {
 struct OpenMPDeclarativeConstruct {
   UNION_CLASS_BOILERPLATE(OpenMPDeclarativeConstruct);
   CharBlock source;
-  std::variant<OpenMPDeclarativeAllocate, OpenMPDeclareMapperConstruct,
+  std::variant<OpenMPDeclarativeAllocate, OpenMPAssumesConstruct, OpenMPDeclareMapperConstruct,
       OpenMPDeclareReductionConstruct, OpenMPDeclareSimdConstruct,
       OpenMPDeclareTargetConstruct, OpenMPThreadprivate,
       OpenMPRequiresConstruct, OpenMPUtilityConstruct>
@@ -4909,7 +4910,7 @@ struct OpenMPConstruct {
       OpenMPSectionConstruct, OpenMPLoopConstruct, OpenMPBlockConstruct,
       OpenMPAtomicConstruct, OpenMPDeclarativeAllocate, OpenMPDispatchConstruct,
       OpenMPUtilityConstruct, OpenMPExecutableAllocate,
-      OpenMPAllocatorsConstruct,OpenMPAssumeConstruct, OpenMPAssumesConstruct, OpenMPCriticalConstruct>
+      OpenMPAllocatorsConstruct, OpenMPAssumeConstruct, OpenMPBeginAssumesConstruct, OpenMPCriticalConstruct>
       u;
 };
 
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 971448339b1abb..70f5c5a27ffdc0 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -3076,6 +3076,13 @@ genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
   TODO(converter.getCurrentLocation(), "OpenMPDeclarativeAllocate");
 }
 
+static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
+                   semantics::SemanticsContext &semaCtx,
+                   lower::pft::Evaluation &eval,
+                   const parser::OpenMPAssumesConstruct &assumesConstruct) {
+  TODO(converter.getCurrentLocation(), "OpenMP ASSUMES declaration");
+}
+
 static void genOMP(
     lower::AbstractConverter &converter, lower::SymMap &symTable,
     semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
@@ -3383,13 +3390,13 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
   TODO(clauseLocation, "OpenMP ASSUME construct");
 }
 
-static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
-                   semantics::SemanticsContext &semaCtx,
-                   lower::pft::Evaluation &eval,
-                   const parser::OpenMPAssumesConstruct &assumesConstruct) {
+static void
+genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
+       semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
+       const parser::OpenMPBeginAssumesConstruct &beginAssumesConstruct) {
   mlir::Location clauseLocation =
-      converter.genLocation(assumesConstruct.source);
-  TODO(clauseLocation, "OpenMP ASSUMES construct");
+      converter.genLocation(beginAssumesConstruct.source);
+  TODO(clauseLocation, "OpenMP BEGIN ASSUMES construct");
 }
 
 static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 2f5799ed7360cb..ad3313b6ddafa9 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -755,11 +755,11 @@ TYPE_PARSER(construct<OmpSeverityClause>(
 
 TYPE_PARSER(construct<OmpMessageClause>(expr))
 
-TYPE_PARSER(construct<OmpHoldsClause>(many(maybe(","_tok) >> indirect(expr))))
+TYPE_PARSER(construct<OmpHoldsClause>(indirect(expr)))
 TYPE_PARSER(construct<OmpAbsentClause>(many(maybe(","_tok) >>
-    construct<OmpDirectiveNameEntry>(OmpDirectiveNameParser{}))))
+    construct<llvm::omp::Directive>(OmpDirectiveNameParser{}))))
 TYPE_PARSER(construct<OmpContainsClause>(many(maybe(","_tok) >>
-    construct<OmpDirectiveNameEntry>(OmpDirectiveNameParser{}))))
+    construct<llvm::omp::Directive>(OmpDirectiveNameParser{}))))
 
 TYPE_PARSER("ABSENT" >> construct<OmpClause>(construct<OmpClause::Absent>(
                             parenthesized(Parser<OmpAbsentClause>{}))) ||
@@ -1295,11 +1295,17 @@ TYPE_PARSER(
         parenthesized(Parser<OmpObjectList>{}), Parser<OmpClauseList>{})) /
     lookAhead(endOmpLine / !statement(allocateStmt)))
 
+// Assumes Construct
+TYPE_PARSER(sourced(construct<OpenMPAssumesConstruct>(
+    verbatim("ASSUMES"_tok), Parser<OmpClauseList>{})))
+
 // Declarative constructs
 TYPE_PARSER(startOmpLine >>
     withMessage("expected OpenMP construct"_err_en_US,
         sourced(construct<OpenMPDeclarativeConstruct>(
-                    Parser<OpenMPDeclareReductionConstruct>{}) ||
+                Parser<OpenMPAssumesConstruct>{}) ||
+            construct<OpenMPDeclarativeConstruct>(
+                Parser<OpenMPDeclareReductionConstruct>{}) ||
             construct<OpenMPDeclarativeConstruct>(
                 Parser<OpenMPDeclareMapperConstruct>{}) ||
             construct<OpenMPDeclarativeConstruct>(
@@ -1320,17 +1326,17 @@ TYPE_PARSER(startOmpLine >>
 TYPE_PARSER(sourced(construct<OpenMPAssumeConstruct>(
                         verbatim("ASSUME"_tok), Parser<OmpClauseList>{}) /
     endOmpLine))
-// Assumes Construct
-TYPE_PARSER(sourced(construct<OmpAssumesDirective>(
-    verbatim("ASSUMES"_tok), Parser<OmpClauseList>{})))
+
+TYPE_PARSER(sourced(construct<OmpBeginAssumesDirective>(
+    "BEGIN"_tok >> verbatim("ASSUMES"_tok), Parser<OmpClauseList>{})))
 
 TYPE_PARSER(sourced(construct<OmpEndAssumesDirective>(
     verbatim(startOmpLine >> "END ASSUMES"_tok))))
 
 TYPE_PARSER(construct<OpenMPAssumesPartConstruct>(block))
 
-TYPE_PARSER(sourced(construct<OpenMPAssumesConstruct>(
-    maybe("BEGIN"_tok) >> Parser<OmpAssumesDirective>{} / endOmpLine,
+TYPE_PARSER(sourced(construct<OpenMPBeginAssumesConstruct>(
+    Parser<OmpBeginAssumesDirective>{} / endOmpLine,
     Parser<OpenMPAssumesPartConstruct>{},
     Parser<OmpEndAssumesDirective>{} / endOmpLine)))
 
@@ -1381,7 +1387,8 @@ TYPE_CONTEXT_PARSER("OpenMP construct"_en_US,
                 construct<OpenMPConstruct>(Parser<OpenMPExecutableAllocate>{}),
                 construct<OpenMPConstruct>(Parser<OpenMPAllocatorsConstruct>{}),
                 construct<OpenMPConstruct>(Parser<OpenMPDeclarativeAllocate>{}),
-                construct<OpenMPConstruct>(Parser<OpenMPAssumesConstruct>{}),
+                construct<OpenMPConstruct>(
+                    Parser<OpenMPBeginAssumesConstruct>{}),
                 construct<OpenMPConstruct>(Parser<OpenMPAssumeConstruct>{}),
                 construct<OpenMPConstruct>(Parser<OpenMPCriticalConstruct>{}))))
 
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index e52f285085982d..05dad8cca873b7 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2115,10 +2115,10 @@ class UnparseVisitor {
                   },
         x.u);
   }
-  void Unparse(const OmpDirectiveNameModifier &x) {
-    Word(llvm::omp::getOpenMPDirectiveName(x.v));
+  void Unparse(const llvm::omp::Directive &x) {
+    Word(llvm::omp::getOpenMPDirectiveName(x));
   }
-  void Unparse(const OmpDirectiveNameEntry &x) {
+  void Unparse(const OmpDirectiveNameModifier &x) {
     Word(llvm::omp::getOpenMPDirectiveName(x.v));
   }
   void Unparse(const OmpIteratorSpecifier &x) {
@@ -2648,6 +2648,18 @@ class UnparseVisitor {
     Put("\n");
     EndOpenMP();
   }
+  void Unparse(const OmpBeginAssumesDirective &x) {
+    BeginOpenMP();
+    Word("!$OMP BEGIN ASSUMES");
+    Walk(std::get<OmpClauseList>(x.t), ", ");
+    Put("\n");
+    EndOpenMP();
+  }
+  void Unparse(const OmpEndAssumesDirective &x) {
+    BeginOpenMP();
+    Word("!$OMP END ASSUMES\n");
+    EndOpenMP();
+  }
   void Unparse(const OmpCriticalDirective &x) {
     BeginOpenMP();
     Word("!$OMP CRITICAL");
@@ -2699,7 +2711,13 @@ class UnparseVisitor {
     Walk(std::get<std::optional<OmpReductionInitializerClause>>(x.t));
     EndOpenMP();
   }
-
+  bool Pre(const OpenMPAssumesConstruct &x) {
+    BeginOpenMP();
+    Word("!$OMP ASSUMES ");
+    Walk(std::get<OmpClauseList>(x.t));
+    Put("\n");
+    EndOpenMP();
+  }
   void Unparse(const OpenMPDeclareMapperConstruct &z) {
     BeginOpenMP();
     Word("!$OMP DECLARE MAPPER (");
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index c4fcb73f48fae2..b7d9c65537ede7 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1268,6 +1268,14 @@ void OmpStructureChecker::Leave(const parser::OpenMPAssumesConstruct &) {
   dirContext_.pop_back();
 }
 
+void OmpStructureChecker::Enter(const parser::OpenMPBeginAssumesConstruct &x) {
+  PushContextAndClauseSets(x.source, llvm::omp::Directive::OMPD_assumes);
+}
+
+void OmpStructureChecker::Leave(const parser::OpenMPBeginAssumesConstruct &) {
+  dirContext_.pop_back();
+}
+
 void OmpStructureChecker::Leave(const parser::OpenMPBlockConstruct &) {
   if (GetDirectiveNest(TargetBlockOnlyTeams)) {
     ExitDirectiveNest(TargetBlockOnlyTeams);
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 833614cc83e8f0..bc754511c4754a 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -85,6 +85,8 @@ class OmpStructureChecker
   void Leave(const parser::OpenMPAssumeConstruct &);
   void Enter(const parser::OpenMPAssumesConstruct &);
   void Leave(const parser::OpenMPAssumesConstruct &);
+  void Enter(const parser::OpenMPBeginAssumesConstruct &);
+  void Leave(const parser::OpenMPBeginAssumesConstruct &);
   void Enter(const parser::OpenMPBlockConstruct &);
   void Leave(const parser::OpenMPBlockConstruct &);
   void Leave(const parser::OmpBeginBlockDirective &);
diff --git a/flang/test/Lower/OpenMP/Todo/assumes.f90 b/flang/test/Lower/OpenMP/Todo/assumes.f90
index 73ad1526e83cc4..3ef4bd857612fd 100644
--- a/flang/test/Lower/OpenMP/Todo/assumes.f90
+++ b/flang/test/Lower/OpenMP/Todo/assumes.f90
@@ -1,9 +1,8 @@
 ! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1 | FileCheck %s
 
-! CHECK: not yet implemented: OpenMP ASSUMES construct
+! CHECK: not yet implemented: OpenMP ASSUMES declaration
 program p
+!$omp assumes no_openmp
   integer r
-  !$omp assumes no_openmp
   print *,r
-  !$omp end assumes
 end program p
diff --git a/flang/test/Lower/OpenMP/Todo/begin-assumes.f90 b/flang/test/Lower/OpenMP/Todo/begin-assumes.f90
new file mode 100644
index 00000000000000..5aad8be417a35b
--- /dev/null
+++ b/flang/test/Lower/OpenMP/Todo/begin-assumes.f90
@@ -0,0 +1,9 @@
+! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1 | FileCheck %s
+
+! CHECK: not yet implemented: OpenMP BEGIN ASSUMES construct
+program p
+  integer r
+!$omp begin assumes no_parallelism
+  print *,r
+!$omp end assumes
+end program p
diff --git a/flang/test/Parser/OpenMP/assumption.f90 b/flang/test/Parser/OpenMP/assumption.f90
index 74c10126a76c61..80c15cbf6c3109 100644
--- a/flang/test/Parser/OpenMP/assumption.f90
+++ b/flang/test/Parser/OpenMP/assumption.f90
@@ -1,6 +1,5 @@
 ! RUN: %flang_fc1  -fopenmp-version=51 -fopenmp -fdebug-unparse-no-sema %s 2>&1 | FileCheck %s
 !!! RUN: %flang_fc1  -fopenmp-version=51 -fopenmp -fdebug-dump-parse-tree-no-sema %s 2>&1 | FileCheck %s --check-prefix="PARSE-TREE"
-
 subroutine sub1
   integer :: r
 !CHECK: !$OMP ASSUME NO_OPENMP
@@ -21,9 +20,9 @@ subroutine sub1
 !CHECK: !$OMP ASSUME ABSENT(ALLOCATE), CONTAINS(WORKSHARE,TASK)
 !PARSE-TREE:   ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumeConstruct
 !PARSE-TREE:   Verbatim
-!PARSE-TREE:   OmpClauseList -> OmpClause -> Absent -> OmpAbsentClause -> OmpDirectiveNameEntry -> llvm::omp::Directive = allocate
-!PARSE-TREE:   OmpClause -> Contains -> OmpContainsClause -> OmpDirectiveNameEntry -> llvm::omp::Directive = workshare
-!PARSE-TREE:   OmpDirectiveNameEntry -> llvm::omp::Directive = task
+!PARSE-TREE:   OmpClauseList -> OmpClause -> Absent -> OmpAbsentClause -> llvm::omp::Directive = allocate
+!PARSE-TREE:   OmpClause -> Contains -> OmpContainsClause -> llvm::omp::Directive = workshare
+!PARSE-TREE:   llvm::omp::Directive = task
  !$omp assume absent(allocate), contains(workshare, task)
 !CHECK: !$OMP ASSUME HOLDS(1==1)
   !$omp assume holds(1.eq.1)
@@ -32,35 +31,27 @@ end subroutine sub1
 
 subroutine sub2
   integer :: r
-!CHECK !$OMP ASSUMES NO_OPENMP
-!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumesConstruct
-!PARSE-TREE: OmpAssumesDirective
+!CHECK !$OMP BEGIN ASSUMES NO_OPENMP
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPBeginAssumesConstruct
+!PARSE-TREE: OmpBeginAssumesDirective
 !PARSE-TREE: Verbatim
 !PARSE-TREE: OmpClauseList -> OmpClause -> NoOpenmp
 !PARSE-TREE: OpenMPAssumesPartConstruct -> Block
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt
 !PARSE-TREE: Expr -> Add
 !PARSE-TREE: OmpEndAssumesDirective
-  !$omp assumes no_openmp
+  !$omp begin assumes no_openmp
   r = r + 1
 !CHECK !$OMP END ASSUMES
   !$omp end assumes
 end subroutine sub2
-
-subroutine sub3
-  integer :: r
+  
+program p
 !CHECK !$OMP ASSUMES NO_OPENMP
-!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumesConstruct
-!PARSE-TREE: OmpAssumesDirective
+!PARSE-TREE: SpecificationPart
+!PARSE-TREE:   OpenMPDeclarativeConstruct -> OpenMPAssumesConstruct
 !PARSE-TREE: Verbatim
 !PARSE-TREE: OmpClauseList -> OmpClause -> NoOpenmp
-!PARSE-TREE: OpenMPAssumesPartConstruct -> Block
-!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt
-!PARSE-TREE: Expr -> Add
-!PARSE-TREE: OmpEndAssumesDirective
-  !$omp begin assumes no_openmp
-  r = r + 1
-!CHECK !$OMP END ASSUMES
-  !$omp end assumes
-end subroutine sub3
+  !$omp assumes no_openmp
+end program p
   

>From dbe9e873e0d061cab4db25964ff185243939cb01 Mon Sep 17 00:00:00 2001
From: Mats Petersson <mats.petersson at arm.com>
Date: Tue, 31 Dec 2024 11:42:46 +0000
Subject: [PATCH 3/6] Remove incorrect "begin" keyword.

This is only used in C++, so do not use it in the Fortran compiler.

Updated tests to suit.
---
 flang/include/flang/Parser/dump-parse-tree.h  |  6 ++---
 flang/include/flang/Parser/parse-tree.h       | 23 ++++++++++---------
 flang/lib/Lower/OpenMP/OpenMP.cpp             | 14 +++++------
 flang/lib/Parser/openmp-parsers.cpp           | 19 ++++++++-------
 flang/lib/Parser/unparse.cpp                  | 10 ++++++--
 flang/lib/Semantics/check-omp-structure.cpp   |  8 +++----
 flang/lib/Semantics/check-omp-structure.h     |  4 ++--
 flang/test/Lower/OpenMP/Todo/assumes.f90      |  6 +++--
 ...in-assumes.f90 => declarative-assumes.f90} |  5 ++--
 flang/test/Parser/OpenMP/assumption.f90       | 16 +++++++------
 10 files changed, 60 insertions(+), 51 deletions(-)
 rename flang/test/Lower/OpenMP/Todo/{begin-assumes.f90 => declarative-assumes.f90} (56%)

diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 09bbea491b9a4a..24f7501929b8be 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -673,10 +673,10 @@ class ParseTreeDumper {
   NODE(parser, OpenACCStandaloneConstruct)
   NODE(parser, OpenACCWaitConstruct)
   NODE(parser, OpenMPAssumeConstruct)
+  NODE(parser, OpenMPDeclarativeAssumes)
+  NODE(parser, OmpAssumesPartConstruct)
+  NODE(parser, OmpAssumesDirective)
   NODE(parser, OpenMPAssumesConstruct)
-  NODE(parser, OpenMPAssumesPartConstruct)
-  NODE(parser, OmpBeginAssumesDirective)
-  NODE(parser, OpenMPBeginAssumesConstruct)
   NODE(parser, OmpEndAssumesDirective)
   NODE(parser, OpenMPAtomicConstruct)
   NODE(parser, OpenMPBlockConstruct)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index d52a61089937a6..e75dad47452c12 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4455,14 +4455,14 @@ struct OpenMPAssumeConstruct {
   CharBlock source;
 };
 
-struct OpenMPAssumesConstruct {
-  TUPLE_CLASS_BOILERPLATE(OpenMPAssumesConstruct);
+struct OpenMPDeclarativeAssumes {
+  TUPLE_CLASS_BOILERPLATE(OpenMPDeclarativeAssumes);
   std::tuple<Verbatim, OmpClauseList> t;
   CharBlock source;
 };
 
-struct OmpBeginAssumesDirective {
-  TUPLE_CLASS_BOILERPLATE(OmpBeginAssumesDirective);
+struct OmpAssumesDirective {
+  TUPLE_CLASS_BOILERPLATE(OmpAssumesDirective);
   std::tuple<Verbatim, OmpClauseList> t;
   CharBlock source;
 };
@@ -4474,14 +4474,14 @@ struct OmpEndAssumesDirective {
 
 //    structured-block
 // ...
-struct OpenMPAssumesPartConstruct {
-  WRAPPER_CLASS_BOILERPLATE(OpenMPAssumesPartConstruct, Block);
+struct OmpAssumesPartConstruct {
+  WRAPPER_CLASS_BOILERPLATE(OmpAssumesPartConstruct, Block);
   CharBlock source;
 };
 
-struct OpenMPBeginAssumesConstruct {
-  TUPLE_CLASS_BOILERPLATE(OpenMPBeginAssumesConstruct);
-  std::tuple<OmpBeginAssumesDirective, OpenMPAssumesPartConstruct,
+struct OpenMPAssumesConstruct {
+  TUPLE_CLASS_BOILERPLATE(OpenMPAssumesConstruct);
+  std::tuple<OmpAssumesDirective, OmpAssumesPartConstruct,
       OmpEndAssumesDirective>
       t;
   CharBlock source;
@@ -4620,7 +4620,8 @@ struct OpenMPDeclarativeAllocate {
 struct OpenMPDeclarativeConstruct {
   UNION_CLASS_BOILERPLATE(OpenMPDeclarativeConstruct);
   CharBlock source;
-  std::variant<OpenMPDeclarativeAllocate, OpenMPAssumesConstruct, OpenMPDeclareMapperConstruct,
+  std::variant<OpenMPDeclarativeAllocate, OpenMPAssumesConstruct, OpenMPDeclarativeAssume,
+      OpenMPDeclareMapperConstruct,
       OpenMPDeclareReductionConstruct, OpenMPDeclareSimdConstruct,
       OpenMPDeclareTargetConstruct, OpenMPThreadprivate,
       OpenMPRequiresConstruct, OpenMPUtilityConstruct>
@@ -4910,7 +4911,7 @@ struct OpenMPConstruct {
       OpenMPSectionConstruct, OpenMPLoopConstruct, OpenMPBlockConstruct,
       OpenMPAtomicConstruct, OpenMPDeclarativeAllocate, OpenMPDispatchConstruct,
       OpenMPUtilityConstruct, OpenMPExecutableAllocate,
-      OpenMPAllocatorsConstruct, OpenMPAssumeConstruct, OpenMPBeginAssumesConstruct, OpenMPCriticalConstruct>
+      OpenMPAllocatorsConstruct, OpenMPAssumeConstruct, OpenMPCriticalConstruct>
       u;
 };
 
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 70f5c5a27ffdc0..7a0ac00225ff87 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -3079,7 +3079,7 @@ genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
 static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
                    semantics::SemanticsContext &semaCtx,
                    lower::pft::Evaluation &eval,
-                   const parser::OpenMPAssumesConstruct &assumesConstruct) {
+                   const parser::OpenMPDeclarativeAssumes &assumesConstruct) {
   TODO(converter.getCurrentLocation(), "OpenMP ASSUMES declaration");
 }
 
@@ -3390,13 +3390,13 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
   TODO(clauseLocation, "OpenMP ASSUME construct");
 }
 
-static void
-genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
-       semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
-       const parser::OpenMPBeginAssumesConstruct &beginAssumesConstruct) {
+static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
+                   semantics::SemanticsContext &semaCtx,
+                   lower::pft::Evaluation &eval,
+                   const parser::OpenMPAssumesConstruct &assumesConstruct) {
   mlir::Location clauseLocation =
-      converter.genLocation(beginAssumesConstruct.source);
-  TODO(clauseLocation, "OpenMP BEGIN ASSUMES construct");
+      converter.genLocation(assumesConstruct.source);
+  TODO(clauseLocation, "OpenMP ASSUMES construct");
 }
 
 static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index ad3313b6ddafa9..c8daf834f0c585 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1296,14 +1296,14 @@ TYPE_PARSER(
     lookAhead(endOmpLine / !statement(allocateStmt)))
 
 // Assumes Construct
-TYPE_PARSER(sourced(construct<OpenMPAssumesConstruct>(
+TYPE_PARSER(sourced(construct<OpenMPDeclarativeAssumes>(
     verbatim("ASSUMES"_tok), Parser<OmpClauseList>{})))
 
 // Declarative constructs
 TYPE_PARSER(startOmpLine >>
     withMessage("expected OpenMP construct"_err_en_US,
         sourced(construct<OpenMPDeclarativeConstruct>(
-                Parser<OpenMPAssumesConstruct>{}) ||
+                Parser<OpenMPDeclarativeAssumes>{}) ||
             construct<OpenMPDeclarativeConstruct>(
                 Parser<OpenMPDeclareReductionConstruct>{}) ||
             construct<OpenMPDeclarativeConstruct>(
@@ -1327,17 +1327,17 @@ TYPE_PARSER(sourced(construct<OpenMPAssumeConstruct>(
                         verbatim("ASSUME"_tok), Parser<OmpClauseList>{}) /
     endOmpLine))
 
-TYPE_PARSER(sourced(construct<OmpBeginAssumesDirective>(
-    "BEGIN"_tok >> verbatim("ASSUMES"_tok), Parser<OmpClauseList>{})))
+TYPE_PARSER(sourced(construct<OmpAssumesDirective>(
+    verbatim("ASSUMES"_tok), Parser<OmpClauseList>{})))
 
 TYPE_PARSER(sourced(construct<OmpEndAssumesDirective>(
     verbatim(startOmpLine >> "END ASSUMES"_tok))))
 
-TYPE_PARSER(construct<OpenMPAssumesPartConstruct>(block))
+TYPE_PARSER(construct<OmpAssumesPartConstruct>(block))
 
-TYPE_PARSER(sourced(construct<OpenMPBeginAssumesConstruct>(
-    Parser<OmpBeginAssumesDirective>{} / endOmpLine,
-    Parser<OpenMPAssumesPartConstruct>{},
+TYPE_PARSER(sourced(construct<OpenMPAssumesConstruct>(
+    Parser<OmpAssumesDirective>{} / endOmpLine,
+    Parser<OmpAssumesPartConstruct>{},
     Parser<OmpEndAssumesDirective>{} / endOmpLine)))
 
 // Block Construct
@@ -1387,8 +1387,7 @@ TYPE_CONTEXT_PARSER("OpenMP construct"_en_US,
                 construct<OpenMPConstruct>(Parser<OpenMPExecutableAllocate>{}),
                 construct<OpenMPConstruct>(Parser<OpenMPAllocatorsConstruct>{}),
                 construct<OpenMPConstruct>(Parser<OpenMPDeclarativeAllocate>{}),
-                construct<OpenMPConstruct>(
-                    Parser<OpenMPBeginAssumesConstruct>{}),
+                construct<OpenMPConstruct>(Parser<OpenMPAssumesConstruct>{}),
                 construct<OpenMPConstruct>(Parser<OpenMPAssumeConstruct>{}),
                 construct<OpenMPConstruct>(Parser<OpenMPCriticalConstruct>{}))))
 
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 05dad8cca873b7..d3b9deb053ba2f 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2648,9 +2648,9 @@ class UnparseVisitor {
     Put("\n");
     EndOpenMP();
   }
-  void Unparse(const OmpBeginAssumesDirective &x) {
+  void Unparse(const OmpAssumesDirective &x) {
     BeginOpenMP();
-    Word("!$OMP BEGIN ASSUMES");
+    Word("!$OMP ASSUMES");
     Walk(std::get<OmpClauseList>(x.t), ", ");
     Put("\n");
     EndOpenMP();
@@ -2718,6 +2718,12 @@ class UnparseVisitor {
     Put("\n");
     EndOpenMP();
   }
+  bool Pre(const OpenMPDeclarativeAssumes &x) {
+    Word("!$OMP ASSUMES ");
+    Walk(std::get<OmpClauseList>(x.t));
+    Put("\n");
+    EndOpenMP();
+  }
   void Unparse(const OpenMPDeclareMapperConstruct &z) {
     BeginOpenMP();
     Word("!$OMP DECLARE MAPPER (");
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index b7d9c65537ede7..e72fcd6b344bca 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1260,19 +1260,19 @@ void OmpStructureChecker::Leave(const parser::OpenMPAssumeConstruct &) {
   dirContext_.pop_back();
 }
 
-void OmpStructureChecker::Enter(const parser::OpenMPAssumesConstruct &x) {
+void OmpStructureChecker::Enter(const parser::OpenMPDeclarativeAssumes &x) {
   PushContextAndClauseSets(x.source, llvm::omp::Directive::OMPD_assumes);
 }
 
-void OmpStructureChecker::Leave(const parser::OpenMPAssumesConstruct &) {
+void OmpStructureChecker::Leave(const parser::OpenMPDeclarativeAssumes &) {
   dirContext_.pop_back();
 }
 
-void OmpStructureChecker::Enter(const parser::OpenMPBeginAssumesConstruct &x) {
+void OmpStructureChecker::Enter(const parser::OpenMPAssumesConstruct &x) {
   PushContextAndClauseSets(x.source, llvm::omp::Directive::OMPD_assumes);
 }
 
-void OmpStructureChecker::Leave(const parser::OpenMPBeginAssumesConstruct &) {
+void OmpStructureChecker::Leave(const parser::OpenMPAssumesConstruct &) {
   dirContext_.pop_back();
 }
 
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index bc754511c4754a..eabb7637562869 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -83,10 +83,10 @@ class OmpStructureChecker
 
   void Enter(const parser::OpenMPAssumeConstruct &);
   void Leave(const parser::OpenMPAssumeConstruct &);
+  void Enter(const parser::OpenMPDeclarativeAssumes &);
+  void Leave(const parser::OpenMPDeclarativeAssumes &);
   void Enter(const parser::OpenMPAssumesConstruct &);
   void Leave(const parser::OpenMPAssumesConstruct &);
-  void Enter(const parser::OpenMPBeginAssumesConstruct &);
-  void Leave(const parser::OpenMPBeginAssumesConstruct &);
   void Enter(const parser::OpenMPBlockConstruct &);
   void Leave(const parser::OpenMPBlockConstruct &);
   void Leave(const parser::OmpBeginBlockDirective &);
diff --git a/flang/test/Lower/OpenMP/Todo/assumes.f90 b/flang/test/Lower/OpenMP/Todo/assumes.f90
index 3ef4bd857612fd..14be4a0a63918d 100644
--- a/flang/test/Lower/OpenMP/Todo/assumes.f90
+++ b/flang/test/Lower/OpenMP/Todo/assumes.f90
@@ -1,8 +1,10 @@
 ! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1 | FileCheck %s
 
-! CHECK: not yet implemented: OpenMP ASSUMES declaration
+! CHECK: not yet implemented: OpenMP ASSUMES construct
 program p
-!$omp assumes no_openmp
   integer r
+  r = 1
+!$omp assumes no_parallelism
   print *,r
+!$omp end assumes
 end program p
diff --git a/flang/test/Lower/OpenMP/Todo/begin-assumes.f90 b/flang/test/Lower/OpenMP/Todo/declarative-assumes.f90
similarity index 56%
rename from flang/test/Lower/OpenMP/Todo/begin-assumes.f90
rename to flang/test/Lower/OpenMP/Todo/declarative-assumes.f90
index 5aad8be417a35b..3ef4bd857612fd 100644
--- a/flang/test/Lower/OpenMP/Todo/begin-assumes.f90
+++ b/flang/test/Lower/OpenMP/Todo/declarative-assumes.f90
@@ -1,9 +1,8 @@
 ! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1 | FileCheck %s
 
-! CHECK: not yet implemented: OpenMP BEGIN ASSUMES construct
+! CHECK: not yet implemented: OpenMP ASSUMES declaration
 program p
+!$omp assumes no_openmp
   integer r
-!$omp begin assumes no_parallelism
   print *,r
-!$omp end assumes
 end program p
diff --git a/flang/test/Parser/OpenMP/assumption.f90 b/flang/test/Parser/OpenMP/assumption.f90
index 80c15cbf6c3109..d5c1572f634e3d 100644
--- a/flang/test/Parser/OpenMP/assumption.f90
+++ b/flang/test/Parser/OpenMP/assumption.f90
@@ -31,16 +31,18 @@ end subroutine sub1
 
 subroutine sub2
   integer :: r
-!CHECK !$OMP BEGIN ASSUMES NO_OPENMP
-!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPBeginAssumesConstruct
-!PARSE-TREE: OmpBeginAssumesDirective
+  integer :: v
+!CHECK !$OMP ASSUMES NO_OPENMP
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumesConstruct
+!PARSE-TREE: OmpAssumesDirective
 !PARSE-TREE: Verbatim
 !PARSE-TREE: OmpClauseList -> OmpClause -> NoOpenmp
-!PARSE-TREE: OpenMPAssumesPartConstruct -> Block
+!PARSE-TREE: OmpAssumesPartConstruct -> Block
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt
 !PARSE-TREE: Expr -> Add
-!PARSE-TREE: OmpEndAssumesDirective
-  !$omp begin assumes no_openmp
+  !PARSE-TREE: OmpEndAssumesDirective
+  v = 87
+  !$omp assumes no_openmp
   r = r + 1
 !CHECK !$OMP END ASSUMES
   !$omp end assumes
@@ -49,7 +51,7 @@ end subroutine sub2
 program p
 !CHECK !$OMP ASSUMES NO_OPENMP
 !PARSE-TREE: SpecificationPart
-!PARSE-TREE:   OpenMPDeclarativeConstruct -> OpenMPAssumesConstruct
+!PARSE-TREE:   OpenMPDeclarativeConstruct -> OpenMPDeclarativeAssumes
 !PARSE-TREE: Verbatim
 !PARSE-TREE: OmpClauseList -> OmpClause -> NoOpenmp
   !$omp assumes no_openmp

>From b5bd2579eaa254ea161de0e7f1a4e5069dae4596 Mon Sep 17 00:00:00 2001
From: Mats Petersson <mats.petersson at arm.com>
Date: Mon, 6 Jan 2025 20:07:16 +0000
Subject: [PATCH 4/6] Fix ASSUME -> ASSUMES and vice versa

---
 flang/include/flang/Parser/dump-parse-tree.h |  6 +--
 flang/include/flang/Parser/parse-tree.h      | 42 ++++++++------------
 flang/lib/Lower/OpenMP/OpenMP.cpp            | 12 +-----
 flang/lib/Parser/openmp-parsers.cpp          | 22 ++++------
 flang/lib/Parser/unparse.cpp                 | 13 ++----
 flang/lib/Semantics/check-omp-structure.cpp  | 11 +----
 flang/lib/Semantics/check-omp-structure.h    |  2 -
 flang/test/Lower/OpenMP/Todo/assume.f90      |  6 ++-
 flang/test/Lower/OpenMP/Todo/assumes.f90     |  8 +---
 flang/test/Parser/OpenMP/assumption.f90      | 16 ++++----
 10 files changed, 46 insertions(+), 92 deletions(-)

diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 24f7501929b8be..dd101fd342ced9 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -674,10 +674,8 @@ class ParseTreeDumper {
   NODE(parser, OpenACCWaitConstruct)
   NODE(parser, OpenMPAssumeConstruct)
   NODE(parser, OpenMPDeclarativeAssumes)
-  NODE(parser, OmpAssumesPartConstruct)
-  NODE(parser, OmpAssumesDirective)
-  NODE(parser, OpenMPAssumesConstruct)
-  NODE(parser, OmpEndAssumesDirective)
+  NODE(parser, OmpAssumeDirective)
+  NODE(parser, OmpEndAssumeDirective)
   NODE(parser, OpenMPAtomicConstruct)
   NODE(parser, OpenMPBlockConstruct)
   NODE(parser, OpenMPCancelConstruct)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index e75dad47452c12..588383f867177b 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4446,44 +4446,36 @@ struct OpenMPUtilityConstruct {
 
 // Ref: [5.2: 213-216]
 //
-// assume-construct ->
-//   ASSUME absent-clause | contains-clause | holds-clause | no-openmp-clause |
+// assumes-construct ->
+//   ASSUMES absent-clause | contains-clause | holds-clause | no-openmp-clause |
 //          no-openmp-routines-clause | no-parallelism-clause
-struct OpenMPAssumeConstruct {
-  TUPLE_CLASS_BOILERPLATE(OpenMPAssumeConstruct);
-  std::tuple<Verbatim, OmpClauseList> t;
-  CharBlock source;
-};
-
 struct OpenMPDeclarativeAssumes {
   TUPLE_CLASS_BOILERPLATE(OpenMPDeclarativeAssumes);
   std::tuple<Verbatim, OmpClauseList> t;
   CharBlock source;
 };
 
-struct OmpAssumesDirective {
-  TUPLE_CLASS_BOILERPLATE(OmpAssumesDirective);
+struct OmpAssumeDirective {
+  TUPLE_CLASS_BOILERPLATE(OmpAssumeDirective);
   std::tuple<Verbatim, OmpClauseList> t;
   CharBlock source;
 };
 
-struct OmpEndAssumesDirective {
-  WRAPPER_CLASS_BOILERPLATE(OmpEndAssumesDirective, Verbatim);
+struct OmpEndAssumeDirective {
+  WRAPPER_CLASS_BOILERPLATE(OmpEndAssumeDirective, Verbatim);
   CharBlock source;
 };
 
-//    structured-block
-// ...
-struct OmpAssumesPartConstruct {
-  WRAPPER_CLASS_BOILERPLATE(OmpAssumesPartConstruct, Block);
-  CharBlock source;
-};
-
-struct OpenMPAssumesConstruct {
-  TUPLE_CLASS_BOILERPLATE(OpenMPAssumesConstruct);
-  std::tuple<OmpAssumesDirective, OmpAssumesPartConstruct,
-      OmpEndAssumesDirective>
-      t;
+// Ref: [5.2: 213-216]
+//
+// assume-construct ->
+//   ASSUME absent-clause | contains-clause | holds_clause | no-openmp-clause
+//          no-openmp-routines-clause | no-parallelism-clause
+//       block
+//   [END ASSUME]
+struct OpenMPAssumeConstruct {
+  TUPLE_CLASS_BOILERPLATE(OpenMPAssumeConstruct);
+  std::tuple<OmpAssumeDirective, Block, std::optional<OmpEndAssumeDirective>> t;
   CharBlock source;
 };
 
@@ -4620,7 +4612,7 @@ struct OpenMPDeclarativeAllocate {
 struct OpenMPDeclarativeConstruct {
   UNION_CLASS_BOILERPLATE(OpenMPDeclarativeConstruct);
   CharBlock source;
-  std::variant<OpenMPDeclarativeAllocate, OpenMPAssumesConstruct, OpenMPDeclarativeAssume,
+  std::variant<OpenMPDeclarativeAllocate, OpenMPAssumeConstruct, OpenMPDeclarativeAssumes,
       OpenMPDeclareMapperConstruct,
       OpenMPDeclareReductionConstruct, OpenMPDeclareSimdConstruct,
       OpenMPDeclareTargetConstruct, OpenMPThreadprivate,
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 7a0ac00225ff87..6931e27ab2f420 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -3385,20 +3385,10 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
                    semantics::SemanticsContext &semaCtx,
                    lower::pft::Evaluation &eval,
                    const parser::OpenMPAssumeConstruct &assumeConstruct) {
-  const auto &verbatim = std::get<parser::Verbatim>(assumeConstruct.t);
-  mlir::Location clauseLocation = converter.genLocation(verbatim.source);
+  mlir::Location clauseLocation = converter.genLocation(assumeConstruct.source);
   TODO(clauseLocation, "OpenMP ASSUME construct");
 }
 
-static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
-                   semantics::SemanticsContext &semaCtx,
-                   lower::pft::Evaluation &eval,
-                   const parser::OpenMPAssumesConstruct &assumesConstruct) {
-  mlir::Location clauseLocation =
-      converter.genLocation(assumesConstruct.source);
-  TODO(clauseLocation, "OpenMP ASSUMES construct");
-}
-
 static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
                    semantics::SemanticsContext &semaCtx,
                    lower::pft::Evaluation &eval,
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index c8daf834f0c585..b073bf67c3e58d 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1323,22 +1323,15 @@ TYPE_PARSER(startOmpLine >>
             endOmpLine))
 
 // Assume Construct
-TYPE_PARSER(sourced(construct<OpenMPAssumeConstruct>(
-                        verbatim("ASSUME"_tok), Parser<OmpClauseList>{}) /
-    endOmpLine))
+TYPE_PARSER(sourced(construct<OmpAssumeDirective>(
+    verbatim("ASSUME"_tok), Parser<OmpClauseList>{})))
 
-TYPE_PARSER(sourced(construct<OmpAssumesDirective>(
-    verbatim("ASSUMES"_tok), Parser<OmpClauseList>{})))
-
-TYPE_PARSER(sourced(construct<OmpEndAssumesDirective>(
-    verbatim(startOmpLine >> "END ASSUMES"_tok))))
+TYPE_PARSER(sourced(construct<OmpEndAssumeDirective>(
+    verbatim(startOmpLine >> "END ASSUME"_tok))))
 
-TYPE_PARSER(construct<OmpAssumesPartConstruct>(block))
-
-TYPE_PARSER(sourced(construct<OpenMPAssumesConstruct>(
-    Parser<OmpAssumesDirective>{} / endOmpLine,
-    Parser<OmpAssumesPartConstruct>{},
-    Parser<OmpEndAssumesDirective>{} / endOmpLine)))
+TYPE_PARSER(sourced(
+    construct<OpenMPAssumeConstruct>(Parser<OmpAssumeDirective>{} / endOmpLine,
+        block, maybe(Parser<OmpEndAssumeDirective>{} / endOmpLine))))
 
 // Block Construct
 TYPE_PARSER(construct<OpenMPBlockConstruct>(
@@ -1387,7 +1380,6 @@ TYPE_CONTEXT_PARSER("OpenMP construct"_en_US,
                 construct<OpenMPConstruct>(Parser<OpenMPExecutableAllocate>{}),
                 construct<OpenMPConstruct>(Parser<OpenMPAllocatorsConstruct>{}),
                 construct<OpenMPConstruct>(Parser<OpenMPDeclarativeAllocate>{}),
-                construct<OpenMPConstruct>(Parser<OpenMPAssumesConstruct>{}),
                 construct<OpenMPConstruct>(Parser<OpenMPAssumeConstruct>{}),
                 construct<OpenMPConstruct>(Parser<OpenMPCriticalConstruct>{}))))
 
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index d3b9deb053ba2f..af349d9548a43a 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2641,23 +2641,16 @@ class UnparseVisitor {
       Walk(*end);
     }
   }
-  void Unparse(const OpenMPAssumeConstruct &x) {
+  void Unparse(const OmpAssumeDirective &x) {
     BeginOpenMP();
     Word("!$OMP ASSUME");
     Walk(std::get<OmpClauseList>(x.t), ", ");
     Put("\n");
     EndOpenMP();
   }
-  void Unparse(const OmpAssumesDirective &x) {
+  void Unparse(const OmpEndAssumeDirective &x) {
     BeginOpenMP();
-    Word("!$OMP ASSUMES");
-    Walk(std::get<OmpClauseList>(x.t), ", ");
-    Put("\n");
-    EndOpenMP();
-  }
-  void Unparse(const OmpEndAssumesDirective &x) {
-    BeginOpenMP();
-    Word("!$OMP END ASSUMES\n");
+    Word("!$OMP END ASSUME\n");
     EndOpenMP();
   }
   void Unparse(const OmpCriticalDirective &x) {
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index e72fcd6b344bca..ff3fbf51ab2cf3 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1252,8 +1252,7 @@ void OmpStructureChecker::CheckMasterNesting(
 }
 
 void OmpStructureChecker::Enter(const parser::OpenMPAssumeConstruct &x) {
-  const auto &dir{std::get<parser::Verbatim>(x.t)};
-  PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_assume);
+  PushContextAndClauseSets(x.source, llvm::omp::Directive::OMPD_assume);
 }
 
 void OmpStructureChecker::Leave(const parser::OpenMPAssumeConstruct &) {
@@ -1268,14 +1267,6 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclarativeAssumes &) {
   dirContext_.pop_back();
 }
 
-void OmpStructureChecker::Enter(const parser::OpenMPAssumesConstruct &x) {
-  PushContextAndClauseSets(x.source, llvm::omp::Directive::OMPD_assumes);
-}
-
-void OmpStructureChecker::Leave(const parser::OpenMPAssumesConstruct &) {
-  dirContext_.pop_back();
-}
-
 void OmpStructureChecker::Leave(const parser::OpenMPBlockConstruct &) {
   if (GetDirectiveNest(TargetBlockOnlyTeams)) {
     ExitDirectiveNest(TargetBlockOnlyTeams);
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index eabb7637562869..8cec05063819b2 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -85,8 +85,6 @@ class OmpStructureChecker
   void Leave(const parser::OpenMPAssumeConstruct &);
   void Enter(const parser::OpenMPDeclarativeAssumes &);
   void Leave(const parser::OpenMPDeclarativeAssumes &);
-  void Enter(const parser::OpenMPAssumesConstruct &);
-  void Leave(const parser::OpenMPAssumesConstruct &);
   void Enter(const parser::OpenMPBlockConstruct &);
   void Leave(const parser::OpenMPBlockConstruct &);
   void Leave(const parser::OmpBeginBlockDirective &);
diff --git a/flang/test/Lower/OpenMP/Todo/assume.f90 b/flang/test/Lower/OpenMP/Todo/assume.f90
index 6942c7774663ed..1216888efabd1b 100644
--- a/flang/test/Lower/OpenMP/Todo/assume.f90
+++ b/flang/test/Lower/OpenMP/Todo/assume.f90
@@ -2,5 +2,9 @@
 
 ! CHECK: not yet implemented: OpenMP ASSUME construct
 program p
-  !$omp assume no_openmp
+  integer r
+  r = 1
+!$omp assume no_parallelism
+  print *,r
+!$omp end assume
 end program p
diff --git a/flang/test/Lower/OpenMP/Todo/assumes.f90 b/flang/test/Lower/OpenMP/Todo/assumes.f90
index 14be4a0a63918d..ac26ed14ded3c6 100644
--- a/flang/test/Lower/OpenMP/Todo/assumes.f90
+++ b/flang/test/Lower/OpenMP/Todo/assumes.f90
@@ -1,10 +1,6 @@
 ! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1 | FileCheck %s
 
-! CHECK: not yet implemented: OpenMP ASSUMES construct
+! CHECK: not yet implemented: OpenMP ASSUMES declaration
 program p
-  integer r
-  r = 1
-!$omp assumes no_parallelism
-  print *,r
-!$omp end assumes
+  !$omp assumes no_openmp
 end program p
diff --git a/flang/test/Parser/OpenMP/assumption.f90 b/flang/test/Parser/OpenMP/assumption.f90
index d5c1572f634e3d..fc74683e075200 100644
--- a/flang/test/Parser/OpenMP/assumption.f90
+++ b/flang/test/Parser/OpenMP/assumption.f90
@@ -32,20 +32,20 @@ end subroutine sub1
 subroutine sub2
   integer :: r
   integer :: v
-!CHECK !$OMP ASSUMES NO_OPENMP
-!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumesConstruct
-!PARSE-TREE: OmpAssumesDirective
+!CHECK !$OMP ASSUME NO_OPENMP
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumeConstruct
+!PARSE-TREE: OmpAssumeDirective
 !PARSE-TREE: Verbatim
 !PARSE-TREE: OmpClauseList -> OmpClause -> NoOpenmp
-!PARSE-TREE: OmpAssumesPartConstruct -> Block
+!PARSE-TREE: Block
 !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt
 !PARSE-TREE: Expr -> Add
-  !PARSE-TREE: OmpEndAssumesDirective
+!PARSE-TREE: OmpEndAssumeDirective
   v = 87
-  !$omp assumes no_openmp
+  !$omp assume no_openmp
   r = r + 1
-!CHECK !$OMP END ASSUMES
-  !$omp end assumes
+!CHECK !$OMP END ASSUME
+  !$omp end assume
 end subroutine sub2
   
 program p

>From d8e85e018deaf1b258a7d7ee48d915a2bd8d8e08 Mon Sep 17 00:00:00 2001
From: Kiran Chandramohan <kiran.chandramohan at arm.com>
Date: Sat, 1 Feb 2025 17:10:24 +0000
Subject: [PATCH 5/6] Fixes for rebase

---
 flang/include/flang/Parser/parse-tree.h |  9 ++++-----
 flang/lib/Lower/OpenMP/OpenMP.cpp       |  3 +++
 flang/lib/Parser/unparse.cpp            | 11 +----------
 3 files changed, 8 insertions(+), 15 deletions(-)

diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 588383f867177b..49defb4d1ca776 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4612,11 +4612,10 @@ struct OpenMPDeclarativeAllocate {
 struct OpenMPDeclarativeConstruct {
   UNION_CLASS_BOILERPLATE(OpenMPDeclarativeConstruct);
   CharBlock source;
-  std::variant<OpenMPDeclarativeAllocate, OpenMPAssumeConstruct, OpenMPDeclarativeAssumes,
-      OpenMPDeclareMapperConstruct,
-      OpenMPDeclareReductionConstruct, OpenMPDeclareSimdConstruct,
-      OpenMPDeclareTargetConstruct, OpenMPThreadprivate,
-      OpenMPRequiresConstruct, OpenMPUtilityConstruct>
+  std::variant<OpenMPDeclarativeAllocate, OpenMPDeclarativeAssumes,
+      OpenMPDeclareMapperConstruct, OpenMPDeclareReductionConstruct,
+      OpenMPDeclareSimdConstruct, OpenMPDeclareTargetConstruct,
+      OpenMPThreadprivate, OpenMPRequiresConstruct, OpenMPUtilityConstruct>
       u;
 };
 
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 6931e27ab2f420..b37e308519dfd8 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -367,6 +367,9 @@ extractOmpDirective(const parser::OpenMPConstruct &ompConstruct) {
           [](const parser::OpenMPAllocatorsConstruct &c) {
             return llvm::omp::OMPD_allocators;
           },
+          [](const parser::OpenMPAssumeConstruct &c) {
+            return llvm::omp::OMPD_assume;
+          },
           [](const parser::OpenMPAtomicConstruct &c) {
             return llvm::omp::OMPD_atomic;
           },
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index af349d9548a43a..47ad6fcc5df6b3 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2115,9 +2115,6 @@ class UnparseVisitor {
                   },
         x.u);
   }
-  void Unparse(const llvm::omp::Directive &x) {
-    Word(llvm::omp::getOpenMPDirectiveName(x));
-  }
   void Unparse(const OmpDirectiveNameModifier &x) {
     Word(llvm::omp::getOpenMPDirectiveName(x.v));
   }
@@ -2704,19 +2701,13 @@ class UnparseVisitor {
     Walk(std::get<std::optional<OmpReductionInitializerClause>>(x.t));
     EndOpenMP();
   }
-  bool Pre(const OpenMPAssumesConstruct &x) {
+  void Unparse(const OpenMPDeclarativeAssumes &x) {
     BeginOpenMP();
     Word("!$OMP ASSUMES ");
     Walk(std::get<OmpClauseList>(x.t));
     Put("\n");
     EndOpenMP();
   }
-  bool Pre(const OpenMPDeclarativeAssumes &x) {
-    Word("!$OMP ASSUMES ");
-    Walk(std::get<OmpClauseList>(x.t));
-    Put("\n");
-    EndOpenMP();
-  }
   void Unparse(const OpenMPDeclareMapperConstruct &z) {
     BeginOpenMP();
     Word("!$OMP DECLARE MAPPER (");

>From 6725e698c65a4c93a950a1ce1e84a5568ce71690 Mon Sep 17 00:00:00 2001
From: Kiran Chandramohan <kiran.chandramohan at arm.com>
Date: Sat, 1 Feb 2025 21:04:24 +0000
Subject: [PATCH 6/6] Fix formatting

---
 flang/lib/Parser/openmp-parsers.cpp | 42 ++++++++++++++---------------
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index b073bf67c3e58d..d5573e47fa7b36 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1300,27 +1300,27 @@ TYPE_PARSER(sourced(construct<OpenMPDeclarativeAssumes>(
     verbatim("ASSUMES"_tok), Parser<OmpClauseList>{})))
 
 // Declarative constructs
-TYPE_PARSER(startOmpLine >>
-    withMessage("expected OpenMP construct"_err_en_US,
-        sourced(construct<OpenMPDeclarativeConstruct>(
-                Parser<OpenMPDeclarativeAssumes>{}) ||
-            construct<OpenMPDeclarativeConstruct>(
-                Parser<OpenMPDeclareReductionConstruct>{}) ||
-            construct<OpenMPDeclarativeConstruct>(
-                Parser<OpenMPDeclareMapperConstruct>{}) ||
-            construct<OpenMPDeclarativeConstruct>(
-                Parser<OpenMPDeclareSimdConstruct>{}) ||
-            construct<OpenMPDeclarativeConstruct>(
-                Parser<OpenMPDeclareTargetConstruct>{}) ||
-            construct<OpenMPDeclarativeConstruct>(
-                Parser<OpenMPDeclarativeAllocate>{}) ||
-            construct<OpenMPDeclarativeConstruct>(
-                Parser<OpenMPRequiresConstruct>{}) ||
-            construct<OpenMPDeclarativeConstruct>(
-                Parser<OpenMPThreadprivate>{}) ||
-            construct<OpenMPDeclarativeConstruct>(
-                Parser<OpenMPUtilityConstruct>{})) /
-            endOmpLine))
+TYPE_PARSER(
+    startOmpLine >> withMessage("expected OpenMP construct"_err_en_US,
+                        sourced(construct<OpenMPDeclarativeConstruct>(
+                                    Parser<OpenMPDeclarativeAssumes>{}) ||
+                            construct<OpenMPDeclarativeConstruct>(
+                                Parser<OpenMPDeclareReductionConstruct>{}) ||
+                            construct<OpenMPDeclarativeConstruct>(
+                                Parser<OpenMPDeclareMapperConstruct>{}) ||
+                            construct<OpenMPDeclarativeConstruct>(
+                                Parser<OpenMPDeclareSimdConstruct>{}) ||
+                            construct<OpenMPDeclarativeConstruct>(
+                                Parser<OpenMPDeclareTargetConstruct>{}) ||
+                            construct<OpenMPDeclarativeConstruct>(
+                                Parser<OpenMPDeclarativeAllocate>{}) ||
+                            construct<OpenMPDeclarativeConstruct>(
+                                Parser<OpenMPRequiresConstruct>{}) ||
+                            construct<OpenMPDeclarativeConstruct>(
+                                Parser<OpenMPThreadprivate>{}) ||
+                            construct<OpenMPDeclarativeConstruct>(
+                                Parser<OpenMPUtilityConstruct>{})) /
+                            endOmpLine))
 
 // Assume Construct
 TYPE_PARSER(sourced(construct<OmpAssumeDirective>(



More information about the llvm-commits mailing list