diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -562,6 +562,7 @@ NODE(parser, OpenMPExecutableAllocate) NODE(parser, OpenMPSimpleStandaloneConstruct) NODE(parser, OpenMPStandaloneConstruct) + NODE(parser, OpenMPSectionConstruct) NODE(parser, OpenMPSectionsConstruct) NODE(parser, OpenMPThreadprivate) NODE(parser, OpenStmt) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3515,7 +3515,8 @@ // [!$omp section // structured-block] // ... -WRAPPER_CLASS(OmpSectionBlocks, std::list); +WRAPPER_CLASS(OpenMPSectionConstruct, Block); +WRAPPER_CLASS(OmpSectionBlocks, std::list); struct OpenMPSectionsConstruct { TUPLE_CLASS_BOILERPLATE(OpenMPSectionsConstruct); @@ -3817,9 +3818,9 @@ struct OpenMPConstruct { UNION_CLASS_BOILERPLATE(OpenMPConstruct); std::variant + OpenMPSectionConstruct, OpenMPLoopConstruct, OpenMPBlockConstruct, + OpenMPAtomicConstruct, OpenMPDeclarativeAllocate, + OpenMPExecutableAllocate, OpenMPCriticalConstruct> u; }; diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -217,6 +217,10 @@ §ionsConstruct) { TODO(converter.getCurrentLocation(), "OpenMPSectionsConstruct"); }, + [&](const Fortran::parser::OpenMPSectionConstruct + §ionsConstruct) { + TODO(converter.getCurrentLocation(), "OpenMPSectionConstruct"); + }, [&](const Fortran::parser::OpenMPLoopConstruct &loopConstruct) { TODO(converter.getCurrentLocation(), "OpenMPLoopConstruct"); }, diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -529,9 +529,13 @@ Parser{}))) // OMP SECTION-BLOCK + +TYPE_PARSER(construct(block)) + TYPE_PARSER(maybe(startOmpLine >> "SECTION"_tok / endOmpLine) >> construct( - nonemptySeparated(block, startOmpLine >> "SECTION"_tok / endOmpLine))) + nonemptySeparated(Parser{}, + startOmpLine >> "SECTION"_tok / endOmpLine))) // OMP SECTIONS (2.7.2), PARALLEL SECTIONS (2.11.2) TYPE_PARSER(construct( diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2405,7 +2405,7 @@ Word("!$OMP SECTION"); Put("\n"); EndOpenMP(); - Walk(y, ""); // y is Block + Walk(y.v, ""); // y.v is Block } } void Unparse(const OpenMPSectionsConstruct &x) { diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -802,7 +802,7 @@ PushContextAndClauseSets(beginDir.source, beginDir.v); const auto §ionBlocks{std::get(x.t)}; for (const auto &block : sectionBlocks.v) { - CheckNoBranching(block, beginDir.v, beginDir.source); + CheckNoBranching(block.v, beginDir.v, beginDir.source); } HasInvalidWorksharingNesting( beginDir.source, llvm::omp::nestedWorkshareErrSet); diff --git a/flang/test/Parser/omp-sections.f90 b/flang/test/Parser/omp-sections.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Parser/omp-sections.f90 @@ -0,0 +1,79 @@ +! RUN: %flang_fc1 -fdebug-unparse-no-sema -fopenmp %s | FileCheck --ignore-case %s + +SUBROUTINE OPENMP_SECTIONS(x, y) + + integer, intent(inout)::x, y + +!============================================================================== +! empty construct +!============================================================================== +!CHECK: !$OMP SECTIONS +!$OMP SECTIONS + !CHECK: !$OMP SECTION +!CHECK: !$OMP END SECTIONS +!$OMP END SECTIONS + +!============================================================================== +! single section, without `!$OMP SECTION` +!============================================================================== +!CHECK: !$OMP SECTIONS +!$OMP SECTIONS + !CHECK: !$OMP SECTION + !CHECK: CALL + CALL F1() +!CHECK: !$OMP END SECTIONS +!$OMP END SECTIONS + +!============================================================================== +! single section with `!$OMP SECTION` +!============================================================================== +!CHECK: !$OMP SECTIONS +!$OMP SECTIONS + !CHECK: !$OMP SECTION + !$OMP SECTION + !CHECK: CALL F1 + CALL F1 +!CHECK: !$OMP END SECTIONS +!$OMP END SECTIONS + +!============================================================================== +! multiple sections +!============================================================================== +!CHECK: !$OMP SECTIONS +!$OMP SECTIONS + !CHECK: !$OMP SECTION + !$OMP SECTION + !CHECK: CALL F1 + CALL F1 + !CHECK: !$OMP SECTION + !$OMP SECTION + !CHECK: CALL F2 + CALL F2 + !CHECK: !$OMP SECTION + !$OMP SECTION + !CHECK: CALL F3 + CALL F3 +!CHECK: !$OMP END SECTIONS +!$OMP END SECTIONS + +!============================================================================== +! multiple sections with clauses +!============================================================================== +!CHECK: !$OMP SECTIONS PRIVATE(x) FIRSTPRIVATE(y) +!$OMP SECTIONS PRIVATE(x) FIRSTPRIVATE(y) + !CHECK: !$OMP SECTION + !$OMP SECTION + !CHECK: CALL F1 + CALL F1 + !CHECK: !$OMP SECTION + !$OMP SECTION + !CHECK: CALL F2 + CALL F2 + !CHECK: !$OMP SECTION + !$OMP SECTION + !CHECK: CALL F3 + CALL F3 +!CHECK: !$OMP END SECTIONS NOWAIT +!$OMP END SECTIONS NOWAIT + +END SUBROUTINE OPENMP_SECTIONS