[flang-commits] [flang] [llvm] [Flang][OMP]Add support for DECLARE MAPPER parsing and semantics (PR #115160)

Mats Petersson via flang-commits flang-commits at lists.llvm.org
Mon Nov 11 06:00:06 PST 2024


https://github.com/Leporacanthicus updated https://github.com/llvm/llvm-project/pull/115160

>From 8bc59ff7116dcaa215e4fbb2ee6a67304e0a7351 Mon Sep 17 00:00:00 2001
From: Mats Petersson <mats.petersson at arm.com>
Date: Mon, 21 Oct 2024 16:24:29 +0000
Subject: [PATCH 1/3] [Flang][OMP]Add support for DECLARE MAPPER parsing and
 semantics

Will hit a TODO in the lowering, which there are tests added
to check for this happening.
---
 flang/include/flang/Parser/dump-parse-tree.h  |  2 +
 flang/include/flang/Parser/parse-tree.h       | 16 ++++++-
 flang/lib/Lower/OpenMP/OpenMP.cpp             |  7 +++
 flang/lib/Parser/openmp-parsers.cpp           | 12 +++++
 flang/lib/Parser/unparse.cpp                  | 23 +++++++++
 flang/lib/Semantics/resolve-directives.cpp    |  9 ++++
 flang/lib/Semantics/resolve-names.cpp         | 26 +++++++++-
 .../Lower/OpenMP/Todo/omp-declare-mapper.f90  | 47 +++++++++++++++++++
 .../Parser/OpenMP/declare-mapper-unparse.f90  | 28 +++++++++++
 9 files changed, 168 insertions(+), 2 deletions(-)
 create mode 100644 flang/test/Lower/OpenMP/Todo/omp-declare-mapper.f90
 create mode 100644 flang/test/Parser/OpenMP/declare-mapper-unparse.f90

diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index bfeb23de535392..474185177317d4 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -504,6 +504,7 @@ class ParseTreeDumper {
   NODE(parser, OmpDeclareTargetSpecifier)
   NODE(parser, OmpDeclareTargetWithClause)
   NODE(parser, OmpDeclareTargetWithList)
+  NODE(parser, OmpDeclareMapperSpecifier)
   NODE(parser, OmpDefaultClause)
   NODE_ENUM(OmpDefaultClause, Type)
   NODE(parser, OmpDefaultmapClause)
@@ -612,6 +613,7 @@ class ParseTreeDumper {
   NODE(parser, OpenMPDeclareReductionConstruct)
   NODE(parser, OpenMPDeclareSimdConstruct)
   NODE(parser, OpenMPDeclareTargetConstruct)
+  NODE(parser, OpenMPDeclareMapperConstruct)
   NODE(parser, OmpMemoryOrderClause)
   NODE(parser, OmpAtomicClause)
   NODE(parser, OmpAtomicClauseList)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index d2c5b45d995813..77decb44e27e8c 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3872,6 +3872,19 @@ struct OpenMPDeclareTargetConstruct {
   std::tuple<Verbatim, OmpDeclareTargetSpecifier> t;
 };
 
+struct OmpDeclareMapperSpecifier {
+  TUPLE_CLASS_BOILERPLATE(OmpDeclareMapperSpecifier);
+  std::tuple<std::optional<Name>, TypeSpec, Name> t;
+};
+
+struct OpenMPDeclareMapperConstruct {
+  TUPLE_CLASS_BOILERPLATE(OpenMPDeclareMapperConstruct);
+  CharBlock source;
+  std::tuple<Verbatim, OmpDeclareMapperSpecifier,
+      std::list<std::list<OmpMapClause>>>
+      t;
+};
+
 // 2.16 declare-reduction -> DECLARE REDUCTION (reduction-identifier : type-list
 //                                              : combiner) [initializer-clause]
 struct OmpReductionCombiner {
@@ -3924,7 +3937,8 @@ struct OpenMPDeclarativeConstruct {
   CharBlock source;
   std::variant<OpenMPDeclarativeAllocate, OpenMPDeclareReductionConstruct,
       OpenMPDeclareSimdConstruct, OpenMPDeclareTargetConstruct,
-      OpenMPThreadprivate, OpenMPRequiresConstruct>
+      OpenMPThreadprivate, OpenMPRequiresConstruct,
+      OpenMPDeclareMapperConstruct>
       u;
 };
 
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 4f9e2347308aa1..83a6967c32a820 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -2597,6 +2597,13 @@ genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
   TODO(converter.getCurrentLocation(), "OpenMPDeclareSimdConstruct");
 }
 
+static void
+genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
+       semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
+       const parser::OpenMPDeclareMapperConstruct &declareMapperConstruct) {
+  TODO(converter.getCurrentLocation(), "OpenMPDeclareMapperConstruct");
+}
+
 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 7a0ecc59a2c5c5..39915b78c66e77 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -836,6 +836,16 @@ TYPE_PARSER(
 TYPE_PARSER(sourced(construct<OpenMPDeclareTargetConstruct>(
     verbatim("DECLARE TARGET"_tok), Parser<OmpDeclareTargetSpecifier>{})))
 
+// declare-mapper-specifier
+TYPE_PARSER(construct<OmpDeclareMapperSpecifier>(
+    maybe(name / ":" / !":"_tok), typeSpec / "::", name))
+
+// ?.? (not 4.5) Declare Mapper Construct
+TYPE_PARSER(sourced(
+    construct<OpenMPDeclareMapperConstruct>(verbatim("DECLARE MAPPER"_tok),
+        "(" >> Parser<OmpDeclareMapperSpecifier>{} / ")",
+        many("MAP" >> parenthesized(many(Parser<OmpMapClause>{}))))))
+
 TYPE_PARSER(construct<OmpReductionCombiner>(Parser<AssignmentStmt>{}) ||
     construct<OmpReductionCombiner>(
         construct<OmpReductionCombiner::FunctionCombiner>(
@@ -944,6 +954,8 @@ TYPE_PARSER(startOmpLine >>
     withMessage("expected OpenMP construct"_err_en_US,
         sourced(construct<OpenMPDeclarativeConstruct>(
                     Parser<OpenMPDeclareReductionConstruct>{}) ||
+            construct<OpenMPDeclarativeConstruct>(
+                Parser<OpenMPDeclareMapperConstruct>{}) ||
             construct<OpenMPDeclarativeConstruct>(
                 Parser<OpenMPDeclareSimdConstruct>{}) ||
             construct<OpenMPDeclarativeConstruct>(
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index bbb126dcdb6d5e..343c21df5619b8 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2665,6 +2665,29 @@ class UnparseVisitor {
               EndOpenMP();
               return false;
             },
+            [&](const OpenMPDeclareMapperConstruct &z) {
+              Word("DECLARE MAPPER (");
+              const auto &spec{std::get<OmpDeclareMapperSpecifier>(z.t)};
+              if (auto mapname{std::get<std::optional<Name>>(spec.t)}) {
+                Walk(mapname);
+                Put(":");
+              }
+              Walk(std::get<TypeSpec>(spec.t));
+              Put("::");
+              Walk(std::get<Name>(spec.t));
+              Put(")");
+
+              const auto &list{
+                  std::get<std::list<std::list<Fortran::parser::OmpMapClause>>>(
+                      z.t)};
+              for (const auto &m : list) {
+                Put(" MAP(");
+                Walk(m);
+                Put(")");
+              }
+              Put("\n");
+              return false;
+            },
             [&](const OpenMPDeclareReductionConstruct &) {
               Word("DECLARE REDUCTION ");
               return true;
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index c2b5b9673239b9..7748fa3a6eec3c 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -431,6 +431,9 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
   bool Pre(const parser::OpenMPDeclareTargetConstruct &);
   void Post(const parser::OpenMPDeclareTargetConstruct &) { PopContext(); }
 
+  bool Pre(const parser::OpenMPDeclareMapperConstruct &);
+  void Post(const parser::OpenMPDeclareMapperConstruct &) { PopContext(); }
+
   bool Pre(const parser::OpenMPThreadprivate &);
   void Post(const parser::OpenMPThreadprivate &) { PopContext(); }
 
@@ -1944,6 +1947,12 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPDeclareTargetConstruct &x) {
   return true;
 }
 
+bool OmpAttributeVisitor::Pre(const parser::OpenMPDeclareMapperConstruct &x) {
+  PushContext(x.source, llvm::omp::Directive::OMPD_declare_mapper);
+
+  return true;
+}
+
 bool OmpAttributeVisitor::Pre(const parser::OpenMPThreadprivate &x) {
   PushContext(x.source, llvm::omp::Directive::OMPD_threadprivate);
   const auto &list{std::get<parser::OmpObjectList>(x.t)};
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index e0a8246ebc752e..f93a6f7d1c742f 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1058,6 +1058,7 @@ class DeclarationVisitor : public ArraySpecVisitor,
   const parser::Name *ResolveDesignator(const parser::Designator &);
   int GetVectorElementKind(
       TypeCategory category, const std::optional<parser::KindSelector> &kind);
+  std::optional<DerivedTypeSpec> ResolveDerivedType(const parser::Name &);
 
 protected:
   bool BeginDecl();
@@ -1205,7 +1206,6 @@ class DeclarationVisitor : public ArraySpecVisitor,
   Symbol &DeclareProcEntity(
       const parser::Name &, Attrs, const Symbol *interface);
   void SetType(const parser::Name &, const DeclTypeSpec &);
-  std::optional<DerivedTypeSpec> ResolveDerivedType(const parser::Name &);
   std::optional<DerivedTypeSpec> ResolveExtendsType(
       const parser::Name &, const parser::Name *);
   Symbol *MakeTypeSymbol(const SourceName &, Details &&);
@@ -1468,6 +1468,10 @@ class OmpVisitor : public virtual DeclarationVisitor {
     AddOmpSourceRange(x.source);
     return true;
   }
+
+  bool Pre(const parser::OpenMPDeclareMapperConstruct &);
+  void Post(const parser::OpenMPDeclareMapperConstruct &) { PopScope(); };
+
   void Post(const parser::OmpBeginLoopDirective &) {
     messageHandler().set_currStmtSource(std::nullopt);
   }
@@ -1605,6 +1609,26 @@ void OmpVisitor::Post(const parser::OpenMPBlockConstruct &x) {
   }
 }
 
+bool OmpVisitor::Pre(const parser::OpenMPDeclareMapperConstruct &x) {
+  AddOmpSourceRange(x.source);
+  BeginDeclTypeSpec();
+  PushScope(Scope::Kind::OtherConstruct, nullptr);
+  const auto &spec{std::get<parser::OmpDeclareMapperSpecifier>(x.t)};
+  if (const auto &mapperName{
+          std::get<std::optional<Fortran::parser::Name>>(spec.t)}) {
+    Symbol *mapperSym{&MakeSymbol(*mapperName, Attrs{})};
+    mapperName->symbol = mapperSym;
+  }
+  Walk(std::get<Fortran::parser::TypeSpec>(spec.t));
+  const auto &varName{std::get<Fortran::parser::ObjectName>(spec.t)};
+  DeclareObjectEntity(varName);
+
+  Walk(std::get<std::list<std::list<Fortran::parser::OmpMapClause>>>(x.t));
+
+  EndDeclTypeSpec();
+  return false;
+}
+
 // Walk the parse tree and resolve names to symbols.
 class ResolveNamesVisitor : public virtual ScopeHandler,
                             public ModuleVisitor,
diff --git a/flang/test/Lower/OpenMP/Todo/omp-declare-mapper.f90 b/flang/test/Lower/OpenMP/Todo/omp-declare-mapper.f90
new file mode 100644
index 00000000000000..ebec4b4adb42a6
--- /dev/null
+++ b/flang/test/Lower/OpenMP/Todo/omp-declare-mapper.f90
@@ -0,0 +1,47 @@
+! This test checks lowering of OpenMP declare mapper Directive.
+
+! RUN: split-file %s %t
+! RUN: not %flang_fc1 -emit-fir -fopenmp %t/omp-declare-mapper-1.f90 2>&1 | FileCheck %t/omp-declare-mapper-1.f90
+! RUN  not %flang_fc1 -emit-fir -fopenmp %t/omp-declare-mapper-2.f90 2>&1 | FileCheck %t/omp-declare-mapper-2.f90
+
+!--- omp-declare-mapper-1.f90
+subroutine declare_mapper_1
+ integer,parameter      :: nvals = 250
+ type my_type
+   integer              :: num_vals
+   integer, allocatable :: values(:)
+ end type 
+
+ type my_type2
+   type (my_type)        :: my_type_var
+   type (my_type)        :: temp
+   real,dimension(nvals) :: unmapped
+   real,dimension(nvals) :: arr
+  end type
+  type (my_type2)        :: t
+  real                   :: x, y(nvals)
+  !$omp declare mapper (my_type :: var) map (var, var%values (1:var%num_vals))
+!CHECK: not yet implemented: OpenMPDeclareMapperConstruct
+end subroutine declare_mapper_1
+
+
+!--- omp-declare-mapper-2.f90
+subroutine declare_mapper_2
+ integer,parameter      :: nvals = 250
+ type my_type
+   integer              :: num_vals
+   integer, allocatable :: values(:)
+ end type 
+
+ type my_type2
+   type (my_type)        :: my_type_var
+   type (my_type)        :: temp
+   real,dimension(nvals) :: unmapped
+   real,dimension(nvals) :: arr
+  end type
+  type (my_type2)        :: t
+  real                   :: x, y(nvals)
+  !$omp declare mapper (my_mapper : my_type2 :: v) map (v%arr, x, y(:)) &
+  !$omp&                map (alloc : v%temp)
+!CHECK: not yet implemented: OpenMPDeclareMapperConstruct
+end subroutine declare_mapper_2
diff --git a/flang/test/Parser/OpenMP/declare-mapper-unparse.f90 b/flang/test/Parser/OpenMP/declare-mapper-unparse.f90
new file mode 100644
index 00000000000000..2842960cd02a09
--- /dev/null
+++ b/flang/test/Parser/OpenMP/declare-mapper-unparse.f90
@@ -0,0 +1,28 @@
+! RUN: %flang_fc1 -fdebug-unparse-no-sema -fopenmp %s | FileCheck --ignore-case %s
+! RUN: %flang_fc1 -fdebug-dump-parse-tree-no-sema -fopenmp %s | FileCheck --check-prefix="PARSE-TREE" %s
+program main
+!CHECK-LABEL: program main
+  implicit none
+
+  type ty
+     integer :: x
+  end type ty
+  
+
+!CHECK: !$OMP DECLARE MAPPER (mymapper:ty::mapped) MAP(mapped,mapped%x)
+  !$omp declare mapper(mymapper : ty :: mapped) map(mapped, mapped%x)
+
+!PARSE-TREE:      OpenMPDeclareMapperConstruct
+!PARSE-TREE:        OmpDeclareMapperSpecifier
+!PARSE-TREE:         Name = 'mymapper'
+!PARSE-TREE:         TypeSpec -> DerivedTypeSpec
+!PARSE-TREE:           Name = 'ty'
+!PARSE-TREE:         Name = 'mapped'    
+!PARSE-TREE:        OmpMapClause
+!PARSE-TREE:          OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'mapped'
+!PARSE-TREE:          OmpObject -> Designator -> DataRef -> StructureComponent
+!PARSE-TREE:           DataRef -> Name = 'mapped'
+!PARSE-TREE:           Name = 'x'  
+
+end program main
+!CHECK-LABEL: end program main

>From 66b01706eef8c151550846ac9ae0340c1340b4c8 Mon Sep 17 00:00:00 2001
From: Mats Petersson <mats.petersson at arm.com>
Date: Fri, 8 Nov 2024 14:31:30 +0000
Subject: [PATCH 2/3] Review updates

---
 flang/include/flang/Parser/parse-tree.h       | 12 +++++------
 flang/lib/Parser/openmp-parsers.cpp           |  9 ++++-----
 flang/lib/Parser/unparse.cpp                  |  9 +--------
 flang/lib/Semantics/check-omp-structure.cpp   | 20 +++++++++++++++++++
 flang/lib/Semantics/check-omp-structure.h     |  2 ++
 flang/lib/Semantics/resolve-directives.cpp    |  1 -
 flang/lib/Semantics/resolve-names.cpp         | 17 ++++++++++------
 .../Lower/OpenMP/Todo/omp-declare-mapper.f90  |  4 ++--
 llvm/include/llvm/Frontend/OpenMP/OMP.td      |  4 ++--
 9 files changed, 47 insertions(+), 31 deletions(-)

diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 77decb44e27e8c..8ae317a4f0e42c 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3880,9 +3880,7 @@ struct OmpDeclareMapperSpecifier {
 struct OpenMPDeclareMapperConstruct {
   TUPLE_CLASS_BOILERPLATE(OpenMPDeclareMapperConstruct);
   CharBlock source;
-  std::tuple<Verbatim, OmpDeclareMapperSpecifier,
-      std::list<std::list<OmpMapClause>>>
-      t;
+  std::tuple<Verbatim, OmpDeclareMapperSpecifier, OmpClauseList> t;
 };
 
 // 2.16 declare-reduction -> DECLARE REDUCTION (reduction-identifier : type-list
@@ -3935,10 +3933,10 @@ struct OpenMPDeclarativeAllocate {
 struct OpenMPDeclarativeConstruct {
   UNION_CLASS_BOILERPLATE(OpenMPDeclarativeConstruct);
   CharBlock source;
-  std::variant<OpenMPDeclarativeAllocate, OpenMPDeclareReductionConstruct,
-      OpenMPDeclareSimdConstruct, OpenMPDeclareTargetConstruct,
-      OpenMPThreadprivate, OpenMPRequiresConstruct,
-      OpenMPDeclareMapperConstruct>
+  std::variant<OpenMPDeclarativeAllocate, OpenMPDeclareMapperConstruct,
+      OpenMPDeclareReductionConstruct, OpenMPDeclareSimdConstruct,
+      OpenMPDeclareTargetConstruct, OpenMPThreadprivate,
+      OpenMPRequiresConstruct>
       u;
 };
 
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 39915b78c66e77..4867bf1d95d1f3 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -840,11 +840,10 @@ TYPE_PARSER(sourced(construct<OpenMPDeclareTargetConstruct>(
 TYPE_PARSER(construct<OmpDeclareMapperSpecifier>(
     maybe(name / ":" / !":"_tok), typeSpec / "::", name))
 
-// ?.? (not 4.5) Declare Mapper Construct
-TYPE_PARSER(sourced(
-    construct<OpenMPDeclareMapperConstruct>(verbatim("DECLARE MAPPER"_tok),
-        "(" >> Parser<OmpDeclareMapperSpecifier>{} / ")",
-        many("MAP" >> parenthesized(many(Parser<OmpMapClause>{}))))))
+// OpenMP 5.2: 5.8.8 Declare Mapper Construct
+TYPE_PARSER(sourced(construct<OpenMPDeclareMapperConstruct>(
+    verbatim("DECLARE MAPPER"_tok),
+    "(" >> Parser<OmpDeclareMapperSpecifier>{} / ")", Parser<OmpClauseList>{})))
 
 TYPE_PARSER(construct<OmpReductionCombiner>(Parser<AssignmentStmt>{}) ||
     construct<OmpReductionCombiner>(
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 343c21df5619b8..dde567fdb02af4 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2677,14 +2677,7 @@ class UnparseVisitor {
               Walk(std::get<Name>(spec.t));
               Put(")");
 
-              const auto &list{
-                  std::get<std::list<std::list<Fortran::parser::OmpMapClause>>>(
-                      z.t)};
-              for (const auto &m : list) {
-                Put(" MAP(");
-                Walk(m);
-                Put(")");
-              }
+              Walk(std::get<OmpClauseList>(z.t));
               Put("\n");
               return false;
             },
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 014604627f2cd1..193db88000a429 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1434,6 +1434,26 @@ void OmpStructureChecker::Leave(const parser::OmpDeclareTargetWithClause &x) {
   }
 }
 
+void OmpStructureChecker::Enter(const parser::OpenMPDeclareMapperConstruct &x) {
+  const auto &dir{std::get<parser::Verbatim>(x.t)};
+  PushContextAndClauseSets(
+      dir.source, llvm::omp::Directive::OMPD_declare_mapper);
+  const auto &spec{std::get<parser::OmpDeclareMapperSpecifier>(x.t)};
+  const auto &type = std::get<parser::TypeSpec>(spec.t);
+  if (const auto derivedTypeSpec{
+          std::get_if<parser::DerivedTypeSpec>(&type.u)}) {
+    if (derivedTypeSpec->derivedTypeSpec->typeSymbol().attrs().test(
+            Attr::ABSTRACT))
+      context_.Say(dir.source, "Type must not be abstract"_err_en_US);
+  } else {
+    context_.Say(dir.source, "Type is not a derived type"_err_en_US);
+  }
+}
+
+void OmpStructureChecker::Leave(const parser::OpenMPDeclareMapperConstruct &) {
+  dirContext_.pop_back();
+}
+
 void OmpStructureChecker::Enter(const parser::OpenMPDeclareTargetConstruct &x) {
   const auto &dir{std::get<parser::Verbatim>(x.t)};
   PushContext(dir.source, llvm::omp::Directive::OMPD_declare_target);
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index d9236be8bced4f..77b978ddd62079 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -90,6 +90,8 @@ class OmpStructureChecker
   void Leave(const parser::OpenMPDeclareSimdConstruct &);
   void Enter(const parser::OpenMPDeclarativeAllocate &);
   void Leave(const parser::OpenMPDeclarativeAllocate &);
+  void Enter(const parser::OpenMPDeclareMapperConstruct &);
+  void Leave(const parser::OpenMPDeclareMapperConstruct &);
   void Enter(const parser::OpenMPDeclareTargetConstruct &);
   void Leave(const parser::OpenMPDeclareTargetConstruct &);
   void Enter(const parser::OpenMPDepobjConstruct &);
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 7748fa3a6eec3c..0a87728537387d 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1949,7 +1949,6 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPDeclareTargetConstruct &x) {
 
 bool OmpAttributeVisitor::Pre(const parser::OpenMPDeclareMapperConstruct &x) {
   PushContext(x.source, llvm::omp::Directive::OMPD_declare_mapper);
-
   return true;
 }
 
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index f93a6f7d1c742f..0bbcf28e8ff6eb 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1058,7 +1058,6 @@ class DeclarationVisitor : public ArraySpecVisitor,
   const parser::Name *ResolveDesignator(const parser::Designator &);
   int GetVectorElementKind(
       TypeCategory category, const std::optional<parser::KindSelector> &kind);
-  std::optional<DerivedTypeSpec> ResolveDerivedType(const parser::Name &);
 
 protected:
   bool BeginDecl();
@@ -1206,6 +1205,7 @@ class DeclarationVisitor : public ArraySpecVisitor,
   Symbol &DeclareProcEntity(
       const parser::Name &, Attrs, const Symbol *interface);
   void SetType(const parser::Name &, const DeclTypeSpec &);
+  std::optional<DerivedTypeSpec> ResolveDerivedType(const parser::Name &);
   std::optional<DerivedTypeSpec> ResolveExtendsType(
       const parser::Name &, const parser::Name *);
   Symbol *MakeTypeSymbol(const SourceName &, Details &&);
@@ -1609,21 +1609,26 @@ void OmpVisitor::Post(const parser::OpenMPBlockConstruct &x) {
   }
 }
 
+// This "manually" walks the tree of the cosntruct, because the order
+// elements are resolved by the normal visitor will try to resolve
+// the map clauses attached to the directive without having resolved
+// the type, so the type is figured out using the implicit rules.
 bool OmpVisitor::Pre(const parser::OpenMPDeclareMapperConstruct &x) {
   AddOmpSourceRange(x.source);
   BeginDeclTypeSpec();
   PushScope(Scope::Kind::OtherConstruct, nullptr);
   const auto &spec{std::get<parser::OmpDeclareMapperSpecifier>(x.t)};
-  if (const auto &mapperName{
-          std::get<std::optional<Fortran::parser::Name>>(spec.t)}) {
+  if (const auto &mapperName{std::get<std::optional<parser::Name>>(spec.t)}) {
     Symbol *mapperSym{&MakeSymbol(*mapperName, Attrs{})};
     mapperName->symbol = mapperSym;
+  } else if (0) {
+    Symbol *mapperSym{&MakeSymbol("default", Attrs{})};
   }
-  Walk(std::get<Fortran::parser::TypeSpec>(spec.t));
-  const auto &varName{std::get<Fortran::parser::ObjectName>(spec.t)};
+  Walk(std::get<parser::TypeSpec>(spec.t));
+  const auto &varName{std::get<parser::ObjectName>(spec.t)};
   DeclareObjectEntity(varName);
 
-  Walk(std::get<std::list<std::list<Fortran::parser::OmpMapClause>>>(x.t));
+  Walk(std::get<parser::OmpClauseList>(x.t));
 
   EndDeclTypeSpec();
   return false;
diff --git a/flang/test/Lower/OpenMP/Todo/omp-declare-mapper.f90 b/flang/test/Lower/OpenMP/Todo/omp-declare-mapper.f90
index ebec4b4adb42a6..5ae48ff7360482 100644
--- a/flang/test/Lower/OpenMP/Todo/omp-declare-mapper.f90
+++ b/flang/test/Lower/OpenMP/Todo/omp-declare-mapper.f90
@@ -1,8 +1,8 @@
 ! This test checks lowering of OpenMP declare mapper Directive.
 
 ! RUN: split-file %s %t
-! RUN: not %flang_fc1 -emit-fir -fopenmp %t/omp-declare-mapper-1.f90 2>&1 | FileCheck %t/omp-declare-mapper-1.f90
-! RUN  not %flang_fc1 -emit-fir -fopenmp %t/omp-declare-mapper-2.f90 2>&1 | FileCheck %t/omp-declare-mapper-2.f90
+! RUN: not %flang_fc1 -emit-fir -fopenmp -fopenmp-version=50 %t/omp-declare-mapper-1.f90 2>&1 | FileCheck %t/omp-declare-mapper-1.f90
+! RUN  not %flang_fc1 -emit-fir -fopenmp -fopenmp-version=50 %t/omp-declare-mapper-2.f90 2>&1 | FileCheck %t/omp-declare-mapper-2.f90
 
 !--- omp-declare-mapper-1.f90
 subroutine declare_mapper_1
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index 36834939d9b451..3bbe4c744004ac 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -612,8 +612,8 @@ def OMP_Critical : Directive<"critical"> {
   let category = CA_Executable;
 }
 def OMP_DeclareMapper : Directive<"declare mapper"> {
-  let allowedClauses = [
-    VersionedClause<OMPC_Map>,
+  let requiredClauses = [
+    VersionedClause<OMPC_Map, 50>,
   ];
   let association = AS_None;
   let category = CA_Declarative;

>From 3d810ef09f4faba31f29fb47d78d1d9804f5568a Mon Sep 17 00:00:00 2001
From: Mats Petersson <mats.petersson at arm.com>
Date: Mon, 11 Nov 2024 13:56:07 +0000
Subject: [PATCH 3/3] Move PushContext so mapper name is available in the outer
 context.

Fix mapper name creation to not "fail" with type missing by using
ConstructName detail flag.

Add tests for abstract and "not derived" type checks.
---
 flang/lib/Semantics/resolve-names.cpp            | 12 ++++++++----
 flang/test/Semantics/OpenMP/declare-mapper01.f90 |  8 ++++++++
 flang/test/Semantics/OpenMP/declare-mapper02.f90 | 10 ++++++++++
 3 files changed, 26 insertions(+), 4 deletions(-)
 create mode 100644 flang/test/Semantics/OpenMP/declare-mapper01.f90
 create mode 100644 flang/test/Semantics/OpenMP/declare-mapper02.f90

diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 0bbcf28e8ff6eb..bda6edfc9881b3 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1616,14 +1616,18 @@ void OmpVisitor::Post(const parser::OpenMPBlockConstruct &x) {
 bool OmpVisitor::Pre(const parser::OpenMPDeclareMapperConstruct &x) {
   AddOmpSourceRange(x.source);
   BeginDeclTypeSpec();
-  PushScope(Scope::Kind::OtherConstruct, nullptr);
   const auto &spec{std::get<parser::OmpDeclareMapperSpecifier>(x.t)};
+  Symbol *mapperSym{nullptr};
   if (const auto &mapperName{std::get<std::optional<parser::Name>>(spec.t)}) {
-    Symbol *mapperSym{&MakeSymbol(*mapperName, Attrs{})};
+    mapperSym =
+        &MakeSymbol(*mapperName, MiscDetails{MiscDetails::Kind::ConstructName});
     mapperName->symbol = mapperSym;
-  } else if (0) {
-    Symbol *mapperSym{&MakeSymbol("default", Attrs{})};
+  } else {
+    mapperSym = &MakeSymbol(
+        "default", Attrs{}, MiscDetails{MiscDetails::Kind::ConstructName});
   }
+
+  PushScope(Scope::Kind::OtherConstruct, nullptr);
   Walk(std::get<parser::TypeSpec>(spec.t));
   const auto &varName{std::get<parser::ObjectName>(spec.t)};
   DeclareObjectEntity(varName);
diff --git a/flang/test/Semantics/OpenMP/declare-mapper01.f90 b/flang/test/Semantics/OpenMP/declare-mapper01.f90
new file mode 100644
index 00000000000000..02ce129e8f04d1
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/declare-mapper01.f90
@@ -0,0 +1,8 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=50
+  ! Test the source code starting with omp syntax
+
+integer :: y
+
+!ERROR: Type is not a derived type
+!$omp declare mapper(mm : integer::x) map(x, y)
+end
diff --git a/flang/test/Semantics/OpenMP/declare-mapper02.f90 b/flang/test/Semantics/OpenMP/declare-mapper02.f90
new file mode 100644
index 00000000000000..00d0a46177ec36
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/declare-mapper02.f90
@@ -0,0 +1,10 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=50
+! Test the source code starting with omp syntax
+
+type, abstract :: t1
+   integer :: y
+end type t1
+
+!ERROR: Type must not be abstract
+!$omp declare mapper(mm : t1::x) map(x, x%y)
+end



More information about the flang-commits mailing list