diff --git a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp index 665b92be00898..231df63bbae92 100644 --- a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp +++ b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp @@ -90,6 +90,10 @@ SourcePosition OpenMPCounterVisitor::getLocation(const OpenMPConstruct &c) { const CharBlock &source{c.source}; return (parsing->allCooked().GetSourcePositionRange(source))->first; }, + [&](const OpenMPUtilityConstruct &c) -> SourcePosition { + const CharBlock &source{c.source}; + return (parsing->allCooked().GetSourcePositionRange(source))->first; + }, }, c.u); } @@ -143,8 +147,8 @@ std::string OpenMPCounterVisitor::getName(const OpenMPConstruct &c) { }, c.u); }, - [&](const OpenMPErrorConstruct &c) -> std::string { - const CharBlock &source{std::get<0>(c.t).source}; + [&](const OpenMPUtilityConstruct &c) -> std::string { + const CharBlock &source{c.source}; return normalize_construct_name(source.ToString()); }, [&](const OpenMPSectionConstruct &c) -> std::string { diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index 7821d40a644a2..fa813727442f0 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -516,6 +516,8 @@ class ParseTreeDumper { #include "llvm/Frontend/OpenMP/OMP.inc" NODE(parser, OmpClauseList) NODE(parser, OmpCriticalDirective) + NODE(parser, OmpErrorDirective) + NODE(parser, OmpNothingDirective) NODE(parser, OmpDeclareTargetSpecifier) NODE(parser, OmpDeclareTargetWithClause) NODE(parser, OmpDeclareTargetWithList) @@ -662,7 +664,7 @@ class ParseTreeDumper { NODE(parser, OmpAtomicDefaultMemOrderClause) NODE_ENUM(common, OmpAtomicDefaultMemOrderType) NODE(parser, OpenMPDepobjConstruct) - NODE(parser, OpenMPErrorConstruct) + NODE(parser, OpenMPUtilityConstruct) NODE(parser, OpenMPFlushConstruct) NODE(parser, OpenMPLoopConstruct) NODE(parser, OpenMPExecutableAllocate) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 2ef593b3e50da..9df7c6d5e39c3 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -4182,6 +4182,30 @@ struct OmpClauseList { // --- Directives and constructs +// Ref: [5.1:89-90], [5.2:216] +// +// nothing-directive -> +// NOTHING // since 5.1 +struct OmpNothingDirective { + using EmptyTrait = std::true_type; + COPY_AND_ASSIGN_BOILERPLATE(OmpNothingDirective); + CharBlock source; +}; + +// 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; +}; + +struct OpenMPUtilityConstruct { + UNION_CLASS_BOILERPLATE(OpenMPUtilityConstruct); + CharBlock source; + std::variant u; +}; + // 2.7.2 SECTIONS // 2.11.2 PARALLEL SECTIONS struct OmpSectionsDirective { @@ -4506,14 +4530,6 @@ struct OpenMPDepobjConstruct { std::tuple t; }; -// Ref: OpenMP [5.2:216-218] -// ERROR AT(compilation|execution) SEVERITY(fatal|warning) MESSAGE("msg-str) -struct OpenMPErrorConstruct { - TUPLE_CLASS_BOILERPLATE(OpenMPErrorConstruct); - CharBlock source; - std::tuple t; -}; - // 2.17.8 flush -> FLUSH [memory-order-clause] [(variable-name-list)] struct OpenMPFlushConstruct { TUPLE_CLASS_BOILERPLATE(OpenMPFlushConstruct); @@ -4586,7 +4602,7 @@ struct OpenMPConstruct { UNION_CLASS_BOILERPLATE(OpenMPConstruct); std::variant u; diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index b07e89d201d19..fe6d82125a9e0 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -2907,8 +2907,8 @@ static void 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::OpenMPErrorConstruct &) { - TODO(converter.getCurrentLocation(), "OpenMPErrorConstruct"); + const parser::OpenMPUtilityConstruct &) { + TODO(converter.getCurrentLocation(), "OpenMPUtilityConstruct"); } 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 67385c03f66c8..0a0a29002de27 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -737,9 +737,20 @@ TYPE_PARSER( TYPE_PARSER(sourced(construct( many(maybe(","_tok) >> sourced(Parser{}))))) -// 2.1 (variable | /common-block | array-sections) +// 2.1 (variable | /common-block/ | array-sections) TYPE_PARSER(construct(nonemptyList(Parser{}))) +TYPE_PARSER(sourced(construct( + verbatim("ERROR"_tok), Parser{}))) + +TYPE_PARSER(sourced(construct("NOTHING" >> ok))) + +TYPE_PARSER(sourced(construct( + sourced(construct( + sourced(Parser{}))) || + sourced(construct( + sourced(Parser{})))))) + // Omp directives enclosing do loop TYPE_PARSER(sourced(construct(first( "DISTRIBUTE PARALLEL DO SIMD" >> @@ -1027,9 +1038,6 @@ TYPE_PARSER(sourced(construct(verbatim("CRITICAL"_tok), TYPE_PARSER(construct( Parser{}, block, Parser{})) -TYPE_PARSER(sourced(construct( - verbatim("ERROR"_tok), Parser{}))) - // 2.11.3 Executable Allocate directive TYPE_PARSER( sourced(construct(verbatim("ALLOCATE"_tok), @@ -1127,7 +1135,7 @@ TYPE_CONTEXT_PARSER("OpenMP construct"_en_US, // OpenMPStandaloneConstruct to resolve !$OMP ORDERED construct(Parser{}), construct(Parser{}), - construct(Parser{}), + construct(Parser{}), construct(Parser{}), construct(Parser{}), construct(Parser{}), diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 0a6af7435b4a2..4fe57f3e348d3 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2710,11 +2710,15 @@ class UnparseVisitor { Walk(x.v); return false; } - void Unparse(const OpenMPErrorConstruct &x) { + void Unparse(const OmpErrorDirective &x) { Word("!$OMP ERROR "); Walk(x.t); Put("\n"); } + void Unparse(const OmpNothingDirective &x) { + Word("!$OMP NOTHING"); + Put("\n"); + } void Unparse(const OmpSectionsDirective &x) { switch (x.v) { case llvm::omp::Directive::OMPD_sections: diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 95b962f5daf57..3a928c8a0289b 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -1688,12 +1688,12 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &x) { dirContext_.pop_back(); } -void OmpStructureChecker::Enter(const parser::OpenMPErrorConstruct &x) { +void OmpStructureChecker::Enter(const parser::OmpErrorDirective &x) { const auto &dir{std::get(x.t)}; PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_error); } -void OmpStructureChecker::Leave(const parser::OpenMPErrorConstruct &x) { +void OmpStructureChecker::Leave(const parser::OmpErrorDirective &x) { dirContext_.pop_back(); } diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h index 346a7bed9138f..2a4f6fbd618c3 100644 --- a/flang/lib/Semantics/check-omp-structure.h +++ b/flang/lib/Semantics/check-omp-structure.h @@ -102,8 +102,8 @@ class OmpStructureChecker void Enter(const parser::OmpDeclareTargetWithList &); void Enter(const parser::OmpDeclareTargetWithClause &); void Leave(const parser::OmpDeclareTargetWithClause &); - void Enter(const parser::OpenMPErrorConstruct &); - void Leave(const parser::OpenMPErrorConstruct &); + void Enter(const parser::OmpErrorDirective &); + void Leave(const parser::OmpErrorDirective &); void Enter(const parser::OpenMPExecutableAllocate &); void Leave(const parser::OpenMPExecutableAllocate &); void Enter(const parser::OpenMPAllocatorsConstruct &); diff --git a/flang/test/Lower/OpenMP/Todo/error.f90 b/flang/test/Lower/OpenMP/Todo/error.f90 index b97e2c20a0cdf..6d3bd892da47d 100644 --- a/flang/test/Lower/OpenMP/Todo/error.f90 +++ b/flang/test/Lower/OpenMP/Todo/error.f90 @@ -1,6 +1,6 @@ ! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1 | FileCheck %s -! CHECK: not yet implemented: OpenMPErrorConstruct +! CHECK: not yet implemented: OpenMPUtilityConstruct program p integer, allocatable :: x !$omp error at(compilation) severity(warning) message("an error") diff --git a/flang/test/Parser/OpenMP/error-unparse.f90 b/flang/test/Parser/OpenMP/error-unparse.f90 index fce5d8cf22863..4dd06b736da80 100644 --- a/flang/test/Parser/OpenMP/error-unparse.f90 +++ b/flang/test/Parser/OpenMP/error-unparse.f90 @@ -3,19 +3,19 @@ program main character(*), parameter :: message = "This is an error" !CHECK: !$OMP ERROR AT(COMPILATION) SEVERITY(WARNING) MESSAGE("some message here") - !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPErrorConstruct + !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPUtilityConstruct -> OmpErrorDirective !PARSE-TREE: OmpClauseList -> OmpClause -> At -> OmpAtClause -> ActionTime = Compilation !PARSE-TREE: OmpClause -> Severity -> OmpSeverityClause -> Severity = Warning !PARSE-TREE: OmpClause -> Message -> OmpMessageClause -> Expr -> LiteralConstant -> CharLiteralConstant !$omp error at(compilation) severity(warning) message("some message here") !CHECK: !$OMP ERROR AT(COMPILATION) SEVERITY(FATAL) MESSAGE(message) - !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPErrorConstruct + !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPUtilityConstruct -> OmpErrorDirective !PARSE-TREE: OmpClauseList -> OmpClause -> At -> OmpAtClause -> ActionTime = Compilation !PARSE-TREE: OmpClause -> Severity -> OmpSeverityClause -> Severity = Fatal !PARSE-TREE: OmpClause -> Message -> OmpMessageClause -> Expr -> Designator -> DataRef -> Name = 'message' !$omp error at(compilation) severity(fatal) message(message) !CHECK: !$OMP ERROR AT(EXECUTION) SEVERITY(FATAL) MESSAGE(message) - !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPErrorConstruct + !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPUtilityConstruct -> OmpErrorDirective !PARSE-TREE: OmpClauseList -> OmpClause -> At -> OmpAtClause -> ActionTime = Execution !PARSE-TREE: OmpClause -> Severity -> OmpSeverityClause -> Severity = Fatal !PARSE-TREE: OmpClause -> Message -> OmpMessageClause -> Expr -> Designator -> DataRef -> Name = 'message' diff --git a/flang/test/Parser/OpenMP/nothing.f90 b/flang/test/Parser/OpenMP/nothing.f90 new file mode 100644 index 0000000000000..80c0932087610 --- /dev/null +++ b/flang/test/Parser/OpenMP/nothing.f90 @@ -0,0 +1,13 @@ +!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=51 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s +!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=51 %s | FileCheck --check-prefix="PARSE-TREE" %s + +subroutine f00 + !$omp nothing +end + +!UNPARSE: SUBROUTINE f00 +!UNPARSE: !$OMP NOTHING +!UNPARSE: END SUBROUTINE + +!PARSE-TREE: ExecutionPart -> Block +!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPUtilityConstruct -> OmpNothingDirective