diff --git a/flang/lib/parser/dump-parse-tree.h b/flang/lib/parser/dump-parse-tree.h index d312cd4356b4..386900bcfb4c 100644 --- a/flang/lib/parser/dump-parse-tree.h +++ b/flang/lib/parser/dump-parse-tree.h @@ -456,8 +456,9 @@ public: NODE(parser::OmpClause, IsDevicePtr) NODE(parser, OmpCriticalDirective) NODE(parser::OmpCriticalDirective, Hint) - NODE(parser, OmpDeclareTargetMapType) - NODE_ENUM(parser::OmpDeclareTargetMapType, Type) + NODE(parser, OmpDeclareTargetSpecifier) + NODE(parser, OmpDeclareTargetWithClause) + NODE(parser, OmpDeclareTargetWithList) NODE(parser, OmpDefaultClause) NODE_ENUM(parser::OmpDefaultClause, Type) NODE(parser, OmpDependClause) @@ -525,10 +526,6 @@ public: NODE(parser, OpenMPDeclareReductionConstruct) NODE(parser, OpenMPDeclareSimdConstruct) NODE(parser, OpenMPDeclareTargetConstruct) - NODE(parser, OpenMPDeclareTargetSpecifier) - NODE(parser::OpenMPDeclareTargetSpecifier, Implicit) - NODE(parser::OpenMPDeclareTargetSpecifier, WithClause) - NODE(parser::OpenMPDeclareTargetSpecifier, WithExtendedList) NODE(parser, OpenMPFlushConstruct) NODE(parser, OpenMPLoopConstruct) NODE(parser, OpenMPSimpleStandaloneConstruct) diff --git a/flang/lib/parser/openmp-grammar.h b/flang/lib/parser/openmp-grammar.h index 8398b45ab436..1be7b858bcb2 100644 --- a/flang/lib/parser/openmp-grammar.h +++ b/flang/lib/parser/openmp-grammar.h @@ -368,26 +368,22 @@ TYPE_PARSER(sourced(construct( Parser{} / ")", maybe(Parser{})))) -// declare-target-map-type -TYPE_PARSER(construct( - "LINK" >> pure(OmpDeclareTargetMapType::Type::Link) || - "TO" >> pure(OmpDeclareTargetMapType::Type::To))) +// declare-target with list +TYPE_PARSER(sourced(construct( + parenthesized(Parser{})))) + +// declare-target with clause +TYPE_PARSER( + sourced(construct(Parser{}))) // declare-target-specifier -TYPE_PARSER(construct( - construct( - Parser{}, - parenthesized(Parser{}))) || - lookAhead(endOfLine) >> - construct( - construct()) || - construct( - parenthesized(construct( - Parser{})))) +TYPE_PARSER( + construct(Parser{}) || + construct(Parser{})) // Declare Target Construct TYPE_PARSER(sourced(construct( - verbatim("DECLARE TARGET"_tok), Parser{}))) + verbatim("DECLARE TARGET"_tok), Parser{}))) TYPE_PARSER(construct(Parser{}) || construct( diff --git a/flang/lib/parser/parse-tree-visitor.h b/flang/lib/parser/parse-tree-visitor.h index 81b1274f1faa..b11501f83d24 100644 --- a/flang/lib/parser/parse-tree-visitor.h +++ b/flang/lib/parser/parse-tree-visitor.h @@ -821,35 +821,5 @@ void Walk(OmpLinearClause::WithoutModifier &x, M &mutator) { mutator.Post(x); } } -template -void Walk(const OpenMPDeclareTargetSpecifier::WithClause &x, V &visitor) { - if (visitor.Pre(x)) { - Walk(x.maptype, visitor); - Walk(x.names, visitor); - visitor.Post(x); - } -} -template -void Walk(OpenMPDeclareTargetSpecifier::WithClause &x, M &mutator) { - if (mutator.Pre(x)) { - Walk(x.maptype, mutator); - Walk(x.names, mutator); - mutator.Post(x); - } -} -template -void Walk(const OpenMPDeclareTargetSpecifier::WithExtendedList &x, V &visitor) { - if (visitor.Pre(x)) { - Walk(x.names, visitor); - visitor.Post(x); - } -} -template -void Walk(OpenMPDeclareTargetSpecifier::WithExtendedList &x, M &mutator) { - if (mutator.Pre(x)) { - Walk(x.names, mutator); - mutator.Post(x); - } -} } #endif // FORTRAN_PARSER_PARSE_TREE_VISITOR_H_ diff --git a/flang/lib/parser/parse-tree.h b/flang/lib/parser/parse-tree.h index 2da1dc263764..9f50c0c29695 100644 --- a/flang/lib/parser/parse-tree.h +++ b/flang/lib/parser/parse-tree.h @@ -3501,33 +3501,25 @@ struct OmpBlockDirective { CharBlock source; }; -struct OmpDeclareTargetMapType { - ENUM_CLASS(Type, Link, To) - WRAPPER_CLASS_BOILERPLATE(OmpDeclareTargetMapType, Type); +struct OmpDeclareTargetWithList { + WRAPPER_CLASS_BOILERPLATE(OmpDeclareTargetWithList, OmpObjectList); + CharBlock source; }; -struct OpenMPDeclareTargetSpecifier { - UNION_CLASS_BOILERPLATE(OpenMPDeclareTargetSpecifier); - struct WithClause { - BOILERPLATE(WithClause); - WithClause(OmpDeclareTargetMapType &&m, OmpObjectList &&n) - : maptype(std::move(m)), names(std::move(n)) {} - OmpDeclareTargetMapType maptype; - OmpObjectList names; - }; - struct WithExtendedList { - BOILERPLATE(WithExtendedList); - WithExtendedList(OmpObjectList &&n) : names(std::move(n)) {} - OmpObjectList names; - }; - EMPTY_CLASS(Implicit); - std::variant u; +struct OmpDeclareTargetWithClause { + WRAPPER_CLASS_BOILERPLATE(OmpDeclareTargetWithClause, OmpClauseList); + CharBlock source; +}; + +struct OmpDeclareTargetSpecifier { + UNION_CLASS_BOILERPLATE(OmpDeclareTargetSpecifier); + std::variant u; }; struct OpenMPDeclareTargetConstruct { TUPLE_CLASS_BOILERPLATE(OpenMPDeclareTargetConstruct); CharBlock source; - std::tuple t; + std::tuple t; }; struct OmpReductionCombiner { diff --git a/flang/lib/parser/unparse.cc b/flang/lib/parser/unparse.cc index c4385c029e55..76732fac4c60 100644 --- a/flang/lib/parser/unparse.cc +++ b/flang/lib/parser/unparse.cc @@ -2187,11 +2187,8 @@ public: Walk(std::get(x.t), ""); Walk(std::get(x.t)); } - void Unparse(const OpenMPDeclareTargetSpecifier::WithClause &x) { - Walk(x.maptype), Put("("), Walk(x.names), Put(")"); - } - void Unparse(const OpenMPDeclareTargetSpecifier::WithExtendedList &x) { - Put("("), Walk(x.names), Put(")"); + void Unparse(const OmpDeclareTargetWithList &x) { + Put("("), Walk(x.v), Put(")"); } void Unparse(const OmpReductionInitializerClause &x) { Word(" INITIALIZER(OMP_PRIV = "); @@ -2415,7 +2412,6 @@ public: WALK_NESTED_ENUM(OmpScheduleClause, ScheduleType) // OMP schedule-type WALK_NESTED_ENUM( OmpIfClause, DirectiveNameModifier) // OMP directive-modifier - WALK_NESTED_ENUM(OmpDeclareTargetMapType, Type) // OMP DeclareTarget map-type WALK_NESTED_ENUM(OmpCancelType, Type) // OMP cancel-type #undef WALK_NESTED_ENUM diff --git a/flang/lib/semantics/check-omp-structure.cc b/flang/lib/semantics/check-omp-structure.cc index a23032e49148..19e0f05d8379 100644 --- a/flang/lib/semantics/check-omp-structure.cc +++ b/flang/lib/semantics/check-omp-structure.cc @@ -282,6 +282,19 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareSimdConstruct &) { ompContext_.pop_back(); } +void OmpStructureChecker::Enter(const parser::OpenMPDeclareTargetConstruct &x) { + const auto &dir{std::get(x.t)}; + PushContext(dir.source, OmpDirective::DECLARE_TARGET); + const auto &spec{std::get(x.t)}; + if (std::holds_alternative(spec.u)) { + SetContextAllowed(OmpClauseSet{OmpClause::TO, OmpClause::LINK}); + } +} + +void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &) { + ompContext_.pop_back(); +} + void OmpStructureChecker::Enter( const parser::OpenMPSimpleStandaloneConstruct &x) { const auto &dir{std::get(x.t)}; diff --git a/flang/lib/semantics/check-omp-structure.h b/flang/lib/semantics/check-omp-structure.h index 8cad33749cf4..2cc29822a2db 100644 --- a/flang/lib/semantics/check-omp-structure.h +++ b/flang/lib/semantics/check-omp-structure.h @@ -71,6 +71,8 @@ public: void Enter(const parser::OpenMPDeclareSimdConstruct &); void Leave(const parser::OpenMPDeclareSimdConstruct &); + void Enter(const parser::OpenMPDeclareTargetConstruct &); + void Leave(const parser::OpenMPDeclareTargetConstruct &); void Enter(const parser::OpenMPSimpleStandaloneConstruct &); void Leave(const parser::OpenMPSimpleStandaloneConstruct &); diff --git a/flang/test/semantics/omp-declarative-directive.f90 b/flang/test/semantics/omp-declarative-directive.f90 index 7f3808038a8e..01739f50e54d 100644 --- a/flang/test/semantics/omp-declarative-directive.f90 +++ b/flang/test/semantics/omp-declarative-directive.f90 @@ -56,16 +56,17 @@ end subroutine sub1 ! 2.15.2 threadprivate module m2 - !$omp declare target - !$omp declare target (N) - !$omp declare target to(Q) - integer, parameter :: N=10000, M=1024 - integer :: i - real :: Q(N, N) - !$omp threadprivate(i) - contains subroutine foo + !$omp declare target + !$omp declare target (foo, N, M) + !$omp declare target to(Q, S) link(R) + !ERROR: MAP clause is not allowed on the DECLARE TARGET directive + !$omp declare target map(from:Q) + integer, parameter :: N=10000, M=1024 + integer :: i + real :: Q(N, N), R(N,M), S(M,M) + !$omp threadprivate(i) end subroutine foo end module m2