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

via flang-commits flang-commits at lists.llvm.org
Thu Nov 14 01:35:39 PST 2024


Author: Mats Petersson
Date: 2024-11-14T09:35:34Z
New Revision: ec1e0c5ecd53e415b23d5bd40b8e44e3ef4b4d92

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

LOG: [Flang][OMP]Add support for DECLARE MAPPER parsing and semantics (#115160)

Will hit a TODO in the lowering, which there are tests added to check
for this happening.

Added: 
    flang/test/Lower/OpenMP/Todo/omp-declare-mapper.f90
    flang/test/Parser/OpenMP/declare-mapper-unparse.f90
    flang/test/Semantics/OpenMP/declare-mapper-symbols.f90
    flang/test/Semantics/OpenMP/declare-mapper01.f90
    flang/test/Semantics/OpenMP/declare-mapper02.f90
    flang/test/Semantics/OpenMP/declare-mapper03.f90

Modified: 
    flang/include/flang/Parser/dump-parse-tree.h
    flang/include/flang/Parser/parse-tree.h
    flang/lib/Lower/OpenMP/OpenMP.cpp
    flang/lib/Parser/openmp-parsers.cpp
    flang/lib/Parser/unparse.cpp
    flang/lib/Semantics/check-omp-structure.cpp
    flang/lib/Semantics/check-omp-structure.h
    flang/lib/Semantics/resolve-directives.cpp
    flang/lib/Semantics/resolve-names.cpp
    flang/lib/Semantics/unparse-with-symbols.cpp
    llvm/include/llvm/Frontend/OpenMP/OMP.td

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 2fb863738d62d0..5886e384b986b6 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -506,6 +506,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)
@@ -621,6 +622,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 c5963e92065148..10d7840775e88d 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3916,6 +3916,19 @@ struct OpenMPDeclareTargetConstruct {
   std::tuple<Verbatim, OmpDeclareTargetSpecifier> t;
 };
 
+struct OmpDeclareMapperSpecifier {
+  TUPLE_CLASS_BOILERPLATE(OmpDeclareMapperSpecifier);
+  std::tuple<std::optional<Name>, TypeSpec, Name> t;
+};
+
+// OMP v5.2: 5.8.8
+//  declare-mapper -> DECLARE MAPPER ([mapper-name :] type :: var) map-clauses
+struct OpenMPDeclareMapperConstruct {
+  TUPLE_CLASS_BOILERPLATE(OpenMPDeclareMapperConstruct);
+  CharBlock source;
+  std::tuple<Verbatim, OmpDeclareMapperSpecifier, OmpClauseList> t;
+};
+
 // 2.16 declare-reduction -> DECLARE REDUCTION (reduction-identifier : type-list
 //                                              : combiner) [initializer-clause]
 struct OmpReductionCombiner {
@@ -3966,9 +3979,10 @@ struct OpenMPDeclarativeAllocate {
 struct OpenMPDeclarativeConstruct {
   UNION_CLASS_BOILERPLATE(OpenMPDeclarativeConstruct);
   CharBlock source;
-  std::variant<OpenMPDeclarativeAllocate, OpenMPDeclareReductionConstruct,
-      OpenMPDeclareSimdConstruct, OpenMPDeclareTargetConstruct,
-      OpenMPThreadprivate, OpenMPRequiresConstruct>
+  std::variant<OpenMPDeclarativeAllocate, OpenMPDeclareMapperConstruct,
+      OpenMPDeclareReductionConstruct, OpenMPDeclareSimdConstruct,
+      OpenMPDeclareTargetConstruct, OpenMPThreadprivate,
+      OpenMPRequiresConstruct>
       u;
 };
 

diff  --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 91f99ba4b0ca55..d70b0f31526979 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -2623,6 +2623,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 ee6f8feb6657a1..c2c730edacc02a 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -860,6 +860,15 @@ 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))
+
+// 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>(
         construct<OmpReductionCombiner::FunctionCombiner>(
@@ -968,6 +977,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 4b511da69832c5..158d3a1f14e4fe 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2652,6 +2652,22 @@ 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(")");
+
+              Walk(std::get<OmpClauseList>(z.t));
+              Put("\n");
+              return false;
+            },
             [&](const OpenMPDeclareReductionConstruct &) {
               Word("DECLARE REDUCTION ");
               return true;

diff  --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 5fe72e6fd4fd25..4414aec576885b 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1472,6 +1472,21 @@ 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 (!std::get_if<parser::DerivedTypeSpec>(&type.u)) {
+    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 0c5f97f743e2e1..eefa6f0eb65090 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -93,6 +93,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 83d666283a48c8..fa92ccc8e3a7db 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(); }
 
@@ -1953,6 +1956,11 @@ 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..9b0e204ac4e918 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1468,6 +1468,9 @@ class OmpVisitor : public virtual DeclarationVisitor {
     AddOmpSourceRange(x.source);
     return true;
   }
+
+  bool Pre(const parser::OpenMPDeclareMapperConstruct &);
+
   void Post(const parser::OmpBeginLoopDirective &) {
     messageHandler().set_currStmtSource(std::nullopt);
   }
@@ -1605,6 +1608,37 @@ void OmpVisitor::Post(const parser::OpenMPBlockConstruct &x) {
   }
 }
 
+// This "manually" walks the tree of the construct, because we need
+// to resolve the type before the map clauses are processed - when
+// just following the natural flow, the map clauses gets processed before
+// the type has been fully processed.
+bool OmpVisitor::Pre(const parser::OpenMPDeclareMapperConstruct &x) {
+  AddOmpSourceRange(x.source);
+  BeginDeclTypeSpec();
+  const auto &spec{std::get<parser::OmpDeclareMapperSpecifier>(x.t)};
+  Symbol *mapperSym{nullptr};
+  if (const auto &mapperName{std::get<std::optional<parser::Name>>(spec.t)}) {
+    mapperSym =
+        &MakeSymbol(*mapperName, MiscDetails{MiscDetails::Kind::ConstructName});
+    mapperName->symbol = mapperSym;
+  } else {
+    const parser::CharBlock defaultName{"default", 7};
+    mapperSym = &MakeSymbol(
+        defaultName, 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);
+
+  Walk(std::get<parser::OmpClauseList>(x.t));
+
+  EndDeclTypeSpec();
+  PopScope();
+  return false;
+}
+
 // Walk the parse tree and resolve names to symbols.
 class ResolveNamesVisitor : public virtual ScopeHandler,
                             public ModuleVisitor,

diff  --git a/flang/lib/Semantics/unparse-with-symbols.cpp b/flang/lib/Semantics/unparse-with-symbols.cpp
index c451f885c06279..02afb89ae57faf 100644
--- a/flang/lib/Semantics/unparse-with-symbols.cpp
+++ b/flang/lib/Semantics/unparse-with-symbols.cpp
@@ -53,6 +53,14 @@ class SymbolDumpVisitor {
   void Post(const parser::OpenMPThreadprivate &) { currStmt_ = std::nullopt; }
   void Post(const parser::Name &name);
 
+  bool Pre(const parser::OpenMPDeclareMapperConstruct &x) {
+    currStmt_ = x.source;
+    return true;
+  }
+  void Post(const parser::OpenMPDeclareMapperConstruct &) {
+    currStmt_ = std::nullopt;
+  }
+
 private:
   std::optional<SourceName> currStmt_; // current statement we are processing
   std::multimap<const char *, const Symbol *> symbols_; // location to symbol

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..5ae48ff7360482
--- /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 -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
+ 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..5ba147d20955e3
--- /dev/null
+++ b/flang/test/Parser/OpenMP/declare-mapper-unparse.f90
@@ -0,0 +1,42 @@
+! 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'  
+
+!CHECK: !$OMP DECLARE MAPPER (ty::mapped) MAP(mapped,mapped%x)
+  !$omp declare mapper(ty :: mapped) map(mapped, mapped%x)
+  
+!PARSE-TREE:      OpenMPDeclareMapperConstruct
+!PARSE-TREE:        OmpDeclareMapperSpecifier
+!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

diff  --git a/flang/test/Semantics/OpenMP/declare-mapper-symbols.f90 b/flang/test/Semantics/OpenMP/declare-mapper-symbols.f90
new file mode 100644
index 00000000000000..b4e03bd1632e57
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/declare-mapper-symbols.f90
@@ -0,0 +1,24 @@
+! RUN: %flang_fc1 -fdebug-dump-symbols -fopenmp -fopenmp-version=50 %s | FileCheck %s
+
+program main
+!CHECK-LABEL: MainProgram scope: main
+  implicit none
+
+  type ty
+     integer :: x
+  end type ty
+  !$omp declare mapper(mymapper : ty :: mapped) map(mapped, mapped%x)
+  !$omp declare mapper(ty :: maptwo) map(maptwo, maptwo%x)
+
+!! Note, symbols come out in their respective scope, but not in declaration order.
+!CHECK: default: Misc ConstructName
+!CHECK: mymapper: Misc ConstructName
+!CHECK: ty: DerivedType components: x
+!CHECK: DerivedType scope: ty
+!CHECK: OtherConstruct scope:
+!CHECK: mapped (OmpMapToFrom) {{.*}} ObjectEntity type: TYPE(ty)
+!CHECK: OtherConstruct scope:  
+!CHECK: maptwo (OmpMapToFrom) {{.*}} ObjectEntity type: TYPE(ty)
+  
+end program main
+

diff  --git a/flang/test/Semantics/OpenMP/declare-mapper01.f90 b/flang/test/Semantics/OpenMP/declare-mapper01.f90
new file mode 100644
index 00000000000000..0712b80769a45c
--- /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 declare mapper with non-derived type.
+
+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..a62a7f8d0a392d
--- /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 declare mapper construct with abstract type.
+
+type, abstract :: t1
+   integer :: y
+end type t1
+
+!ERROR: ABSTRACT derived type may not be used here
+!$omp declare mapper(mm : t1::x) map(x, x%y)
+end

diff  --git a/flang/test/Semantics/OpenMP/declare-mapper03.f90 b/flang/test/Semantics/OpenMP/declare-mapper03.f90
new file mode 100644
index 00000000000000..b70b8a67f33e08
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/declare-mapper03.f90
@@ -0,0 +1,16 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=50
+! Test the declare mapper construct with two default mappers.
+
+type :: t1
+   integer :: y
+end type t1
+
+type :: t2
+   real :: y, z
+end type t2
+
+!error: 'default' is already declared in this scoping unit
+
+!$omp declare mapper(t1::x) map(x, x%y)
+!$omp declare mapper(t2::w) map(w, w%y, w%z)
+end

diff  --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index fa96c3f367f0ce..12f51035656a56 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -625,8 +625,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, 45>,
   ];
   let association = AS_None;
   let category = CA_Declarative;


        


More information about the flang-commits mailing list