From 8f3b119ecc996b24c1a6281d374ee275eaecdc10 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Wed, 17 Sep 2025 14:45:34 -0500 Subject: [PATCH] [flang][OpenMP] Use OmpDirectiveSpecification in utility directives --- flang/include/flang/Parser/openmp-utils.h | 8 ---- flang/include/flang/Parser/parse-tree.h | 8 +--- flang/lib/Parser/openmp-parsers.cpp | 41 +++++++++++---------- flang/lib/Parser/unparse.cpp | 11 ++++-- flang/lib/Semantics/check-omp-structure.cpp | 21 ++++++----- flang/lib/Semantics/check-omp-structure.h | 2 + 6 files changed, 45 insertions(+), 46 deletions(-) diff --git a/flang/include/flang/Parser/openmp-utils.h b/flang/include/flang/Parser/openmp-utils.h index 032fb8996fe48..af14b20989af0 100644 --- a/flang/include/flang/Parser/openmp-utils.h +++ b/flang/include/flang/Parser/openmp-utils.h @@ -39,8 +39,6 @@ struct ConstructId { } MAKE_CONSTR_ID(OmpDeclareVariantDirective, D::OMPD_declare_variant); -MAKE_CONSTR_ID(OmpErrorDirective, D::OMPD_error); -MAKE_CONSTR_ID(OmpMetadirectiveDirective, D::OMPD_metadirective); MAKE_CONSTR_ID(OpenMPDeclarativeAllocate, D::OMPD_allocate); MAKE_CONSTR_ID(OpenMPDeclarativeAssumes, D::OMPD_assumes); MAKE_CONSTR_ID(OpenMPDeclareMapperConstruct, D::OMPD_declare_mapper); @@ -62,10 +60,6 @@ struct DirectiveNameScope { return name; } - static OmpDirectiveName GetOmpDirectiveName(const OmpNothingDirective &x) { - return MakeName(x.source, llvm::omp::Directive::OMPD_nothing); - } - static OmpDirectiveName GetOmpDirectiveName(const OmpBeginLoopDirective &x) { return x.DirName(); } @@ -102,8 +96,6 @@ struct DirectiveNameScope { if constexpr (std::is_base_of_v) { return std::get(x.t).DirName(); } else if constexpr (std::is_same_v || - std::is_same_v || - std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 7307283eb91ec..eb64bc396a1b4 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -4837,17 +4837,13 @@ struct OmpMetadirectiveDirective { // nothing-directive -> // NOTHING // since 5.1 struct OmpNothingDirective { - using EmptyTrait = std::true_type; - COPY_AND_ASSIGN_BOILERPLATE(OmpNothingDirective); - CharBlock source; + WRAPPER_CLASS_BOILERPLATE(OmpNothingDirective, OmpDirectiveSpecification); }; // Ref: OpenMP [5.2:216-218] // ERROR AT(compilation|execution) SEVERITY(fatal|warning) MESSAGE("msg-str) struct OmpErrorDirective { - TUPLE_CLASS_BOILERPLATE(OmpErrorDirective); - CharBlock source; - std::tuple t; + WRAPPER_CLASS_BOILERPLATE(OmpErrorDirective, OmpDirectiveSpecification); }; struct OpenMPUtilityConstruct { diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index c6d4de108fb59..9d7fbf63cfa4c 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -1276,11 +1276,18 @@ TYPE_PARSER(sourced(construct( // 2.1 (variable | /common-block/ | array-sections) TYPE_PARSER(construct(nonemptyList(Parser{}))) -TYPE_PARSER(sourced(construct( - verbatim("ERROR"_tok), Parser{}))) - // --- Parsers for directives and constructs -------------------------- +static inline constexpr auto IsDirective(llvm::omp::Directive dir) { + return [dir](const OmpDirectiveName &name) -> bool { return dir == name.v; }; +} + +static inline constexpr auto IsMemberOf(const DirectiveSet &dirs) { + return [&dirs](const OmpDirectiveName &name) -> bool { + return dirs.test(llvm::to_underlying(name.v)); + }; +} + TYPE_PARSER(sourced(construct(OmpDirectiveNameParser{}))) OmpDirectiveSpecification static makeFlushFromOldSyntax(Verbatim &&text, @@ -1355,27 +1362,23 @@ struct LooselyStructuredBlockParser { } }; -TYPE_PARSER(sourced(construct("NOTHING" >> ok))) +TYPE_PARSER(construct( + predicated(Parser{}, + IsDirective(llvm::omp::Directive::OMPD_error)) >= + Parser{})) -TYPE_PARSER(sourced(construct( - sourced(construct( - sourced(Parser{}))) || - sourced(construct( - sourced(Parser{})))))) +TYPE_PARSER(construct( + predicated(Parser{}, + IsDirective(llvm::omp::Directive::OMPD_nothing)) >= + Parser{})) + +TYPE_PARSER( // + sourced(construct(Parser{})) || + sourced(construct(Parser{}))) TYPE_PARSER(sourced(construct( verbatim("METADIRECTIVE"_tok), Parser{}))) -static inline constexpr auto IsDirective(llvm::omp::Directive dir) { - return [dir](const OmpDirectiveName &name) -> bool { return dir == name.v; }; -} - -static inline constexpr auto IsMemberOf(const DirectiveSet &dirs) { - return [&dirs](const OmpDirectiveName &name) -> bool { - return dirs.test(llvm::to_underlying(name.v)); - }; -} - struct OmpBeginDirectiveParser { using resultType = OmpDirectiveSpecification; diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 73bbbc04f46b1..9e455695b7b15 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2610,13 +2610,18 @@ class UnparseVisitor { return false; } void Unparse(const OmpErrorDirective &x) { - Word("!$OMP ERROR "); - Walk(x.t); + BeginOpenMP(); + Word("!$OMP "); + Walk(x.v); Put("\n"); + EndOpenMP(); } void Unparse(const OmpNothingDirective &x) { - Word("!$OMP NOTHING"); + BeginOpenMP(); + Word("!$OMP "); + Walk(x.v); Put("\n"); + EndOpenMP(); } void Unparse(const OmpSectionsDirective &x) { switch (x.v) { diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 4c7cd1734e0e7..266ef221ea7c9 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -608,14 +608,6 @@ template struct DirectiveSpellingVisitor { checker_(GetDirName(x.t).source, Directive::OMPD_dispatch); return false; } - bool Pre(const parser::OmpErrorDirective &x) { - checker_(std::get(x.t).source, Directive::OMPD_error); - return false; - } - bool Pre(const parser::OmpNothingDirective &x) { - checker_(x.source, Directive::OMPD_nothing); - return false; - } bool Pre(const parser::OpenMPExecutableAllocate &x) { checker_(std::get(x.t).source, Directive::OMPD_allocate); return false; @@ -1755,8 +1747,17 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &x) { } void OmpStructureChecker::Enter(const parser::OmpErrorDirective &x) { - const auto &dir{std::get(x.t)}; - PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_error); + const parser::OmpDirectiveName &dirName{x.v.DirName()}; + PushContextAndClauseSets(dirName.source, dirName.v); +} + +void OmpStructureChecker::Enter(const parser::OmpNothingDirective &x) { + const parser::OmpDirectiveName &dirName{x.v.DirName()}; + PushContextAndClauseSets(dirName.source, dirName.v); +} + +void OmpStructureChecker::Leave(const parser::OmpNothingDirective &x) { + dirContext_.pop_back(); } void OmpStructureChecker::Enter(const parser::OpenMPDispatchConstruct &x) { diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h index ce074f5f3f86e..81cabdfed0a39 100644 --- a/flang/lib/Semantics/check-omp-structure.h +++ b/flang/lib/Semantics/check-omp-structure.h @@ -120,6 +120,8 @@ class OmpStructureChecker void Leave(const parser::OpenMPDispatchConstruct &); void Enter(const parser::OmpErrorDirective &); void Leave(const parser::OmpErrorDirective &); + void Enter(const parser::OmpNothingDirective &); + void Leave(const parser::OmpNothingDirective &); void Enter(const parser::OpenMPExecutableAllocate &); void Leave(const parser::OpenMPExecutableAllocate &); void Enter(const parser::OpenMPAllocatorsConstruct &);