// R507 declaration-construct ->
// specification-construct | data-stmt | format-stmt |
// entry-stmt | stmt-function-stmt
-constexpr auto execPartLookAhead{first(actionStmt >> ok, "ASSOCIATE ("_tok,
+constexpr auto execPartLookAhead{first(actionStmt >> ok, openmpEndLoopDirective >> ok, openmpConstruct >> ok, "ASSOCIATE ("_tok,
"BLOCK"_tok, "SELECT"_tok, "CHANGE TEAM"_sptok, "CRITICAL"_tok, "DO"_tok,
"IF ("_tok, "WHERE ("_tok, "FORALL ("_tok)};
constexpr auto declErrorRecovery{
construct<SpecificationConstruct>(
statement(indirect(typeDeclarationStmt))),
construct<SpecificationConstruct>(indirect(Parser<StructureDef>{})),
- construct<SpecificationConstruct>(indirect(openmpConstruct)),
+ construct<SpecificationConstruct>(indirect(openmpDeclarativeConstruct)),
construct<SpecificationConstruct>(indirect(compilerDirective))))
// R513 other-specification-stmt ->
// [use-stmt]... [import-stmt]... [implicit-part]
// [declaration-construct]...
TYPE_CONTEXT_PARSER("specification part"_en_US,
- construct<SpecificationPart>(
+ construct<SpecificationPart>(many(openmpDeclarativeConstruct),
many(unambiguousStatement(indirect(Parser<UseStmt>{}))),
many(unambiguousStatement(indirect(Parser<ImportStmt>{}))),
implicitPart, many(declarationConstruct)))
// specialized error recovery in the event of a spurious executable
// statement.
constexpr auto limitedSpecificationPart{inContext("specification part"_en_US,
- construct<SpecificationPart>(
+ construct<SpecificationPart>(many(openmpDeclarativeConstruct),
many(unambiguousStatement(indirect(Parser<UseStmt>{}))),
many(unambiguousStatement(indirect(Parser<ImportStmt>{}))),
implicitPart, many(limitedDeclarationConstruct)))};
construct<ExecutableConstruct>(indirect(Parser<SelectTypeConstruct>{})),
construct<ExecutableConstruct>(indirect(whereConstruct)),
construct<ExecutableConstruct>(indirect(forallConstruct)),
+ construct<ExecutableConstruct>(indirect(openmpEndLoopDirective)),
construct<ExecutableConstruct>(indirect(openmpConstruct)),
construct<ExecutableConstruct>(indirect(compilerDirective)))};
// OpenMP Directives and Clauses
namespace Fortran::parser {
-constexpr auto beginOmpDirective{skipStuffBeforeStatement >> "!$OMP "_sptok};
+constexpr auto endOmpLine = space >> endOfLine;
// OpenMP Clauses
-
// DEFAULT (PRIVATE | FIRSTPRIVATE | SHARED | NONE )
TYPE_PARSER(construct<OmpDefaultClause>(
"PRIVATE" >> pure(OmpDefaultClause::Type::Private) ||
// MAP ([ [map-type-modifier[,]] map-type : ] list)
// map-type-modifier -> ALWAYS
// map-type -> TO | FROM | TOFROM | ALLOC | RELEASE | DELETE
+TYPE_PARSER(construct<OmpMapType>(
+ maybe("ALWAYS" >> construct<OmpMapType::Always>() / maybe(","_tok)),
+ "TO" >> pure(OmpMapType::Type::To) / ":"_tok ||
+ "FROM" >> pure(OmpMapType::Type::From) / ":"_tok ||
+ "TOFROM" >> pure(OmpMapType::Type::Tofrom) / ":"_tok ||
+ "ALLOC" >> pure(OmpMapType::Type::Alloc) / ":"_tok ||
+ "RELEASE" >> pure(OmpMapType::Type::Release) / ":"_tok ||
+ "DELETE" >> pure(OmpMapType::Type::Delete) / ":"_tok))
+
TYPE_PARSER(construct<OmpMapClause>(
- maybe(maybe("ALWAYS" >> maybe(","_tok)) >>
- ("TO" >> pure(OmpMapClause::Type::To) / ":"_tok ||
- "FROM" >> pure(OmpMapClause::Type::From) / ":"_tok ||
- "TOFROM" >> pure(OmpMapClause::Type::Tofrom) / ":"_tok ||
- "ALLOC" >> pure(OmpMapClause::Type::Alloc) / ":"_tok ||
- "RELEASE" >> pure(OmpMapClause::Type::Release) / ":"_tok ||
- "DELETE" >> pure(OmpMapClause::Type::Delete) / ":"_tok)),
- nonemptyList(name)))
+ maybe(Parser<OmpMapType>{}), Parser<OmpObjectList>{}))
// SCHEDULE ([modifier [, modifier]:]kind[, chunk_size])
// Modifier -> MONITONIC | NONMONOTONIC | SIMD
"GUIDED" >> pure(OmpScheduleClause::ScheduleType::Guided) ||
"AUTO" >> pure(OmpScheduleClause::ScheduleType::Auto) ||
"RUNTIME" >> pure(OmpScheduleClause::ScheduleType::Runtime),
- maybe(","_tok) >> scalarIntExpr))
+ maybe(","_tok >> scalarIntExpr)))
// IF(directive-name-modifier: scalar-logical-expr)
TYPE_PARSER(construct<OmpIfClause>(
maybe(
- "PARALLEL"_tok >> pure(OmpIfClause::DirectiveNameModifier::Parallel) ||
- "TARGET ENTER DATA"_tok >>
- pure(OmpIfClause::DirectiveNameModifier::TargetEnterData) ||
- "TARGET EXIT DATA"_tok >>
- pure(OmpIfClause::DirectiveNameModifier::TargetExitData) ||
- "TARGET DATA"_tok >>
- pure(OmpIfClause::DirectiveNameModifier::TargetData) ||
- "TARGET UPDATE"_tok >>
- pure(OmpIfClause::DirectiveNameModifier::TargetUpdate) ||
- "TARGET"_tok >> pure(OmpIfClause::DirectiveNameModifier::Target) ||
- "TASKLOOP"_tok >> pure(OmpIfClause::DirectiveNameModifier::Taskloop) ||
- "TASK"_tok >> pure(OmpIfClause::DirectiveNameModifier::Task)) /
- maybe(":"_tok),
+ ("PARALLEL" >> pure(OmpIfClause::DirectiveNameModifier::Parallel) ||
+ "TARGET ENTER DATA" >>
+ pure(OmpIfClause::DirectiveNameModifier::TargetEnterData) ||
+ "TARGET EXIT DATA" >>
+ pure(OmpIfClause::DirectiveNameModifier::TargetExitData) ||
+ "TARGET DATA" >>
+ pure(OmpIfClause::DirectiveNameModifier::TargetData) ||
+ "TARGET UPDATE" >>
+ pure(OmpIfClause::DirectiveNameModifier::TargetUpdate) ||
+ "TARGET" >> pure(OmpIfClause::DirectiveNameModifier::Target) ||
+ "TASKLOOP" >> pure(OmpIfClause::DirectiveNameModifier::Taskloop) ||
+ "TASK" >> pure(OmpIfClause::DirectiveNameModifier::Task)) /
+ ":"_tok),
scalarLogicalExpr))
-// REDUCTION(reduction-identifier: list)
-constexpr auto reductionBinaryOperator{
- "+" >> pure(OmpReductionOperator::BinaryOperator::Add) ||
- "-" >> pure(OmpReductionOperator::BinaryOperator::Subtract) ||
- "*" >> pure(OmpReductionOperator::BinaryOperator::Multiply) ||
- ".AND." >> pure(OmpReductionOperator::BinaryOperator::AND) ||
- ".OR." >> pure(OmpReductionOperator::BinaryOperator::OR) ||
- ".EQV." >> pure(OmpReductionOperator::BinaryOperator::EQV) ||
- ".NEQV." >> pure(OmpReductionOperator::BinaryOperator::NEQV)};
-
-constexpr auto reductionProcedureOperator{
- "MIN" >> pure(OmpReductionOperator::ProcedureOperator::MIN) ||
- "MAX" >> pure(OmpReductionOperator::ProcedureOperator::MAX) ||
- "IAND" >> pure(OmpReductionOperator::ProcedureOperator::IAND) ||
- "IOR" >> pure(OmpReductionOperator::ProcedureOperator::IOR) ||
- "IEOR" >> pure(OmpReductionOperator::ProcedureOperator::IEOR)};
-
-TYPE_PARSER(construct<OmpReductionOperator>(reductionBinaryOperator) ||
- construct<OmpReductionOperator>(reductionProcedureOperator))
+TYPE_PARSER(
+ construct<OmpReductionOperator>(indirect(Parser<DefinedOperator>{})) ||
+ construct<OmpReductionOperator>(Parser<ProcedureDesignator>{}))
TYPE_PARSER(construct<OmpReductionClause>(
Parser<OmpReductionOperator>{} / ":"_tok, nonemptyList(designator)))
construct<OmpDependSinkVec>(name, maybe(Parser<OmpDependSinkVecLength>{})))
TYPE_PARSER(construct<OmpDependenceType>(
- "IN"_tok >> pure(OmpDependenceType::Type::In) ||
- "OUT"_tok >> pure(OmpDependenceType::Type::Out) ||
- "INOUT"_tok >> pure(OmpDependenceType::Type::Inout)))
+ "INOUT" >> pure(OmpDependenceType::Type::Inout) ||
+ "IN" >> pure(OmpDependenceType::Type::In) ||
+ "OUT" >> pure(OmpDependenceType::Type::Out)))
TYPE_CONTEXT_PARSER("Omp Depend clause"_en_US,
construct<OmpDependClause>(construct<OmpDependClause::Sink>(
construct<OmpDependClause>(construct<OmpDependClause::InOut>(
Parser<OmpDependenceType>{}, ":"_tok >> nonemptyList(designator))))
-// LINEAR(list: linear-step)
-TYPE_PARSER(construct<OmpLinearModifier>(
- "REF"_tok >> pure(OmpLinearModifier::Type::Ref) ||
- "VAL"_tok >> pure(OmpLinearModifier::Type::Val) ||
- "UVAL"_tok >> pure(OmpLinearModifier::Type::Uval)))
+// linear-modifier
+TYPE_PARSER(
+ construct<OmpLinearModifier>("REF" >> pure(OmpLinearModifier::Type::Ref) ||
+ "VAL" >> pure(OmpLinearModifier::Type::Val) ||
+ "UVAL" >> pure(OmpLinearModifier::Type::Uval)))
+// LINEAR(list: linear-step)
TYPE_CONTEXT_PARSER("Omp LINEAR clause"_en_US,
construct<OmpLinearClause>(
construct<OmpLinearClause>(construct<OmpLinearClause::WithModifier>(
TYPE_PARSER(construct<OmpAlignedClause>(
nonemptyList(name), maybe(":"_tok) >> scalarIntConstantExpr))
-TYPE_PARSER(construct<OmpNameList>(pure(OmpNameList::Kind::Object), name) ||
- construct<OmpNameList>("/" >> pure(OmpNameList::Kind::Common), name / "/"))
-
-TYPE_PARSER(
- construct<OmpClause>(construct<OmpClause::Defaultmap>("DEFAULTMAP"_tok >>
- parenthesized("TOFROM"_tok >> ":"_tok >> "SCALAR"_tok))) ||
- construct<OmpClause>(construct<OmpClause::Inbranch>("INBRANCH"_tok)) ||
- construct<OmpClause>(construct<OmpClause::Mergeable>("MERGEABLE"_tok)) ||
- construct<OmpClause>(construct<OmpClause::Nogroup>("NOGROUP"_tok)) ||
- construct<OmpClause>(
- construct<OmpClause::Notinbranch>("NOTINBRANCH"_tok)) ||
- construct<OmpClause>(construct<OmpClause::Nowait>("NOWAIT"_tok)) ||
- construct<OmpClause>(construct<OmpClause::Untied>("UNTIED"_tok)) ||
- construct<OmpClause>(construct<OmpClause::Collapse>(
- "COLLAPSE"_tok >> parenthesized(scalarIntConstantExpr))) ||
- construct<OmpClause>(construct<OmpClause::Copyin>(
- "COPYIN"_tok >> parenthesized(nonemptyList(Parser<OmpNameList>{})))) ||
- construct<OmpClause>(construct<OmpClause::Copyprivate>("COPYPRIVATE"_tok >>
- parenthesized(nonemptyList(Parser<OmpNameList>{})))) ||
- construct<OmpClause>(construct<OmpClause::Device>(
- "DEVICE"_tok >> parenthesized(scalarIntExpr))) ||
- construct<OmpClause>(
- construct<OmpClause::DistSchedule>("DIST_SCHEDULE"_tok >>
+TYPE_PARSER(construct<OmpObject>(pure(OmpObject::Kind::Object), designator) ||
+ construct<OmpObject>(
+ "/" >> pure(OmpObject::Kind::Common), designator / "/"))
+
+TYPE_PARSER("DEFAULTMAP" >>
+ construct<OmpClause>(construct<OmpClause::Defaultmap>(
+ parenthesized("TOFROM"_tok >> ":"_tok >> "SCALAR"_tok))) ||
+ "INBRANCH" >> construct<OmpClause>(construct<OmpClause::Inbranch>()) ||
+ "MERGEABLE" >> construct<OmpClause>(construct<OmpClause::Mergeable>()) ||
+ "NOGROUP" >> construct<OmpClause>(construct<OmpClause::Nogroup>()) ||
+ "NOTINBRANCH" >>
+ construct<OmpClause>(construct<OmpClause::Notinbranch>()) ||
+ "NOWAIT" >> construct<OmpClause>(construct<OmpNowait>()) ||
+ "UNTIED" >> construct<OmpClause>(construct<OmpClause::Untied>()) ||
+ "COLLAPSE" >> construct<OmpClause>(construct<OmpClause::Collapse>(
+ parenthesized(scalarIntConstantExpr))) ||
+ "COPYIN" >> construct<OmpClause>(construct<OmpClause::Copyin>(
+ parenthesized(Parser<OmpObjectList>{}))) ||
+ "COPYPRIVATE" >> construct<OmpClause>(construct<OmpClause::Copyprivate>(
+ (parenthesized(Parser<OmpObjectList>{})))) ||
+ "DEVICE" >> construct<OmpClause>(construct<OmpClause::Device>(
+ parenthesized(scalarIntExpr))) ||
+ "DIST_SCHEDULE" >>
+ construct<OmpClause>(construct<OmpClause::DistSchedule>(
parenthesized("STATIC"_tok >> ","_tok >> scalarIntExpr))) ||
- construct<OmpClause>(construct<OmpClause::Final>(
- "FINAL"_tok >> parenthesized(scalarIntExpr))) ||
- construct<OmpClause>(
- construct<OmpClause::Firstprivate>("FIRSTPRIVATE"_tok >>
- parenthesized(nonemptyList(Parser<OmpNameList>{})))) ||
- construct<OmpClause>(construct<OmpClause::From>(
- "FROM"_tok >> parenthesized(nonemptyList(designator)))) ||
- construct<OmpClause>(construct<OmpClause::Grainsize>(
- "GRAINSIZE"_tok >> parenthesized(scalarIntExpr))) ||
- construct<OmpClause>(construct<OmpClause::Lastprivate>("LASTPRIVATE"_tok >>
- parenthesized(nonemptyList(Parser<OmpNameList>{})))) ||
- construct<OmpClause>(construct<OmpClause::Link>(
- "LINK"_tok >> parenthesized(nonemptyList(name)))) ||
- construct<OmpClause>(construct<OmpClause::NumTasks>(
- "NUM_TASKS"_tok >> parenthesized(scalarIntExpr))) ||
- construct<OmpClause>(construct<OmpClause::NumTeams>(
- "NUM_TEAMS"_tok >> parenthesized(scalarIntExpr))) ||
- construct<OmpClause>(construct<OmpClause::NumThreads>(
- "NUM_THREADS"_tok >> parenthesized(scalarIntExpr))) ||
- construct<OmpClause>(construct<OmpClause::Ordered>(
- "ORDERED"_tok >> maybe(parenthesized(scalarIntConstantExpr)))) ||
- construct<OmpClause>(construct<OmpClause::Priority>(
- "PRIORITY"_tok >> parenthesized(scalarIntExpr))) ||
- construct<OmpClause>(construct<OmpClause::Private>(
- "PRIVATE"_tok >> parenthesized(nonemptyList(Parser<OmpNameList>{})))) ||
- construct<OmpClause>(construct<OmpClause::Safelen>(
- "SAFELEN"_tok >> parenthesized(scalarIntConstantExpr))) ||
- construct<OmpClause>(construct<OmpClause::Shared>(
- "SHARED"_tok >> parenthesized(nonemptyList(Parser<OmpNameList>{})))) ||
- construct<OmpClause>(construct<OmpClause::Simdlen>(
- "SIMDLEN"_tok >> parenthesized(scalarIntConstantExpr))) ||
- construct<OmpClause>(construct<OmpClause::ThreadLimit>(
- "THREAD_LIMIT"_tok >> parenthesized(scalarIntExpr))) ||
- construct<OmpClause>(construct<OmpClause::To>(
- "TO"_tok >> parenthesized(nonemptyList(designator)))) ||
- construct<OmpClause>(construct<OmpClause::Uniform>(
- "UNIFORM"_tok >> parenthesized(nonemptyList(name)))) ||
- construct<OmpClause>(construct<OmpClause::UseDevicePtr>(
- "USE_DEVICE_PTR"_tok >> parenthesized(nonemptyList(name)))) ||
- construct<OmpClause>(
- "ALIGNED"_tok >> parenthesized(Parser<OmpAlignedClause>{})) ||
- construct<OmpClause>(
- "DEFAULT"_tok >> parenthesized(Parser<OmpDefaultClause>{})) ||
- construct<OmpClause>(
- "DEPEND"_tok >> parenthesized(Parser<OmpDependClause>{})) ||
- construct<OmpClause>("IF"_tok >> parenthesized(Parser<OmpIfClause>{})) ||
- construct<OmpClause>(
- "LINEAR"_tok >> parenthesized(Parser<OmpLinearClause>{})) ||
- construct<OmpClause>("MAP"_tok >> parenthesized(Parser<OmpMapClause>{})) ||
- construct<OmpClause>(
- "PROC_BIND"_tok >> parenthesized(Parser<OmpProcBindClause>{})) ||
- construct<OmpClause>(
- "REDUCTION"_tok >> parenthesized(Parser<OmpReductionClause>{})) ||
- construct<OmpClause>(
- "SCHEDULE"_tok >> parenthesized(Parser<OmpScheduleClause>{})))
-
-TYPE_PARSER(skipStuffBeforeStatement >> "!$OMP END"_sptok >>
- (construct<OmpEndDirective>(Parser<OmpLoopDirective>{})))
-
-// Omp directives enclosing do loop
+ "FINAL" >> construct<OmpClause>(
+ construct<OmpClause::Final>(parenthesized(scalarIntExpr))) ||
+ "FIRSTPRIVATE" >> construct<OmpClause>(construct<OmpClause::Firstprivate>(
+ parenthesized(Parser<OmpObjectList>{}))) ||
+ "FROM" >> construct<OmpClause>(construct<OmpClause::From>(
+ parenthesized(nonemptyList(designator)))) ||
+ "GRAINSIZE" >> construct<OmpClause>(construct<OmpClause::Grainsize>(
+ parenthesized(scalarIntExpr))) ||
+ "LASTPRIVATE" >> construct<OmpClause>(construct<OmpClause::Lastprivate>(
+ parenthesized(Parser<OmpObjectList>{}))) ||
+ "NUM_TASKS" >> construct<OmpClause>(construct<OmpClause::NumTasks>(
+ parenthesized(scalarIntExpr))) ||
+ "NUM_TEAMS" >> construct<OmpClause>(construct<OmpClause::NumTeams>(
+ parenthesized(scalarIntExpr))) ||
+ "NUM_THREADS" >> construct<OmpClause>(construct<OmpClause::NumThreads>(
+ parenthesized(scalarIntExpr))) ||
+ "ORDERED" >> construct<OmpClause>(construct<OmpClause::Ordered>(
+ maybe(parenthesized(scalarIntConstantExpr)))) ||
+ "PRIORITY" >> construct<OmpClause>(construct<OmpClause::Priority>(
+ parenthesized(scalarIntExpr))) ||
+ "PRIVATE" >> construct<OmpClause>(construct<OmpClause::Private>(
+ parenthesized(Parser<OmpObjectList>{}))) ||
+ "SAFELEN" >> construct<OmpClause>(construct<OmpClause::Safelen>(
+ parenthesized(scalarIntConstantExpr))) ||
+ "SHARED" >> construct<OmpClause>(construct<OmpClause::Shared>(
+ parenthesized(Parser<OmpObjectList>{}))) ||
+ "SIMDLEN" >> construct<OmpClause>(construct<OmpClause::Simdlen>(
+ parenthesized(scalarIntConstantExpr))) ||
+ "THREAD_LIMIT" >> construct<OmpClause>(construct<OmpClause::ThreadLimit>(
+ parenthesized(scalarIntExpr))) ||
+ "TO" >> construct<OmpClause>(construct<OmpClause::To>(
+ parenthesized(nonemptyList(designator)))) ||
+ "UNIFORM" >> construct<OmpClause>(construct<OmpClause::Uniform>(
+ parenthesized(nonemptyList(name)))) ||
+ "USE_DEVICE_PTR" >> construct<OmpClause>(construct<OmpClause::UseDevicePtr>(
+ parenthesized(nonemptyList(name)))) ||
+ "ALIGNED" >>
+ construct<OmpClause>(parenthesized(Parser<OmpAlignedClause>{})) ||
+ "DEFAULT" >>
+ construct<OmpClause>(parenthesized(Parser<OmpDefaultClause>{})) ||
+ "DEPEND" >>
+ construct<OmpClause>(parenthesized(Parser<OmpDependClause>{})) ||
+ "IF" >> construct<OmpClause>(parenthesized(Parser<OmpIfClause>{})) ||
+ "LINEAR" >>
+ construct<OmpClause>(parenthesized(Parser<OmpLinearClause>{})) ||
+ "MAP" >> construct<OmpClause>(parenthesized(Parser<OmpMapClause>{})) ||
+ "PROC_BIND" >>
+ construct<OmpClause>(parenthesized(Parser<OmpProcBindClause>{})) ||
+ "REDUCTION" >>
+ construct<OmpClause>(parenthesized(Parser<OmpReductionClause>{})) ||
+ "SCHEDULE" >>
+ construct<OmpClause>(parenthesized(Parser<OmpScheduleClause>{})))
+
+// [Clause, [Clause], ...]
TYPE_PARSER(
- construct<OmpLoopDirective>(
- construct<OmpLoopDirective::DistributeParallelDoSimd>(
- "DISTRIBUTE PARALLEL DO SIMD"_tok >> many(Parser<OmpClause>{}))) ||
- construct<OmpLoopDirective>(
- construct<OmpLoopDirective::DistributeParallelDo>(
- "DISTRIBUTE PARALLEL DO"_tok >> many(Parser<OmpClause>{}))) ||
- construct<OmpLoopDirective>(construct<OmpLoopDirective::DistributeSimd>(
- "DISTRIBUTE SIMD"_tok >> many(Parser<OmpClause>{}))) ||
- construct<OmpLoopDirective>(construct<OmpLoopDirective::Distribute>(
- "DISTRIBUTE"_tok >> many(Parser<OmpClause>{}))) ||
- construct<OmpLoopDirective>(construct<OmpLoopDirective::DoSimd>(
- "DO SIMD"_tok >> many(Parser<OmpClause>{}))) ||
- construct<OmpLoopDirective>(construct<OmpLoopDirective::Do>(
- "DO"_tok >> many(Parser<OmpClause>{}))) ||
- construct<OmpLoopDirective>(construct<OmpLoopDirective::ParallelDoSimd>(
- "PARALLEL DO SIMD"_tok >> many(Parser<OmpClause>{}))) ||
- construct<OmpLoopDirective>(construct<OmpLoopDirective::ParallelDo>(
- "PARALLEL DO"_tok >> many(Parser<OmpClause>{}))) ||
- construct<OmpLoopDirective>(construct<OmpLoopDirective::Simd>(
- "SIMD"_tok >> many(Parser<OmpClause>{}))) ||
- construct<OmpLoopDirective>(
- construct<OmpLoopDirective::TargetParallelDoSimd>(
- "TARGET PARALLEL DO SIMD"_tok >> many(Parser<OmpClause>{}))) ||
- construct<OmpLoopDirective>(construct<OmpLoopDirective::TargetParallelDo>(
- "TARGET PARALLEL DO"_tok >> many(Parser<OmpClause>{}))) ||
- construct<OmpLoopDirective>(construct<OmpLoopDirective::TargetSimd>(
- "TARGET SIMD"_tok >> many(Parser<OmpClause>{}))) ||
- construct<OmpLoopDirective>(
- construct<OmpLoopDirective::TargetTeamsDistributeParallelDoSimd>(
- "TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD"_tok >>
- many(Parser<OmpClause>{}))) ||
- construct<OmpLoopDirective>(
- construct<OmpLoopDirective::TargetTeamsDistributeParallelDo>(
- "TARGET TEAMS DISTRIBUTE PARALLEL DO"_tok >>
- many(Parser<OmpClause>{}))) ||
- construct<OmpLoopDirective>(
- construct<OmpLoopDirective::TargetTeamsDistributeSimd>(
- "TARGET TEAMS DISTRIBUTE SIMD"_tok >> many(Parser<OmpClause>{}))) ||
- construct<OmpLoopDirective>(
- construct<OmpLoopDirective::TargetTeamsDistribute>(
- "TARGET TEAMS DISTRIBUTE"_tok >> many(Parser<OmpClause>{}))) ||
- construct<OmpLoopDirective>(construct<OmpLoopDirective::TaskloopSimd>(
- "TASKLOOP SIMD" >> many(Parser<OmpClause>{}))) ||
- construct<OmpLoopDirective>(construct<OmpLoopDirective::Taskloop>(
- "TASKLOOP" >> many(Parser<OmpClause>{}))) ||
- construct<OmpLoopDirective>(
- construct<OmpLoopDirective::TeamsDistributeParallelDoSimd>(
- "TEAMS DISTRIBUTE PARALLEL DO SIMD"_tok >>
- many(Parser<OmpClause>{}))) ||
- construct<OmpLoopDirective>(
- construct<OmpLoopDirective::TeamsDistributeParallelDo>(
- "TEAMS DISTRIBUTE PARALLEL DO"_tok >> many(Parser<OmpClause>{}))) ||
- construct<OmpLoopDirective>(
- construct<OmpLoopDirective::TeamsDistributeSimd>(
- "TEAMS DISTRIBUTE SIMD"_tok >> many(Parser<OmpClause>{}))) ||
- construct<OmpLoopDirective>(construct<OmpLoopDirective::TeamsDistribute>(
- "TEAMS DISTRIBUTE"_tok >> many(Parser<OmpClause>{}))))
-
-TYPE_PARSER(construct<OmpStandaloneDirective>(
- construct<OmpStandaloneDirective::Barrier>(
- "BARRIER"_tok >> many(Parser<OmpClause>{}))) ||
- construct<OmpStandaloneDirective>(
- construct<OmpStandaloneDirective::CancellationPoint>(
- "CANCELLATION POINT"_tok >> many(Parser<OmpClause>{}))) ||
- construct<OmpStandaloneDirective>(construct<OmpStandaloneDirective::Cancel>(
- "CANCEL"_tok >> many(Parser<OmpClause>{}))) ||
- construct<OmpStandaloneDirective>(construct<OmpStandaloneDirective::Flush>(
- "FLUSH"_tok >> many(Parser<OmpClause>{}))) ||
- construct<OmpStandaloneDirective>(
- construct<OmpStandaloneDirective::TargetEnterData>(
- "TARGET ENTER DATA"_tok >> many(Parser<OmpClause>{}))) ||
- construct<OmpStandaloneDirective>(
- construct<OmpStandaloneDirective::TargetExitData>(
- "TARGET EXIT DATA"_tok >> many(Parser<OmpClause>{}))) ||
- construct<OmpStandaloneDirective>(
- construct<OmpStandaloneDirective::TargetUpdate>(
- "TARGET UPDATE"_tok >> many(Parser<OmpClause>{}))) ||
- construct<OmpStandaloneDirective>(
- construct<OmpStandaloneDirective::Taskwait>(
- "TASKWAIT"_tok >> many(Parser<OmpClause>{}))) ||
- construct<OmpStandaloneDirective>(
- construct<OmpStandaloneDirective::Taskyield>(
- "TASKYIELD"_tok >> many(Parser<OmpClause>{}))))
+ construct<OmpClauseList>(many(maybe(","_tok) >> Parser<OmpClause>{})))
+
+// (variable | /common-block | array-sections)
+TYPE_PARSER(construct<OmpObjectList>(nonemptyList(Parser<OmpObject>{})))
+// Omp directives enclosing do loop
+TYPE_PARSER("DISTRIBUTE PARALLEL DO SIMD" >>
+ construct<OmpLoopDirective>(
+ construct<OmpLoopDirective::DistributeParallelDoSimd>()) ||
+ "DISTRIBUTE PARALLEL DO" >>
+ construct<OmpLoopDirective>(
+ construct<OmpLoopDirective::DistributeParallelDo>()) ||
+ "DISTRIBUTE SIMD" >> construct<OmpLoopDirective>(
+ construct<OmpLoopDirective::DistributeSimd>()) ||
+ "DISTRIBUTE" >> construct<OmpLoopDirective>(
+ construct<OmpLoopDirective::Distribute>()) ||
+ "PARALLEL DO SIMD" >> construct<OmpLoopDirective>(
+ construct<OmpLoopDirective::ParallelDoSimd>()) ||
+ "PARALLEL DO" >> construct<OmpLoopDirective>(
+ construct<OmpLoopDirective::ParallelDo>()) ||
+ "SIMD" >>
+ construct<OmpLoopDirective>(construct<OmpLoopDirective::Simd>()) ||
+ "DO SIMD" >>
+ construct<OmpLoopDirective>(construct<OmpLoopDirective::DoSimd>()) ||
+ "DO" >> construct<OmpLoopDirective>(construct<OmpLoopDirective::Do>()) ||
+ "TARGET PARALLEL DO SIMD" >>
+ construct<OmpLoopDirective>(
+ construct<OmpLoopDirective::TargetParallelDoSimd>()) ||
+ "TARGET PARALLEL DO" >>
+ construct<OmpLoopDirective>(
+ construct<OmpLoopDirective::TargetParallelDo>()) ||
+ "TARGET SIMD" >> construct<OmpLoopDirective>(
+ construct<OmpLoopDirective::TargetSimd>()) ||
+ "TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD" >>
+ construct<OmpLoopDirective>(construct<
+ OmpLoopDirective::TargetTeamsDistributeParallelDoSimd>()) ||
+ "TARGET TEAMS DISTRIBUTE PARALLEL DO" >>
+ construct<OmpLoopDirective>(
+ construct<OmpLoopDirective::TargetTeamsDistributeParallelDo>()) ||
+ "TARGET TEAMS DISTRIBUTE SIMD" >>
+ construct<OmpLoopDirective>(
+ construct<OmpLoopDirective::TargetTeamsDistributeSimd>()) ||
+ "TARGET TEAMS DISTRIBUTE" >>
+ construct<OmpLoopDirective>(
+ construct<OmpLoopDirective::TargetTeamsDistribute>()) ||
+ "TASKLOOP SIMD" >> construct<OmpLoopDirective>(
+ construct<OmpLoopDirective::TaskloopSimd>()) ||
+ "TASKLOOP" >>
+ construct<OmpLoopDirective>(construct<OmpLoopDirective::Taskloop>()) ||
+ "TEAMS DISTRIBUTE PARALLEL DO SIMD" >>
+ construct<OmpLoopDirective>(
+ construct<OmpLoopDirective::TeamsDistributeParallelDoSimd>()) ||
+ "TEAMS DISTRIBUTE PARALLEL DO" >>
+ construct<OmpLoopDirective>(
+ construct<OmpLoopDirective::TeamsDistributeParallelDo>()) ||
+ "TEAMS DISTRIBUTE SIMD" >>
+ construct<OmpLoopDirective>(
+ construct<OmpLoopDirective::TeamsDistributeSimd>()) ||
+ "TEAMS DISTRIBUTE" >> construct<OmpLoopDirective>(
+ construct<OmpLoopDirective::TeamsDistribute>()))
+
+// Cancellation Point construct
+TYPE_PARSER("CANCELLATION POINT" >>
+ construct<OpenMPCancellationPointConstruct>(
+ "PARALLEL" >> pure(OmpCancelType::Type::Parallel) ||
+ "SECTIONS" >> pure(OmpCancelType::Type::Sections) ||
+ "DO" >> pure(OmpCancelType::Type::Do) ||
+ "TASKGROUP" >> pure(OmpCancelType::Type::Taskgroup)))
+
+// Cancel construct
TYPE_PARSER(
- construct<OpenMPLoopConstruct>(statement(Parser<OmpLoopDirective>{}),
- Parser<DoConstruct>{}, maybe(Parser<OmpEndDirective>{})))
+ "CANCEL" >> construct<OpenMPCancelConstruct>(
+ ("PARALLEL" >> pure(OmpCancelType::Type::Parallel) ||
+ "SECTIONS" >> pure(OmpCancelType::Type::Sections) ||
+ "DO" >> pure(OmpCancelType::Type::Do) ||
+ "TASKGROUP" >> pure(OmpCancelType::Type::Taskgroup)),
+ maybe("IF" >> parenthesized(scalarLogicalExpr))))
+
+// Flush construct
+TYPE_PARSER("FLUSH" >> construct<OpenMPFlushConstruct>(
+ maybe(parenthesized(Parser<OmpObjectList>{}))))
+
+// Standalone directives
+TYPE_PARSER("TARGET ENTER DATA" >>
+ construct<OmpStandaloneDirective>(
+ construct<OmpStandaloneDirective::TargetEnterData>()) ||
+ "TARGET EXIT DATA" >>
+ construct<OmpStandaloneDirective>(
+ construct<OmpStandaloneDirective::TargetExitData>()) ||
+ "TARGET UPDATE" >> construct<OmpStandaloneDirective>(
+ construct<OmpStandaloneDirective::TargetUpdate>()))
+
+// Directives enclosing structured-block
+TYPE_PARSER("MASTER" >>
+ construct<OmpBlockDirective>(construct<OmpBlockDirective::Master>()) ||
+ "ORDERED" >>
+ construct<OmpBlockDirective>(construct<OmpBlockDirective::Ordered>()) ||
+ "PARALLEL WORKSHARE" >>
+ construct<OmpBlockDirective>(
+ construct<OmpBlockDirective::ParallelWorkshare>()) ||
+ "PARALLEL" >> construct<OmpBlockDirective>(
+ construct<OmpBlockDirective::Parallel>()) ||
+ "TARGET DATA" >> construct<OmpBlockDirective>(
+ construct<OmpBlockDirective::TargetData>()) ||
+ "TARGET PARALLEL" >> construct<OmpBlockDirective>(
+ construct<OmpBlockDirective::TargetParallel>()) ||
+ "TARGET TEAMS" >> construct<OmpBlockDirective>(
+ construct<OmpBlockDirective::TargetTeams>()) ||
+ "TARGET" >>
+ construct<OmpBlockDirective>(construct<OmpBlockDirective::Target>()) ||
+ "TASKGROUP" >> construct<OmpBlockDirective>(
+ construct<OmpBlockDirective::Taskgroup>()) ||
+ "TASK" >>
+ construct<OmpBlockDirective>(construct<OmpBlockDirective::Task>()) ||
+ "TEAMS" >>
+ construct<OmpBlockDirective>(construct<OmpBlockDirective::Teams>()))
+
+TYPE_PARSER(construct<OmpReductionInitializerClause>("INITIALIZER"_tok >>
+ parenthesized("OMP_PRIV"_tok >> "="_tok >> indirect(expr))))
+
+// Declare Reduction Construct
+TYPE_PARSER(construct<OpenMPDeclareReductionConstruct>(
+ "("_tok >> Parser<OmpReductionOperator>{} / ":"_tok,
+ nonemptyList(Parser<DeclarationTypeSpec>{}) / ":"_tok,
+ Parser<OmpReductionCombiner>{} / ")"_tok,
+ maybe(Parser<OmpReductionInitializerClause>{})))
+
+// declare-target-map-type
+TYPE_PARSER(construct<OmpDeclareTargetMapType>(
+ "LINK" >> pure(OmpDeclareTargetMapType::Type::Link) ||
+ "TO" >> pure(OmpDeclareTargetMapType::Type::To)))
+
+// Declarative directives
+TYPE_PARSER(construct<OpenMPDeclareTargetConstruct>(
+ construct<OpenMPDeclareTargetConstruct>(
+ construct<OpenMPDeclareTargetConstruct::WithClause>(
+ Parser<OmpDeclareTargetMapType>{},
+ parenthesized(Parser<OmpObjectList>{}))) ||
+ lookAhead(endOfLine) >>
+ construct<OpenMPDeclareTargetConstruct>(
+ construct<OpenMPDeclareTargetConstruct::Implicit>()) ||
+ construct<OpenMPDeclareTargetConstruct>(
+ parenthesized(construct<OpenMPDeclareTargetConstruct::WithExtendedList>(
+ Parser<OmpObjectList>{})))))
+
+TYPE_PARSER(construct<OmpReductionCombiner>(Parser<AssignmentStmt>{}) ||
+ construct<OmpReductionCombiner>(
+ construct<OmpReductionCombiner::FunctionCombiner>(
+ construct<Call>(Parser<ProcedureDesignator>{},
+ parenthesized(optionalList(actualArgSpec))))))
+
+// OMP END ATOMIC
+TYPE_PARSER(construct<OmpEndAtomic>("!$OMP "_sptok >> "END ATOMIC"_tok))
+
+// OMP [SEQ_CST] ATOMIC READ [SEQ_CST]
+TYPE_PARSER(construct<OmpAtomicRead>(
+ maybe(
+ "SEQ_CST"_tok >> construct<OmpAtomicRead::SeqCst1>() / maybe(","_tok)),
+ "READ" >> maybe(","_tok) >>
+ maybe("SEQ_CST"_tok >> construct<OmpAtomicRead::SeqCst2>()) /
+ endOmpLine,
+ statement(assignmentStmt), maybe(Parser<OmpEndAtomic>{} / endOmpLine)))
+
+// OMP ATOMIC [SEQ_CST] CAPTURE [SEQ_CST]
+TYPE_PARSER(construct<OmpAtomicCapture>(
+ maybe("SEQ_CST"_tok >>
+ construct<OmpAtomicCapture::SeqCst1>() / maybe(","_tok)),
+ "CAPTURE" >> maybe(","_tok) >>
+ maybe("SEQ_CST"_tok >> construct<OmpAtomicCapture::SeqCst2>()) /
+ endOmpLine,
+ statement(assignmentStmt), statement(assignmentStmt),
+ Parser<OmpEndAtomic>{} / endOmpLine))
+
+// OMP ATOMIC [SEQ_CST] UPDATE [SEQ_CST]
+TYPE_PARSER(construct<OmpAtomicUpdate>(
+ maybe("SEQ_CST"_tok >>
+ construct<OmpAtomicUpdate::SeqCst1>() / maybe(","_tok)),
+ "UPDATE" >> maybe(","_tok) >>
+ maybe("SEQ_CST"_tok >> construct<OmpAtomicUpdate::SeqCst2>()) /
+ endOmpLine,
+ statement(assignmentStmt), maybe(Parser<OmpEndAtomic>{} / endOmpLine)))
+
+// OMP ATOMIC [SEQ_CST]
+TYPE_PARSER(construct<OmpAtomic>(
+ maybe("SEQ_CST"_tok >> construct<OmpAtomic::SeqCst>()) / endOmpLine,
+ statement(assignmentStmt), maybe(Parser<OmpEndAtomic>{} / endOmpLine)))
+
+// ATOMIC [SEQ_CST] WRITE [SEQ_CST]
+TYPE_PARSER(construct<OmpAtomicWrite>(
+ maybe(
+ "SEQ_CST"_tok >> construct<OmpAtomicWrite::SeqCst1>() / maybe(","_tok)),
+ "WRITE" >> maybe(","_tok) >>
+ maybe("SEQ_CST"_tok >> construct<OmpAtomicWrite::SeqCst2>()) /
+ endOmpLine,
+ statement(assignmentStmt), maybe(Parser<OmpEndAtomic>{} / endOmpLine)))
+
+// Atomic Construct
+TYPE_PARSER("ATOMIC" >>
+ (construct<OpenMPAtomicConstruct>(Parser<OmpAtomicRead>{}) ||
+ construct<OpenMPAtomicConstruct>(Parser<OmpAtomicCapture>{}) ||
+ construct<OpenMPAtomicConstruct>(Parser<OmpAtomicWrite>{}) ||
+ construct<OpenMPAtomicConstruct>(Parser<OmpAtomicUpdate>{}) ||
+ construct<OpenMPAtomicConstruct>(Parser<OmpAtomic>{})))
+
+// OMP CRITICAL
+TYPE_PARSER("!$OMP "_sptok >> "END"_tok >> "CRITICAL"_tok >>
+ construct<OmpEndCritical>(maybe(parenthesized(name))))
+
+TYPE_PARSER("CRITICAL" >>
+ construct<OpenMPCriticalConstruct>(maybe(parenthesized(name)),
+ maybe("HINT"_tok >> construct<OpenMPCriticalConstruct::Hint>(
+ parenthesized(constantExpr))) /
+ endOmpLine,
+ block, Parser<OmpEndCritical>{} / endOmpLine))
+
+// Declare Simd construct
+TYPE_PARSER(construct<OpenMPDeclareSimdConstruct>(
+ maybe(parenthesized(name)), Parser<OmpClauseList>{}))
+
+// Declarative construct & Threadprivate directive
+TYPE_PARSER(lookAhead(!"!$OMP END"_tok) >> "!$OMP "_tok >>
+ ("DECLARE REDUCTION" >>
+ construct<OpenMPDeclarativeConstruct>(
+ construct<OpenMPDeclarativeConstruct>(
+ Parser<OpenMPDeclareReductionConstruct>{})) /
+ endOmpLine ||
+ "DECLARE SIMD" >> construct<OpenMPDeclarativeConstruct>(
+ Parser<OpenMPDeclareSimdConstruct>{}) /
+ endOmpLine ||
+ "DECLARE TARGET" >> construct<OpenMPDeclarativeConstruct>(
+ construct<OpenMPDeclarativeConstruct>(
+ Parser<OpenMPDeclareTargetConstruct>{})) /
+ endOmpLine ||
+ "THREADPRIVATE" >>
+ construct<OpenMPDeclarativeConstruct>(
+ construct<OpenMPDeclarativeConstruct::Threadprivate>(
+ parenthesized(Parser<OmpObjectList>{})) /
+ endOmpLine)))
+
+// Block Construct
+TYPE_PARSER(construct<OpenMPBlockConstruct>(Parser<OmpBlockDirective>{},
+ Parser<OmpClauseList>{} / endOmpLine, block,
+ Parser<OmpEndBlockDirective>{} / endOmpLine))
TYPE_PARSER(construct<OpenMPStandaloneConstruct>(
- statement(Parser<OmpStandaloneDirective>{})))
+ Parser<OmpStandaloneDirective>{}, Parser<OmpClauseList>{} / endOmpLine))
+
+// OMP BARRIER
+TYPE_PARSER("BARRIER" >> construct<OpenMPBarrierConstruct>() / endOmpLine)
+
+// OMP TASKWAIT
+TYPE_PARSER("TASKWAIT" >> construct<OpenMPTaskwaitConstruct>() / endOmpLine)
+
+// OMP TASKYIELD
+TYPE_PARSER("TASKYIELD" >> construct<OpenMPTaskyieldConstruct>() / endOmpLine)
+
+// OMP SINGLE
+TYPE_PARSER(skipStuffBeforeStatement >> "!$OMP "_sptok >> "END"_tok >>
+ construct<OmpEndSingle>("SINGLE"_tok >> Parser<OmpClauseList>{}))
+
+TYPE_PARSER("SINGLE" >>
+ construct<OpenMPSingleConstruct>(Parser<OmpClauseList>{} / endOmpLine,
+ block, Parser<OmpEndSingle>{} / endOmpLine))
+
+TYPE_PARSER(skipStuffBeforeStatement >> "!$OMP "_sptok >> "END"_tok >>
+ construct<OmpEndWorkshare>("WORKSHARE"_tok))
+
+// OMP WORKSHARE
+TYPE_PARSER("WORKSHARE" >>
+ construct<OpenMPWorkshareConstruct>(endOmpLine >> block,
+ Parser<OmpEndWorkshare>{} >>
+ maybe(construct<OmpNowait>("NOWAIT"_tok)) / endOmpLine))
+
+// OMP END DO SIMD [NOWAIT]
+TYPE_PARSER(construct<OmpEndDoSimd>(maybe(construct<OmpNowait>("NOWAIT"_tok))))
+
+// OMP END DO [NOWAIT]
+TYPE_PARSER(construct<OmpEndDo>(maybe(construct<OmpNowait>("NOWAIT"_tok))))
+
+// OMP END SECTIONS [NOWAIT]
+TYPE_PARSER(skipStuffBeforeStatement >> "!$OMP "_sptok >> "END"_tok >>
+ "SECTIONS"_tok >>
+ construct<OmpEndSections>(
+ maybe("NOWAIT"_tok >> construct<OmpNowait>()) / endOmpLine))
+
+// OMP SECTIONS
+TYPE_PARSER("SECTIONS" >>
+ construct<OpenMPSectionsConstruct>(
+ Parser<OmpClauseList>{} / endOmpLine, block, Parser<OmpEndSections>{}))
+
+// OMP END PARALLEL SECTIONS [NOWAIT]
+TYPE_PARSER(skipStuffBeforeStatement >> "!$OMP "_sptok >> "END"_tok >>
+ "PARALLEL SECTIONS"_tok >>
+ construct<OmpEndParallelSections>(
+ maybe("NOWAIT"_tok >> construct<OmpNowait>()) / endOmpLine))
+
+// OMP PARALLEL SECTIONS
+TYPE_PARSER("PARALLEL SECTIONS" >> construct<OpenMPParallelSectionsConstruct>(
+ Parser<OmpClauseList>{} / endOmpLine,
+ block, Parser<OmpEndParallelSections>{}))
TYPE_CONTEXT_PARSER("OpenMP construct"_en_US,
- beginOmpDirective >> (construct<OpenMPConstruct>(
- indirect(Parser<OpenMPStandaloneConstruct>{})) ||
- construct<OpenMPConstruct>(
- indirect(Parser<OpenMPLoopConstruct>{}))))
+ skipStuffBeforeStatement >> "!$OMP "_sptok >> lookAhead(!"END"_tok) >>
+ (construct<OpenMPConstruct>(
+ indirect(Parser<OpenMPStandaloneConstruct>{})) ||
+ construct<OpenMPConstruct>(
+ indirect(Parser<OpenMPBarrierConstruct>{})) ||
+ construct<OpenMPConstruct>(
+ indirect(Parser<OpenMPTaskwaitConstruct>{})) ||
+ construct<OpenMPConstruct>(
+ indirect(Parser<OpenMPTaskyieldConstruct>{})) ||
+ construct<OpenMPConstruct>(
+ indirect(Parser<OpenMPSingleConstruct>{})) ||
+ construct<OpenMPConstruct>(
+ indirect(Parser<OpenMPSectionsConstruct>{})) ||
+ construct<OpenMPConstruct>(
+ indirect(Parser<OpenMPParallelSectionsConstruct>{})) ||
+ construct<OpenMPConstruct>(
+ indirect(Parser<OpenMPWorkshareConstruct>{})) ||
+ construct<OpenMPConstruct>(
+ indirect(Parser<OpenMPLoopConstruct>{})) ||
+ construct<OpenMPConstruct>(
+ indirect(Parser<OpenMPBlockConstruct>{})) ||
+ construct<OpenMPConstruct>(
+ indirect(Parser<OpenMPAtomicConstruct>{})) ||
+ construct<OpenMPConstruct>(
+ indirect(Parser<OpenMPCriticalConstruct>{})) ||
+ construct<OpenMPConstruct>(
+ indirect(Parser<OpenMPCancelConstruct>{})) ||
+ construct<OpenMPConstruct>(
+ indirect(Parser<OpenMPCancellationPointConstruct>{})) ||
+ construct<OpenMPConstruct>(
+ indirect(Parser<OpenMPFlushConstruct>{})) ||
+ "SECTION"_tok >> endOmpLine >>
+ construct<OpenMPConstruct>(construct<OmpSection>())))
+
+// END OMP Block directives
+TYPE_PARSER(skipStuffBeforeStatement >> "!$OMP "_sptok >> "END"_tok >>
+ construct<OmpEndBlockDirective>(indirect(Parser<OmpBlockDirective>{})))
+
+// END OMP Loop directives
+TYPE_PARSER(skipStuffBeforeStatement >> "!$OMP "_sptok >> "END"_tok >>
+ (construct<OpenMPEndLoopDirective>(
+ "DO SIMD" >> indirect(Parser<OmpEndDoSimd>{}) / endOmpLine) ||
+ construct<OpenMPEndLoopDirective>(
+ "DO" >> indirect(Parser<OmpEndDo>{}) / endOmpLine) ||
+ construct<OpenMPEndLoopDirective>(
+ indirect(Parser<OmpLoopDirective>{}) / endOmpLine)))
+
+TYPE_PARSER(construct<OpenMPLoopConstruct>(
+ Parser<OmpLoopDirective>{}, Parser<OmpClauseList>{} / endOmpLine))
} // namespace Fortran::parser
#endif // FORTRAN_PARSER_OPENMP_GRAMMAR_H_
mutator.Post(x);
}
}
-
template<typename V>
void Walk(const OmpLinearClause::WithModifier &x, V &visitor) {
if (visitor.Pre(x)) {
mutator.Post(x);
}
}
+template<typename V>
+void Walk(const OpenMPDeclareTargetConstruct::WithClause &x, V &visitor) {
+ if (visitor.Pre(x)) {
+ Walk(x.maptype, visitor);
+ Walk(x.names, visitor);
+ visitor.Post(x);
+ }
+}
+template<typename M> void Walk(OpenMPDeclareTargetConstruct::WithClause &x, M &mutator) {
+ if (mutator.Pre(x)) {
+ Walk(x.maptype, mutator);
+ Walk(x.names, mutator);
+ mutator.Post(x);
+ }
+}
+template<typename V>
+void Walk(const OpenMPDeclareTargetConstruct::WithExtendedList &x, V &visitor) {
+ if (visitor.Pre(x)) {
+ Walk(x.names, visitor);
+ visitor.Post(x);
+ }
+}
+template<typename M>
+void Walk(OpenMPDeclareTargetConstruct::WithExtendedList &x, M &mutator) {
+ if (mutator.Pre(x)) {
+ Walk(x.names, mutator);
+ mutator.Post(x);
+ }
+}
} // namespace Fortran::parser
#endif // FORTRAN_PARSER_PARSE_TREE_VISITOR_H_
struct AssignedGotoStmt;
struct PauseStmt;
struct OpenMPConstruct;
-struct OmpClause;
-struct OmpStandaloneDirective;
-struct OmpLoopDirective;
-struct OmpEndDirective;
+struct OpenMPDeclarativeConstruct;
+struct OmpBlockDirective;
+struct OpenMPEndLoopDirective;
// Cooked character stream locations
using Location = const char *;
// Implicit definitions of the Standard
// R403 scalar-xyz -> xyz
-// These class template wrappers correspond to the Standard's modifiers
+// These template class wrappers correspond to the Standard's modifiers
// scalar-xyz, constant-xzy, int-xzy, default-char-xyz, & logical-xyz.
// TODO: Implement as wrappers instead, or maybe remove.
template<typename A> struct Scalar {
Statement<common::Indirection<ProcedureDeclarationStmt>>,
Statement<OtherSpecificationStmt>,
Statement<common::Indirection<TypeDeclarationStmt>>,
- common::Indirection<StructureDef>, common::Indirection<OpenMPConstruct>,
+ common::Indirection<StructureDef>,
+ common::Indirection<OpenMPDeclarativeConstruct>,
common::Indirection<CompilerDirective>>
u;
};
// from the implicit part to the declaration constructs
struct SpecificationPart {
TUPLE_CLASS_BOILERPLATE(SpecificationPart);
- std::tuple<std::list<Statement<common::Indirection<UseStmt>>>,
+ std::tuple<std::list<OpenMPDeclarativeConstruct>,
+ std::list<Statement<common::Indirection<UseStmt>>>,
std::list<Statement<common::Indirection<ImportStmt>>>, ImplicitPart,
std::list<DeclarationConstruct>>
t;
common::Indirection<SelectTypeConstruct>,
common::Indirection<WhereConstruct>, common::Indirection<ForallConstruct>,
common::Indirection<CompilerDirective>,
- common::Indirection<OpenMPConstruct>>
+ common::Indirection<OpenMPConstruct>,
+ common::Indirection<OpenMPEndLoopDirective>>
u;
};
};
// R604 constant -> literal-constant | named-constant
-// Renamed to dodge a clash with Constant<> class template.
+// Renamed to dodge a clash with Constant<> template class.
struct ConstantValue {
UNION_CLASS_BOILERPLATE(ConstantValue);
std::variant<LiteralConstant, NamedConstant> u;
WRAPPER_CLASS_BOILERPLATE(OmpDefaultClause, Type);
};
-// List -> variable-name | / common-block /
-struct OmpNameList {
- TUPLE_CLASS_BOILERPLATE(OmpNameList);
+// variable-name | / common-block / | array-sections
+struct OmpObject {
+ TUPLE_CLASS_BOILERPLATE(OmpObject);
ENUM_CLASS(Kind, Object, Common)
- std::tuple<Kind, Name> t;
+ std::tuple<Kind, Designator> t;
+};
+
+WRAPPER_CLASS(OmpObjectList, std::list<OmpObject>);
+
+// map-type ->(TO | FROM | TOFROM | ALLOC | RELEASE | DELETE)
+struct OmpMapType {
+ TUPLE_CLASS_BOILERPLATE(OmpMapType);
+ EMPTY_CLASS(Always);
+ ENUM_CLASS(Type, To, From, Tofrom, Alloc, Release, Delete)
+ std::tuple<std::optional<Always>, Type> t;
};
-// MAP((TO | FROM | TOFROM | ALLOC | RELEASE | DELETE) : list)
+// MAP ( map-type : list)
struct OmpMapClause {
TUPLE_CLASS_BOILERPLATE(OmpMapClause);
- ENUM_CLASS(Type, To, From, Tofrom, Alloc, Release, Delete)
- std::tuple<std::optional<Type>, std::list<Name>> t;
+ std::tuple<std::optional<OmpMapType>, OmpObjectList> t;
};
// schedule-modifier-type -> MONOTONIC | NONMONOTONIC | SIMD
WRAPPER_CLASS_BOILERPLATE(OmpLinearModifier, Type);
};
-// LINEAR((modifier(list) | (list)) [: linear-step])
+// LINEAR((linear-modifier(list) | (list)) [: linear-step])
struct OmpLinearClause {
UNION_CLASS_BOILERPLATE(OmpLinearClause);
struct WithModifier {
std::variant<WithModifier, WithoutModifier> u;
};
-// reduction-identifier -> "+", "-", "*", .AND., .OR., .EQV., .NEQV.,
-// MIN, MAX, IAND, IOR, IEOR
+// reduction-identifier -> Add, Subtract, Multiply, .and., .or., .eqv., .neqv.,
+// min, max, iand, ior, ieor
struct OmpReductionOperator {
UNION_CLASS_BOILERPLATE(OmpReductionOperator);
- ENUM_CLASS(ProcedureOperator, MIN, MAX, IAND, IOR, IEOR)
- ENUM_CLASS(BinaryOperator, Add, Subtract, Multiply, AND, OR, EQV, NEQV)
- std::variant<ProcedureOperator, BinaryOperator> u;
+ std::variant<common::Indirection<DefinedOperator>, ProcedureDesignator> u;
};
// REDUCTION(reduction-identifier: list)
std::tuple<OmpReductionOperator, std::list<Designator>> t;
};
-// DEPEND(SOURCE | SINK: vec | DEPEND((IN | OUT | INOUT) : list)
-// vec -> iterator_variable [ +/- d1], x2 [ +/- d2], ...
-// d1 -> non-negative-constant
-// list -> names | array-sections
-
+// depend-vec-length -> +/- non-negative-constant
struct OmpDependSinkVecLength {
TUPLE_CLASS_BOILERPLATE(OmpDependSinkVecLength);
std::tuple<common::Indirection<DefinedOperator>, ScalarIntConstantExpr> t;
};
+// depend-vec -> iterator_variable [+/- depend-vec-length]
struct OmpDependSinkVec {
TUPLE_CLASS_BOILERPLATE(OmpDependSinkVec);
std::tuple<Name, std::optional<OmpDependSinkVecLength>> t;
WRAPPER_CLASS_BOILERPLATE(OmpDependenceType, Type);
};
+// DEPEND(SOURCE | SINK: vec | DEPEND((IN | OUT | INOUT) : list)
struct OmpDependClause {
UNION_CLASS_BOILERPLATE(OmpDependClause);
EMPTY_CLASS(Source);
std::variant<Source, Sink, InOut> u;
};
+// NOWAIT
+EMPTY_CLASS(OmpNowait);
+
// OpenMP Clauses
struct OmpClause {
UNION_CLASS_BOILERPLATE(OmpClause);
EMPTY_CLASS(Mergeable);
EMPTY_CLASS(Nogroup);
EMPTY_CLASS(Notinbranch);
- EMPTY_CLASS(Nowait);
EMPTY_CLASS(Untied);
WRAPPER_CLASS(Collapse, ScalarIntConstantExpr);
- WRAPPER_CLASS(Copyin, std::list<OmpNameList>);
- WRAPPER_CLASS(Copyprivate, std::list<OmpNameList>);
+ WRAPPER_CLASS(Copyin, OmpObjectList);
+ WRAPPER_CLASS(Copyprivate, OmpObjectList);
WRAPPER_CLASS(Device, ScalarIntExpr);
WRAPPER_CLASS(DistSchedule, ScalarIntExpr);
WRAPPER_CLASS(Final, ScalarIntExpr);
- WRAPPER_CLASS(Firstprivate, std::list<OmpNameList>);
+ WRAPPER_CLASS(Firstprivate, OmpObjectList);
WRAPPER_CLASS(From, std::list<Designator>);
WRAPPER_CLASS(Grainsize, ScalarIntExpr);
- WRAPPER_CLASS(Lastprivate, std::list<OmpNameList>);
- WRAPPER_CLASS(Link, std::list<Name>);
+ WRAPPER_CLASS(Lastprivate, OmpObjectList);
WRAPPER_CLASS(NumTasks, ScalarIntExpr);
WRAPPER_CLASS(NumTeams, ScalarIntExpr);
WRAPPER_CLASS(NumThreads, ScalarIntExpr);
WRAPPER_CLASS(Ordered, std::optional<ScalarIntConstantExpr>);
WRAPPER_CLASS(Priority, ScalarIntExpr);
- WRAPPER_CLASS(Private, std::list<OmpNameList>);
+ WRAPPER_CLASS(Private, OmpObjectList);
WRAPPER_CLASS(Safelen, ScalarIntConstantExpr);
- WRAPPER_CLASS(Shared, std::list<OmpNameList>);
+ WRAPPER_CLASS(Shared, OmpObjectList);
WRAPPER_CLASS(Simdlen, ScalarIntConstantExpr);
WRAPPER_CLASS(ThreadLimit, ScalarIntExpr);
WRAPPER_CLASS(To, std::list<Designator>);
WRAPPER_CLASS(Uniform, std::list<Name>);
WRAPPER_CLASS(UseDevicePtr, std::list<Name>);
- std::variant<Defaultmap, Inbranch, Mergeable, Nogroup, Notinbranch, Nowait,
+ std::variant<Defaultmap, Inbranch, Mergeable, Nogroup, Notinbranch, OmpNowait,
Untied, Collapse, Copyin, Copyprivate, Device, DistSchedule, Final,
- Firstprivate, From, Grainsize, Lastprivate, Link, NumTasks, NumTeams,
+ Firstprivate, From, Grainsize, Lastprivate, NumTasks, NumTeams,
NumThreads, Ordered, Priority, Private, Safelen, Shared, Simdlen,
ThreadLimit, To, Uniform, UseDevicePtr, OmpAlignedClause,
OmpDefaultClause, OmpDependClause, OmpIfClause, OmpLinearClause,
u;
};
+WRAPPER_CLASS(OmpClauseList, std::list<OmpClause>);
+
+// SECTIONS, PARALLEL SECTIONS
+WRAPPER_CLASS(OmpEndSections, std::optional<OmpNowait>);
+WRAPPER_CLASS(OmpEndParallelSections, std::optional<OmpNowait>);
+EMPTY_CLASS(OmpSection);
+
+struct OpenMPSectionsConstruct {
+ TUPLE_CLASS_BOILERPLATE(OpenMPSectionsConstruct);
+ std::tuple<OmpClauseList, Block, OmpEndSections> t;
+};
+
+struct OpenMPParallelSectionsConstruct {
+ TUPLE_CLASS_BOILERPLATE(OpenMPParallelSectionsConstruct);
+ std::tuple<OmpClauseList, Block, OmpEndParallelSections> t;
+};
+
+// WORKSHARE
+EMPTY_CLASS(OmpEndWorkshare);
+struct OpenMPWorkshareConstruct {
+ TUPLE_CLASS_BOILERPLATE(OpenMPWorkshareConstruct);
+ std::tuple<Block, std::optional<OmpNowait>> t;
+};
+
+// SINGLE
+WRAPPER_CLASS(OmpEndSingle, OmpClauseList);
+struct OpenMPSingleConstruct {
+ TUPLE_CLASS_BOILERPLATE(OpenMPSingleConstruct);
+ std::tuple<OmpClauseList, Block, OmpEndSingle> t;
+};
+
+// OpenMP directive enclosing block
+struct OmpBlockDirective {
+ UNION_CLASS_BOILERPLATE(OmpBlockDirective);
+ EMPTY_CLASS(Master);
+ EMPTY_CLASS(Ordered);
+ EMPTY_CLASS(ParallelWorkshare);
+ EMPTY_CLASS(Parallel);
+ EMPTY_CLASS(TargetData);
+ EMPTY_CLASS(TargetParallel);
+ EMPTY_CLASS(TargetTeams);
+ EMPTY_CLASS(Target);
+ EMPTY_CLASS(Taskgroup);
+ EMPTY_CLASS(Task);
+ EMPTY_CLASS(Teams);
+ std::variant<Master, Ordered, ParallelWorkshare, Parallel, TargetData,
+ TargetParallel, TargetTeams, Target, Taskgroup, Task, Teams>
+ u;
+};
+
+struct OmpDeclareTargetMapType {
+ ENUM_CLASS(Type, Link, To)
+ WRAPPER_CLASS_BOILERPLATE(OmpDeclareTargetMapType, Type);
+};
+
+struct OpenMPDeclareTargetConstruct {
+ UNION_CLASS_BOILERPLATE(OpenMPDeclareTargetConstruct);
+ 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<WithClause, WithExtendedList, Implicit> u;
+};
+
+struct OmpReductionCombiner {
+ UNION_CLASS_BOILERPLATE(OmpReductionCombiner);
+ WRAPPER_CLASS(FunctionCombiner, Call);
+ std::variant<AssignmentStmt, FunctionCombiner> u;
+};
+
+WRAPPER_CLASS(OmpReductionInitializerClause, common::Indirection<Expr>);
+
+struct OpenMPDeclareReductionConstruct {
+ TUPLE_CLASS_BOILERPLATE(OpenMPDeclareReductionConstruct);
+ std::tuple<OmpReductionOperator, std::list<DeclarationTypeSpec>,
+ OmpReductionCombiner, std::optional<OmpReductionInitializerClause>>
+ t;
+};
+
+struct OpenMPDeclareSimdConstruct {
+ TUPLE_CLASS_BOILERPLATE(OpenMPDeclareSimdConstruct);
+ std::tuple<std::optional<Name>, OmpClauseList> t;
+};
+
+struct OpenMPDeclarativeConstruct {
+ UNION_CLASS_BOILERPLATE(OpenMPDeclarativeConstruct);
+ WRAPPER_CLASS(Threadprivate, OmpObjectList);
+ std::variant<OpenMPDeclareReductionConstruct, OpenMPDeclareSimdConstruct,
+ OpenMPDeclareTargetConstruct, Threadprivate>
+ u;
+};
+
+// CRITICAL [Name] <block> END CRITICAL [Name]
+WRAPPER_CLASS(OmpEndCritical, std::optional<Name>);
+struct OpenMPCriticalConstruct {
+ TUPLE_CLASS_BOILERPLATE(OpenMPCriticalConstruct);
+ WRAPPER_CLASS(Hint, ConstantExpr);
+ std::tuple<std::optional<Name>, std::optional<Hint>, Block, OmpEndCritical> t;
+};
+
+// END ATOMIC
+EMPTY_CLASS(OmpEndAtomic);
+
+// ATOMIC READ
+struct OmpAtomicRead {
+ TUPLE_CLASS_BOILERPLATE(OmpAtomicRead);
+ EMPTY_CLASS(SeqCst1);
+ EMPTY_CLASS(SeqCst2);
+ std::tuple<std::optional<SeqCst1>, std::optional<SeqCst2>,
+ Statement<AssignmentStmt>, std::optional<OmpEndAtomic>>
+ t;
+};
+
+// ATOMIC WRITE
+struct OmpAtomicWrite {
+ TUPLE_CLASS_BOILERPLATE(OmpAtomicWrite);
+ EMPTY_CLASS(SeqCst1);
+ EMPTY_CLASS(SeqCst2);
+ std::tuple<std::optional<SeqCst1>, std::optional<SeqCst2>,
+ Statement<AssignmentStmt>, std::optional<OmpEndAtomic>>
+ t;
+};
+
+// ATOMIC UPDATE
+struct OmpAtomicUpdate {
+ TUPLE_CLASS_BOILERPLATE(OmpAtomicUpdate);
+ EMPTY_CLASS(SeqCst1);
+ EMPTY_CLASS(SeqCst2);
+ std::tuple<std::optional<SeqCst1>, std::optional<SeqCst2>,
+ Statement<AssignmentStmt>, std::optional<OmpEndAtomic>>
+ t;
+};
+
+// ATOMIC CAPTURE
+struct OmpAtomicCapture {
+ TUPLE_CLASS_BOILERPLATE(OmpAtomicCapture);
+ EMPTY_CLASS(SeqCst1);
+ EMPTY_CLASS(SeqCst2);
+ WRAPPER_CLASS(Stmt1, Statement<AssignmentStmt>);
+ WRAPPER_CLASS(Stmt2, Statement<AssignmentStmt>);
+ std::tuple<std::optional<SeqCst1>, std::optional<SeqCst2>, Stmt1, Stmt2,
+ OmpEndAtomic>
+ t;
+};
+
+// ATOMIC
+struct OmpAtomic {
+ TUPLE_CLASS_BOILERPLATE(OmpAtomic);
+ EMPTY_CLASS(SeqCst);
+ std::tuple<std::optional<SeqCst>, Statement<AssignmentStmt>,
+ std::optional<OmpEndAtomic>>
+ t;
+};
+
+struct OpenMPAtomicConstruct {
+ UNION_CLASS_BOILERPLATE(OpenMPAtomicConstruct);
+ std::variant<OmpAtomicRead, OmpAtomicWrite, OmpAtomicCapture, OmpAtomicUpdate,
+ OmpAtomic>
+ u;
+};
+
struct OmpLoopDirective {
UNION_CLASS_BOILERPLATE(OmpLoopDirective);
- WRAPPER_CLASS(DistributeParallelDoSimd, std::list<OmpClause>);
- WRAPPER_CLASS(DistributeParallelDo, std::list<OmpClause>);
- WRAPPER_CLASS(DistributeSimd, std::list<OmpClause>);
- WRAPPER_CLASS(Distribute, std::list<OmpClause>);
- WRAPPER_CLASS(DoSimd, std::list<OmpClause>);
- WRAPPER_CLASS(Do, std::list<OmpClause>);
- WRAPPER_CLASS(ParallelDoSimd, std::list<OmpClause>);
- WRAPPER_CLASS(ParallelDo, std::list<OmpClause>);
- WRAPPER_CLASS(Simd, std::list<OmpClause>);
- WRAPPER_CLASS(TargetParallelDoSimd, std::list<OmpClause>);
- WRAPPER_CLASS(TargetParallelDo, std::list<OmpClause>);
- WRAPPER_CLASS(TargetTeamsDistributeParallelDoSimd, std::list<OmpClause>);
- WRAPPER_CLASS(TargetTeamsDistributeParallelDo, std::list<OmpClause>);
- WRAPPER_CLASS(TargetTeamsDistributeSimd, std::list<OmpClause>);
- WRAPPER_CLASS(TargetTeamsDistribute, std::list<OmpClause>);
- WRAPPER_CLASS(TargetSimd, std::list<OmpClause>);
- WRAPPER_CLASS(TaskloopSimd, std::list<OmpClause>);
- WRAPPER_CLASS(Taskloop, std::list<OmpClause>);
- WRAPPER_CLASS(TeamsDistributeParallelDoSimd, std::list<OmpClause>);
- WRAPPER_CLASS(TeamsDistributeParallelDo, std::list<OmpClause>);
- WRAPPER_CLASS(TeamsDistributeSimd, std::list<OmpClause>);
- WRAPPER_CLASS(TeamsDistribute, std::list<OmpClause>);
+ EMPTY_CLASS(DistributeParallelDoSimd);
+ EMPTY_CLASS(DistributeParallelDo);
+ EMPTY_CLASS(DistributeSimd);
+ EMPTY_CLASS(Distribute);
+ EMPTY_CLASS(ParallelDoSimd);
+ EMPTY_CLASS(ParallelDo);
+ EMPTY_CLASS(Do);
+ EMPTY_CLASS(DoSimd);
+ EMPTY_CLASS(Simd);
+ EMPTY_CLASS(TargetParallelDoSimd);
+ EMPTY_CLASS(TargetParallelDo);
+ EMPTY_CLASS(TargetTeamsDistributeParallelDoSimd);
+ EMPTY_CLASS(TargetTeamsDistributeParallelDo);
+ EMPTY_CLASS(TargetTeamsDistributeSimd);
+ EMPTY_CLASS(TargetTeamsDistribute);
+ EMPTY_CLASS(TargetSimd);
+ EMPTY_CLASS(TaskloopSimd);
+ EMPTY_CLASS(Taskloop);
+ EMPTY_CLASS(TeamsDistributeParallelDoSimd);
+ EMPTY_CLASS(TeamsDistributeParallelDo);
+ EMPTY_CLASS(TeamsDistributeSimd);
+ EMPTY_CLASS(TeamsDistribute);
std::variant<DistributeParallelDoSimd, DistributeParallelDo, DistributeSimd,
- Distribute, DoSimd, Do, ParallelDoSimd, ParallelDo, Simd,
+ Distribute, ParallelDoSimd, ParallelDo, Do, DoSimd, Simd,
TargetParallelDoSimd, TargetParallelDo,
TargetTeamsDistributeParallelDoSimd, TargetTeamsDistributeParallelDo,
TargetTeamsDistributeSimd, TargetTeamsDistribute, TargetSimd,
u;
};
+// Cancel/Cancellation type
+struct OmpCancelType {
+ ENUM_CLASS(Type, Parallel, Sections, Do, Taskgroup)
+ WRAPPER_CLASS_BOILERPLATE(OmpCancelType, Type);
+};
+
+// CANCELLATION POINT
+WRAPPER_CLASS(OpenMPCancellationPointConstruct, OmpCancelType);
+
+// CANCEL
+struct OpenMPCancelConstruct {
+ TUPLE_CLASS_BOILERPLATE(OpenMPCancelConstruct);
+ WRAPPER_CLASS(If, ScalarLogicalExpr);
+ std::tuple<OmpCancelType, std::optional<If>> t;
+};
+
+// FLUSH
+WRAPPER_CLASS(OpenMPFlushConstruct, std::optional<OmpObjectList>);
+
+// Standalone constructs
struct OmpStandaloneDirective {
UNION_CLASS_BOILERPLATE(OmpStandaloneDirective);
- WRAPPER_CLASS(Barrier, std::list<OmpClause>);
- WRAPPER_CLASS(CancellationPoint, std::list<OmpClause>);
- WRAPPER_CLASS(Cancel, std::list<OmpClause>);
- WRAPPER_CLASS(Flush, std::list<OmpClause>);
- WRAPPER_CLASS(TargetEnterData, std::list<OmpClause>);
- WRAPPER_CLASS(TargetExitData, std::list<OmpClause>);
- WRAPPER_CLASS(TargetUpdate, std::list<OmpClause>);
- WRAPPER_CLASS(Taskwait, std::list<OmpClause>);
- WRAPPER_CLASS(Taskyield, std::list<OmpClause>);
- std::variant<Barrier, CancellationPoint, Cancel, Flush, TargetEnterData,
- TargetExitData, TargetUpdate, Taskwait, Taskyield>
+ EMPTY_CLASS(TargetEnterData);
+ EMPTY_CLASS(TargetExitData);
+ EMPTY_CLASS(TargetUpdate);
+ std::variant<TargetEnterData, TargetExitData, TargetUpdate> u;
+};
+
+EMPTY_CLASS(OpenMPTaskyieldConstruct);
+EMPTY_CLASS(OpenMPTaskwaitConstruct);
+EMPTY_CLASS(OpenMPBarrierConstruct);
+WRAPPER_CLASS(OmpEndBlockDirective, common::Indirection<OmpBlockDirective>);
+
+// DO / DO SIMD
+WRAPPER_CLASS(OmpEndDoSimd, std::optional<OmpNowait>);
+WRAPPER_CLASS(OmpEndDo, std::optional<OmpNowait>);
+struct OpenMPEndLoopDirective {
+ UNION_CLASS_BOILERPLATE(OpenMPEndLoopDirective);
+ std::variant<common::Indirection<OmpEndDoSimd>, common::Indirection<OmpEndDo>,
+ common::Indirection<OmpLoopDirective>>
u;
};
-struct OmpEndDirective {
- UNION_CLASS_BOILERPLATE(OmpEndDirective);
- std::variant<OmpLoopDirective> u;
+struct OpenMPBlockConstruct {
+ TUPLE_CLASS_BOILERPLATE(OpenMPBlockConstruct);
+ std::tuple<OmpBlockDirective, OmpClauseList, Block, OmpEndBlockDirective> t;
};
struct OpenMPLoopConstruct {
TUPLE_CLASS_BOILERPLATE(OpenMPLoopConstruct);
- std::tuple<Statement<OmpLoopDirective>, DoConstruct,
- std::optional<OmpEndDirective>>
- t;
+ std::tuple<OmpLoopDirective, OmpClauseList> t;
};
-WRAPPER_CLASS(OpenMPStandaloneConstruct, Statement<OmpStandaloneDirective>);
+struct OpenMPStandaloneConstruct {
+ TUPLE_CLASS_BOILERPLATE(OpenMPStandaloneConstruct);
+ std::tuple<OmpStandaloneDirective, OmpClauseList> t;
+};
struct OpenMPConstruct {
UNION_CLASS_BOILERPLATE(OpenMPConstruct);
std::variant<common::Indirection<OpenMPStandaloneConstruct>,
- common::Indirection<OpenMPLoopConstruct>>
+ common::Indirection<OpenMPBarrierConstruct>,
+ common::Indirection<OpenMPTaskwaitConstruct>,
+ common::Indirection<OpenMPTaskyieldConstruct>,
+ common::Indirection<OpenMPSingleConstruct>,
+ common::Indirection<OpenMPSectionsConstruct>,
+ common::Indirection<OpenMPParallelSectionsConstruct>,
+ common::Indirection<OpenMPWorkshareConstruct>,
+ common::Indirection<OpenMPLoopConstruct>,
+ common::Indirection<OpenMPBlockConstruct>,
+ common::Indirection<OpenMPCancellationPointConstruct>,
+ common::Indirection<OpenMPCancelConstruct>,
+ common::Indirection<OpenMPFlushConstruct>,
+ common::Indirection<OpenMPAtomicConstruct>,
+ common::Indirection<OpenMPCriticalConstruct>, OmpSection>
u;
};
constexpr auto skipBadLine{SkipPast<'\n'>{} >> construct<ErrorRecovery>()};
constexpr auto executionPartErrorRecovery{stmtErrorRecoveryStart >>
!"END"_tok >> !"CONTAINS"_tok >> !"ELSE"_tok >> !"CASE"_tok >>
- !"TYPE IS"_tok >> !"CLASS"_tok >> !"RANK"_tok >> skipBadLine};
+ !"TYPE IS"_tok >> !"CLASS"_tok >> !"RANK"_tok >>
+ !("!$OMP "_sptok >> "END"_tok) >> skipBadLine};
} // namespace Fortran::parser
#endif // FORTRAN_PARSER_STMT_PARSER_H_
constexpr Parser<ContainsStmt> containsStmt; // R1543
constexpr Parser<CompilerDirective> compilerDirective;
constexpr Parser<OpenMPConstruct> openmpConstruct;
+constexpr Parser<OpenMPDeclarativeConstruct> openmpDeclarativeConstruct;
+constexpr Parser<OpenMPEndLoopDirective> openmpEndLoopDirective;
} // namespace Fortran::parser
#endif // FORTRAN_PARSER_TYPE_PARSERS_H_
Walk(std::get<Name>(x.t));
}
// OpenMP Clauses & Directives
- void Unparse(const OmpNameList &x) {
- bool isCommon{
- std::get<OmpNameList::Kind>(x.t) == OmpNameList::Kind::Common};
+ void Unparse(const OmpObject &x) {
+ bool isCommon{std::get<OmpObject::Kind>(x.t) == OmpObject::Kind::Common};
const char *slash{isCommon ? "/" : ""};
- Put(slash), Walk(std::get<Name>(x.t)), Put(slash);
+ Put(slash), Walk(std::get<Designator>(x.t)), Put(slash);
}
+ void Unparse(const OmpMapType::Always &x) { Word("ALWAYS,"); }
void Unparse(const OmpMapClause &x) {
- Word(" MAP("), Walk(std::get<std::optional<OmpMapClause::Type>>(x.t), ":");
- Walk(std::get<std::list<Name>>(x.t), ", ");
+ Word("MAP(");
+ Walk(std::get<std::optional<OmpMapType>>(x.t), ":");
+ Walk(std::get<OmpObjectList>(x.t));
Put(") ");
}
void Unparse(const OmpScheduleModifier &x) {
Walk(",", std::get<std::optional<OmpScheduleModifier::Modifier2>>(x.t));
}
void Unparse(const OmpScheduleClause &x) {
- Word(" SCHEDULE(");
+ Word("SCHEDULE(");
Walk(std::get<std::optional<OmpScheduleModifier>>(x.t));
Walk(std::get<OmpScheduleClause::ScheduleType>(x.t));
Walk(",", std::get<std::optional<ScalarIntExpr>>(x.t));
Put(")");
}
void Unparse(const OmpAlignedClause &x) {
- Word(" ALIGNED("), Walk(std::get<std::list<Name>>(x.t), ",");
+ Word("ALIGNED("), Walk(std::get<std::list<Name>>(x.t), ",");
Walk(std::get<std::optional<ScalarIntConstantExpr>>(x.t));
Put(") ");
}
void Unparse(const OmpIfClause &x) {
- Word(" IF("),
+ Word("IF("),
Walk(std::get<std::optional<OmpIfClause::DirectiveNameModifier>>(x.t),
":");
Walk(std::get<ScalarLogicalExpr>(x.t));
Put(") ");
}
void Unparse(const OmpLinearClause::WithoutModifier &x) {
- Word(" LINEAR("), Walk(x.names, ", ");
+ Word("LINEAR("), Walk(x.names, ", ");
Walk(":", x.step);
Put(")");
}
void Unparse(const OmpLinearClause::WithModifier &x) {
- Word(" LINEAR("), Walk(x.modifier), Put("("), Walk(x.names, ","), Put(")");
+ Word("LINEAR("), Walk(x.modifier), Put("("), Walk(x.names, ","), Put(")");
Walk(":", x.step);
Put(")");
}
- void Unparse(const OmpReductionOperator::BinaryOperator &x) {
- switch (x) {
- case OmpReductionOperator::BinaryOperator::Add: Put("+"); break;
- case OmpReductionOperator::BinaryOperator::Subtract: Put("-"); break;
- case OmpReductionOperator::BinaryOperator::Multiply: Put("*"); break;
- case OmpReductionOperator::BinaryOperator::AND: Word(".AND."); break;
- case OmpReductionOperator::BinaryOperator::OR: Word(".OR."); break;
- case OmpReductionOperator::BinaryOperator::EQV: Word(".EQV."); break;
- case OmpReductionOperator::BinaryOperator::NEQV: Word(".NEQV."); break;
- default: break;
- }
- }
void Unparse(const OmpReductionClause &x) {
- Word(" REDUCTION(");
+ Word("REDUCTION(");
Walk(std::get<OmpReductionOperator>(x.t));
Put(":");
Walk(std::get<std::list<Designator>>(x.t), ",");
Walk(std::get<std::optional<OmpDependSinkVecLength>>(x.t));
}
void Unparse(const OmpDependClause::InOut &x) {
+ Put("(");
Walk(std::get<OmpDependenceType>(x.t));
Put(":");
Walk(std::get<std::list<Designator>>(x.t), ",");
+ Put(")");
}
- void Unparse(const OmpDependClause &x) {
- std::visit(common::visitors{[&](const OmpDependClause::Source &y) {
- Word("DEPEND(SOURCE)");
- },
- [&](const OmpDependClause::Sink &y) {
- Word("DEPEND(SINK:");
- Walk(y.v);
- Put(")");
- },
- [&](const OmpDependClause::InOut &y) {
- Word("DEPEND(");
- Walk(y.t);
- Put(")");
- }},
+ bool Pre(const OmpDependClause &x) {
+ return std::visit(common::visitors{[&](const OmpDependClause::Source &y) {
+ Word("DEPEND(SOURCE)");
+ return false;
+ },
+ [&](const OmpDependClause::Sink &y) {
+ Word("DEPEND(SINK:");
+ Walk(y.v);
+ Put(")");
+ return false;
+ },
+ [&](const OmpDependClause::InOut &y) {
+ Word("DEPEND");
+ return true;
+ }},
x.u);
}
+ bool Pre(const OmpDefaultClause &x) {
+ Word("DEFAULT(");
+ return true;
+ }
+ void Post(const OmpDefaultClause &x) { Put(")"); }
+ bool Pre(const OmpProcBindClause &x) {
+ Word("PROC_BIND(");
+ return true;
+ }
+ void Post(const OmpProcBindClause &x) { Put(")"); }
void Before(const OmpClause::Defaultmap &x) {
- Word(" DEFAULTMAP(TOFROM:SCALAR)");
+ Word("DEFAULTMAP(TOFROM:SCALAR)");
}
void Before(const OmpClause::Inbranch &x) { Word("INBRANCH"); }
void Before(const OmpClause::Mergeable &x) { Word("MERGEABLE"); }
void Before(const OmpClause::Nogroup &x) { Word("NOGROUP"); }
void Before(const OmpClause::Notinbranch &x) { Word("NOTINBRANCH"); }
- void Before(const OmpClause::Nowait &x) { Word("NOWAIT"); }
void Before(const OmpClause::Untied &x) { Word("UNTIED"); }
+ void Unparse(const OmpNowait &) { Word("NOWAIT"); }
void Unparse(const OmpClause::Collapse &x) {
Word("COLLAPSE(");
Walk(x.v);
}
void Unparse(const OmpClause::Copyin &x) {
Word("COPYIN(");
- Walk(x.v, ",");
+ Walk(x.v);
Put(")");
}
void Unparse(const OmpClause::Copyprivate &x) {
Word("COPYPRIVATE(");
- Walk(x.v, ",");
+ Walk(x.v);
Put(")");
}
void Unparse(const OmpClause::Device &x) {
}
void Unparse(const OmpClause::Firstprivate &x) {
Word("FIRSTPRIVATE(");
- Walk(x.v, ",");
+ Walk(x.v);
Put(")");
}
void Unparse(const OmpClause::From &x) {
}
void Unparse(const OmpClause::Lastprivate &x) {
Word("LASTPRIVATE(");
- Walk(x.v, ",");
- Put(")");
- }
- void Unparse(const OmpClause::Link &x) {
- Word("LINK(");
- Walk(x.v, ",");
+ Walk(x.v);
Put(")");
}
void Unparse(const OmpClause::NumTasks &x) {
}
void Unparse(const OmpClause::Private &x) {
Word("PRIVATE(");
- Walk(x.v, ",");
+ Walk(x.v);
Put(")");
}
void Unparse(const OmpClause::Safelen &x) {
}
void Unparse(const OmpClause::Shared &x) {
Word("SHARED(");
- Walk(x.v, ",");
+ Walk(x.v);
Put(")");
}
void Unparse(const OmpClause::To &x) {
void Unparse(const OmpLoopDirective &x) {
std::visit(
common::visitors{
- [&](const OmpLoopDirective::DistributeParallelDoSimd &y) {
+ [&](const OmpLoopDirective::DistributeParallelDoSimd &) {
Word("DISTRIBUTE PARALLEL DO SIMD ");
- Walk(y.v, " ");
},
- [&](const OmpLoopDirective::DistributeParallelDo &y) {
+ [&](const OmpLoopDirective::DistributeParallelDo &) {
Word("DISTRIBUTE PARALLEL DO ");
- Walk(y.v, " ");
},
- [&](const OmpLoopDirective::DistributeSimd &y) {
+ [&](const OmpLoopDirective::DistributeSimd &) {
Word("DISTRIBUTE SIMD ");
- Walk(y.v, " ");
- },
- [&](const OmpLoopDirective::Distribute &y) {
- Word("DISTRIBUTE ");
- Walk(y.v, " ");
- },
- [&](const OmpLoopDirective::DoSimd &y) {
- Word("DO SIMD ");
- Walk(y.v, " ");
- },
- [&](const OmpLoopDirective::Do &y) {
- Word("DO ");
- Walk(y.v, " ");
},
- [&](const OmpLoopDirective::ParallelDoSimd &y) {
+ [&](const OmpLoopDirective::Distribute &) { Word("DISTRIBUTE "); },
+ [&](const OmpLoopDirective::ParallelDoSimd &) {
Word("PARALLEL DO SIMD ");
- Walk(y.v, " ");
},
- [&](const OmpLoopDirective::ParallelDo &y) {
- Word("PARALLEL DO ");
- Walk(y.v, " ");
- },
- [&](const OmpLoopDirective::Simd &y) {
- Word("SIMD ");
- Walk(y.v, " ");
- },
- [&](const OmpLoopDirective::TargetParallelDoSimd &y) {
+ [&](const OmpLoopDirective::ParallelDo &) { Word("PARALLEL DO "); },
+ [&](const OmpLoopDirective::Do &) { Word("DO "); },
+ [&](const OmpLoopDirective::DoSimd &) { Word("Do SIMD "); },
+ [&](const OmpLoopDirective::Simd &) { Word("SIMD "); },
+ [&](const OmpLoopDirective::TargetParallelDoSimd &) {
Word("TARGET PARALLEL DO SIMD ");
- Walk(y.v, " ");
},
- [&](const OmpLoopDirective::TargetParallelDo &y) {
+ [&](const OmpLoopDirective::TargetParallelDo &) {
Word("TARGET PARALLEL DO ");
- Walk(y.v, " ");
},
- [&](const OmpLoopDirective::TargetTeamsDistributeParallelDoSimd
- &y) {
+ [&](const OmpLoopDirective::TargetTeamsDistributeParallelDoSimd &) {
Word("TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD ");
- Walk(y.v, " ");
},
- [&](const OmpLoopDirective::TargetTeamsDistributeParallelDo &y) {
+ [&](const OmpLoopDirective::TargetTeamsDistributeParallelDo &) {
Word("TARGET TEAMS DISTRIBUTE PARALLEL DO ");
- Walk(y.v, " ");
},
- [&](const OmpLoopDirective::TargetTeamsDistributeSimd &y) {
+ [&](const OmpLoopDirective::TargetTeamsDistributeSimd &) {
Word("TARGET TEAMS DISTRIBUTE SIMD ");
- Walk(y.v, " ");
},
- [&](const OmpLoopDirective::TargetTeamsDistribute &y) {
+ [&](const OmpLoopDirective::TargetTeamsDistribute &) {
Word("TARGET TEAMS DISTRIBUTE ");
- Walk(y.v, " ");
- },
- [&](const OmpLoopDirective::TargetSimd &y) {
- Word("TARGET SIMD ");
- Walk(y.v, " ");
},
- [&](const OmpLoopDirective::TaskloopSimd &y) {
+ [&](const OmpLoopDirective::TargetSimd &) { Word("TARGET SIMD "); },
+ [&](const OmpLoopDirective::TaskloopSimd &) {
Word("TASKLOOP SIMD ");
- Walk(y.v, " ");
},
- [&](const OmpLoopDirective::Taskloop &y) {
- Word("TASKLOOP ");
- Walk(y.v, " ");
- },
- [&](const OmpLoopDirective::TeamsDistributeParallelDoSimd &y) {
+ [&](const OmpLoopDirective::Taskloop &) { Word("TASKLOOP "); },
+ [&](const OmpLoopDirective::TeamsDistributeParallelDoSimd &) {
Word("TEAMS DISTRIBUTE PARALLEL DO SIMD ");
- Walk(y.v, " ");
},
- [&](const OmpLoopDirective::TeamsDistributeParallelDo &y) {
+ [&](const OmpLoopDirective::TeamsDistributeParallelDo &) {
Word("TEAMS DISTRIBUTE PARALLEL DO ");
- Walk(y.v, " ");
},
- [&](const OmpLoopDirective::TeamsDistributeSimd &y) {
+ [&](const OmpLoopDirective::TeamsDistributeSimd &) {
Word("TEAMS DISTRIBUTE SIMD ");
- Walk(y.v, " ");
},
- [&](const OmpLoopDirective::TeamsDistribute &y) {
+ [&](const OmpLoopDirective::TeamsDistribute &) {
Word("TEAMS DISTRIBUTE ");
- Walk(y.v, " ");
}},
x.u);
- Put("\n");
- Indent();
}
+ void Unparse(const OmpObjectList &x) { Walk(x.v, ","); }
void Unparse(const OmpStandaloneDirective &x) {
- std::visit(common::visitors{[&](const OmpStandaloneDirective::Barrier &y) {
- Word("BARRIER ");
- Walk(y.v, " ");
- },
- [&](const OmpStandaloneDirective::CancellationPoint &y) {
- Word("CANCELLATION POINT ");
- Walk(y.v, " ");
- },
- [&](const OmpStandaloneDirective::Cancel &y) {
- Word("CANCEL ");
- Walk(y.v, " ");
- },
- [&](const OmpStandaloneDirective::Flush &y) {
- Word("FLUSH ");
- Walk(y.v, " ");
- },
- [&](const OmpStandaloneDirective::TargetEnterData &y) {
- Word("TARGET ENTER DATA ");
- Walk(y.v, " ");
- },
- [&](const OmpStandaloneDirective::TargetExitData &y) {
- Word("TARGET EXIT DATA ");
- Walk(y.v, " ");
- },
- [&](const OmpStandaloneDirective::TargetUpdate &y) {
- Word("TARGET UPDATE ");
- Walk(y.v, " ");
- },
- [&](const OmpStandaloneDirective::Taskwait &y) {
- Word("TASKWAIT ");
- Walk(y.v, " ");
- },
- [&](const OmpStandaloneDirective::Taskyield &y) {
- Word("TASKYIELD ");
- Walk(y.v, " ");
- }},
+ std::visit(
+ common::visitors{[&](const OmpStandaloneDirective::TargetEnterData &) {
+ Word("TARGET ENTER DATA ");
+ },
+ [&](const OmpStandaloneDirective::TargetExitData &) {
+ Word("TARGET EXIT DATA ");
+ },
+ [&](const OmpStandaloneDirective::TargetUpdate &) {
+ Word("TARGET UPDATE ");
+ }},
x.u);
+ }
+ void Unparse(const OmpBlockDirective &x) {
+ std::visit(
+ common::visitors{
+ [&](const OmpBlockDirective::Master &y) { Word("MASTER"); },
+ [&](const OmpBlockDirective::Ordered &) { Word("ORDERED "); },
+ [&](const OmpBlockDirective::ParallelWorkshare &) {
+ Word("PARALLEL WORKSHARE ");
+ },
+ [&](const OmpBlockDirective::Parallel &) { Word("PARALLEL "); },
+ [&](const OmpBlockDirective::TargetData &) {
+ Word("TARGET DATA ");
+ },
+ [&](const OmpBlockDirective::TargetParallel &) {
+ Word("TARGET PARALLEL ");
+ },
+ [&](const OmpBlockDirective::TargetTeams &) {
+ Word("TARGET TEAMS ");
+ },
+ [&](const OmpBlockDirective::Target &) { Word("TARGET "); },
+ [&](const OmpBlockDirective::Taskgroup &) { Word("TASKGROUP "); },
+ [&](const OmpBlockDirective::Task &) { Word("TASK "); },
+ [&](const OmpBlockDirective::Teams &) { Word("TEAMS "); }},
+ x.u);
+ }
+ void Unparse(const OmpAtomic &x) {
+ BeginOpenMP();
+ Word("!$OMP ATOMIC");
+ Walk(std::get<std::optional<OmpAtomic::SeqCst>>(x.t), " SEQ_CST");
Put("\n");
- Indent();
+ EndOpenMP();
+ Walk(std::get<Statement<AssignmentStmt>>(x.t));
+ BeginOpenMP();
+ Walk(std::get<std::optional<OmpEndAtomic>>(x.t), "!$OMP END ATOMIC\n");
+ EndOpenMP();
+ }
+ void Unparse(const OmpAtomicCapture &x) {
+ BeginOpenMP();
+ Word("!$OMP ATOMIC");
+ Walk(std::get<std::optional<OmpAtomicCapture::SeqCst1>>(x.t), " SEQ_CST,");
+ Word(" CAPTURE");
+ Walk(std::get<std::optional<OmpAtomicCapture::SeqCst2>>(x.t), " ,SEQ_CST");
+ Put("\n");
+ EndOpenMP();
+ Walk(std::get<OmpAtomicCapture::Stmt1>(x.t));
+ Put("\n");
+ Walk(std::get<OmpAtomicCapture::Stmt2>(x.t));
+ BeginOpenMP();
+ Word("!$OMP END ATOMIC\n");
+ EndOpenMP();
+ }
+ void Unparse(const OmpAtomicRead &x) {
+ BeginOpenMP();
+ Word("!$OMP ATOMIC");
+ Walk(std::get<std::optional<OmpAtomicRead::SeqCst1>>(x.t), " SEQ_CST,");
+ Word(" READ");
+ Walk(std::get<std::optional<OmpAtomicRead::SeqCst2>>(x.t), " ,SEQ_CST");
+ Put("\n");
+ EndOpenMP();
+ Walk(std::get<Statement<AssignmentStmt>>(x.t));
+ BeginOpenMP();
+ Walk(std::get<std::optional<OmpEndAtomic>>(x.t), "!$OMP END ATOMIC\n");
+ EndOpenMP();
+ }
+ void Unparse(const OmpAtomicUpdate &x) {
+ BeginOpenMP();
+ Word("!$OMP ATOMIC");
+ Walk(std::get<std::optional<OmpAtomicUpdate::SeqCst1>>(x.t), " SEQ_CST,");
+ Word(" UPDATE");
+ Walk(std::get<std::optional<OmpAtomicUpdate::SeqCst2>>(x.t), " ,SEQ_CST");
+ Put("\n");
+ EndOpenMP();
+ Walk(std::get<Statement<AssignmentStmt>>(x.t));
+ BeginOpenMP();
+ Walk(std::get<std::optional<OmpEndAtomic>>(x.t), "!$OMP END ATOMIC\n");
+ EndOpenMP();
+ }
+ void Unparse(const OmpAtomicWrite &x) {
+ BeginOpenMP();
+ Word("!$OMP ATOMIC");
+ Walk(std::get<std::optional<OmpAtomicWrite::SeqCst1>>(x.t), " SEQ_CST,");
+ Word(" WRITE");
+ Walk(std::get<std::optional<OmpAtomicWrite::SeqCst2>>(x.t), " ,SEQ_CST");
+ Put("\n");
+ EndOpenMP();
+ Walk(std::get<Statement<AssignmentStmt>>(x.t));
+ BeginOpenMP();
+ Walk(std::get<std::optional<OmpEndAtomic>>(x.t), "!$OMP END ATOMIC\n");
+ EndOpenMP();
+ }
+ void Unparse(const OmpEndCritical &x) {
+ Walk(" (", x.v, ")");
+ EndOpenMP();
+ }
+ void Unparse(const OpenMPCriticalConstruct &x) {
+ BeginOpenMP();
+ Word("!$OMP CRITICAL");
+ Walk(" (", std::get<std::optional<Name>>(x.t), ")");
+ Walk(" HINT(", std::get<std::optional<OpenMPCriticalConstruct::Hint>>(x.t),
+ ")");
+ Put("\n");
+ EndOpenMP();
+ Walk(std::get<Block>(x.t), "");
+ BeginOpenMP();
+ Word("!$OMP END CRITICAL");
+ Walk(std::get<OmpEndCritical>(x.t));
+ Put("\n");
+ EndOpenMP();
}
- void Unparse(const OmpEndDirective &x) {
- Outdent();
- std::visit(common::visitors{[&](const OmpLoopDirective &y) {
- Word("!$OMP END ");
- Walk(y);
- }},
+ void Unparse(const OpenMPDeclareTargetConstruct::WithClause &x) {
+ Walk(x.maptype), Put("("), Walk(x.names), Put(")");
+ }
+ void Unparse(const OpenMPDeclareTargetConstruct::WithExtendedList &x) {
+ Put("("), Walk(x.names), Put(")");
+ }
+ void Unparse(const OmpReductionInitializerClause &x) {
+ Word(" INITIALIZER(OMP_PRIV = ");
+ Walk(x.v);
+ Put(")");
+ }
+ void Unparse(const OmpReductionCombiner::FunctionCombiner &x) {
+ const auto &pd = std::get<ProcedureDesignator>(x.v.t);
+ const auto &args = std::get<std::list<ActualArgSpec>>(x.v.t);
+ Walk(pd);
+ if (args.empty()) {
+ if (std::holds_alternative<ProcComponentRef>(pd.u)) {
+ Put("()");
+ }
+ } else {
+ Walk("(", args, ", ", ")");
+ }
+ }
+ void Unparse(const OpenMPDeclareReductionConstruct &x) {
+ Put("(");
+ Walk(std::get<OmpReductionOperator>(x.t)), Put(" : ");
+ Walk(std::get<std::list<DeclarationTypeSpec>>(x.t), ","), Put(" : ");
+ Walk(std::get<OmpReductionCombiner>(x.t));
+ Put(")");
+ Walk(std::get<std::optional<OmpReductionInitializerClause>>(x.t));
+ }
+ bool Pre(const OpenMPDeclarativeConstruct &x) {
+ BeginOpenMP();
+ Word("!$OMP ");
+ return std::visit(
+ common::visitors{[&](const OpenMPDeclareReductionConstruct &y) {
+ Word("DECLARE REDUCTION ");
+ return true;
+ },
+ [&](const OpenMPDeclareSimdConstruct &y) {
+ Word("DECLARE SIMD ");
+ Walk("(", std::get<std::optional<Name>>(y.t), ")");
+ Walk(std::get<OmpClauseList>(y.t));
+ Put("\n");
+ EndOpenMP();
+ return false;
+ },
+ [&](const OpenMPDeclareTargetConstruct &y) {
+ Word("DECLARE TARGET ");
+ return true;
+ },
+ [&](const OpenMPDeclarativeConstruct::Threadprivate &y) {
+ Word("THREADPRIVATE (");
+ return true;
+ }},
x.u);
}
+ void Post(const OpenMPDeclarativeConstruct &x) {
+ Put("\n");
+ EndOpenMP();
+ }
+ void Post(const OpenMPDeclarativeConstruct::Threadprivate &x) {
+ Put(")\n");
+ EndOpenMP();
+ }
+ void Unparse(const OmpEndDoSimd &x) {
+ BeginOpenMP();
+ Word("DO SIMD ");
+ Walk(x.v);
+ EndOpenMP();
+ }
+ void Unparse(const OmpEndDo &x) {
+ BeginOpenMP();
+ Word("DO ");
+ Walk(x.v);
+ EndOpenMP();
+ }
+ bool Pre(const OpenMPBarrierConstruct &x) {
+ BeginOpenMP();
+ Word("!$OMP BARRIER");
+ Put("\n");
+ EndOpenMP();
+ return false;
+ }
+ void Unparse(const OpenMPSingleConstruct &x) {
+ BeginOpenMP();
+ Word("!$OMP SINGLE");
+ Walk(std::get<OmpClauseList>(x.t));
+ EndOpenMP();
+ Put("\n");
+ Walk(std::get<Block>(x.t), "");
+ BeginOpenMP();
+ Word("!$OMP END SINGLE ");
+ Walk(std::get<OmpEndSingle>(x.t));
+ Put("\n");
+ EndOpenMP();
+ }
+ void Unparse(const OmpSection &x) {
+ BeginOpenMP();
+ Word("!$OMP SECTION");
+ Put("\n");
+ EndOpenMP();
+ }
+ void Unparse(const OpenMPSectionsConstruct &x) {
+ BeginOpenMP();
+ Word("!$OMP SECTIONS");
+ Walk(std::get<OmpClauseList>(x.t));
+ Put("\n");
+ EndOpenMP();
+ Walk(std::get<Block>(x.t), "");
+ BeginOpenMP();
+ Word("!$OMP END SECTIONS");
+ Put("\n");
+ EndOpenMP();
+ }
+ void Unparse(const OpenMPParallelSectionsConstruct &x) {
+ BeginOpenMP();
+ Word("!$OMP PARALLEL SECTIONS");
+ Walk(std::get<OmpClauseList>(x.t));
+ Put("\n");
+ EndOpenMP();
+ Walk(std::get<Block>(x.t), "");
+ BeginOpenMP();
+ Word("!$OMP END PARALLEL SECTIONS");
+ Put("\n");
+ EndOpenMP();
+ }
+ void Unparse(const OpenMPWorkshareConstruct &x) {
+ BeginOpenMP();
+ Word("!$OMP WORKSHARE");
+ Put("\n");
+ EndOpenMP();
+ Walk(std::get<Block>(x.t), "");
+ BeginOpenMP();
+ Word("!$OMP END WORKSHARE ");
+ Walk(std::get<std::optional<OmpNowait>>(x.t));
+ Put("\n");
+ EndOpenMP();
+ }
+ bool Pre(const OpenMPTaskyieldConstruct &x) {
+ BeginOpenMP();
+ Word("!$OMP TASKYIELD");
+ Put("\n");
+ EndOpenMP();
+ return false;
+ }
+ bool Pre(const OpenMPTaskwaitConstruct &x) {
+ BeginOpenMP();
+ Word("!$OMP TASKWAIT");
+ Put("\n");
+ EndOpenMP();
+ return false;
+ }
+ void Unparse(const OpenMPCancellationPointConstruct &x) {
+ BeginOpenMP();
+ Word("!$OMP CANCELLATION POINT ");
+ Walk(x.v);
+ Put("\n");
+ EndOpenMP();
+ }
+ void Unparse(const OpenMPCancelConstruct &x) {
+ BeginOpenMP();
+ Word("!$OMP CANCEL ");
+ Walk(std::get<OmpCancelType>(x.t));
+ Walk(std::get<std::optional<OpenMPCancelConstruct::If>>(x.t));
+ Put("\n");
+ EndOpenMP();
+ }
+ void Unparse(const OpenMPFlushConstruct &x) {
+ BeginOpenMP();
+ Word("!$OMP FLUSH");
+ if ((x.v).has_value()) {
+ Put("(");
+ Walk(x.v);
+ Put(")");
+ }
+ Put("\n");
+ EndOpenMP();
+ }
+ bool Pre(const OpenMPEndLoopDirective &x) {
+ BeginOpenMP();
+ Word("!$OMP END ");
+ return true;
+ }
+ void Post(const OpenMPEndLoopDirective &x) {
+ Put("\n");
+ EndOpenMP();
+ }
+ void Unparse(const OmpClauseList &x) { Walk(" ", x.v, " "); }
void Unparse(const OpenMPStandaloneConstruct &x) {
- Outdent();
+ BeginOpenMP();
Word("!$OMP ");
- Walk(x.v);
+ Walk(std::get<OmpStandaloneDirective>(x.t));
+ Walk(std::get<OmpClauseList>(x.t));
+ Put("\n");
+ EndOpenMP();
}
- bool Pre(const OpenMPLoopConstruct &x) {
- Outdent();
+ void Unparse(const OpenMPBlockConstruct &x) {
+ BeginOpenMP();
Word("!$OMP ");
- return true;
+ Walk(std::get<OmpBlockDirective>(x.t));
+ Walk(std::get<OmpClauseList>(x.t));
+ Put("\n");
+ EndOpenMP();
+ Walk(std::get<Block>(x.t), "");
+ BeginOpenMP();
+ Word("!$OMP END ");
+ Walk(std::get<OmpEndBlockDirective>(x.t));
+ Put("\n");
+ EndOpenMP();
+ }
+ void Unparse(const OpenMPLoopConstruct &x) {
+ BeginOpenMP();
+ Word("!$OMP ");
+ Walk(std::get<OmpLoopDirective>(x.t));
+ Walk(std::get<OmpClauseList>(x.t));
+ Put("\n");
+ EndOpenMP();
}
-
void Unparse(const BasedPointerStmt &x) {
Word("POINTER ("), Walk(std::get<0>(x.t)), Put(", ");
Walk(std::get<1>(x.t));
WALK_NESTED_ENUM(OmpDefaultClause, Type) // OMP DEFAULT
WALK_NESTED_ENUM(OmpScheduleModifierType, ModType) // OMP schedule-modifier
WALK_NESTED_ENUM(OmpLinearModifier, Type) // OMP linear-modifier
- WALK_NESTED_ENUM(
- OmpReductionOperator, ProcedureOperator) // OMP reduction-identifier
WALK_NESTED_ENUM(OmpDependenceType, Type) // OMP dependence-type
- WALK_NESTED_ENUM(OmpMapClause, Type) // OMP map-type
+ WALK_NESTED_ENUM(OmpMapType, Type) // OMP map-type
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
void Done() const { CHECK(indent_ == 0); }
CHECK(indent_ >= indentationAmount_);
indent_ -= indentationAmount_;
}
+ void BeginOpenMP() { openmpDirective_ = true; }
+ void EndOpenMP() { openmpDirective_ = false; }
// Call back to the traversal framework.
template<typename T> void Walk(const T &x) {
std::set<CharBlock> structureComponents_;
Encoding encoding_{Encoding::UTF8};
bool capitalizeKeywords_{true};
+ bool openmpDirective_{false};
bool backslashEscapes_{false};
preStatementType *preStatement_{nullptr};
};
void UnparseVisitor::Put(char ch) {
+ int sav = indent_;
+ if (openmpDirective_) {
+ indent_ = 0;
+ }
if (column_ <= 1) {
if (ch == '\n') {
return;
for (int j{0}; j < indent_; ++j) {
out_ << ' ';
}
- out_ << '&';
- column_ = indent_ + 3;
+ if (openmpDirective_) {
+ out_ << "!$OMP&";
+ column_ = 8;
+ } else {
+ out_ << '&';
+ column_ = indent_ + 3;
+ }
}
out_ << ch;
+ if (openmpDirective_) {
+ indent_ = sav;
+ }
}
void UnparseVisitor::Put(const char *str) {
NODE(parser, ObjectDecl)
NODE(parser, OldParameterStmt)
NODE(parser, OmpAlignedClause)
+ NODE(parser, OpenMPAtomicConstruct)
+ NODE(parser, OmpEndAtomic)
+ NODE(parser, OpenMPCriticalConstruct)
+ NODE(parser::OpenMPCriticalConstruct, Hint)
+ NODE(parser, OmpEndCritical)
+ NODE(parser, OmpAtomic)
+ NODE(parser::OmpAtomic, SeqCst)
+ NODE(parser, OmpAtomicCapture)
+ NODE(parser::OmpAtomicCapture, SeqCst1)
+ NODE(parser::OmpAtomicCapture, SeqCst2)
+ NODE(parser::OmpAtomicCapture, Stmt1)
+ NODE(parser::OmpAtomicCapture, Stmt2)
+ NODE(parser, OmpAtomicRead)
+ NODE(parser::OmpAtomicRead, SeqCst1)
+ NODE(parser::OmpAtomicRead, SeqCst2)
+ NODE(parser, OmpAtomicUpdate)
+ NODE(parser::OmpAtomicUpdate, SeqCst1)
+ NODE(parser::OmpAtomicUpdate, SeqCst2)
+ NODE(parser, OmpAtomicWrite)
+ NODE(parser::OmpAtomicWrite, SeqCst1)
+ NODE(parser::OmpAtomicWrite, SeqCst2)
+ NODE(parser, OmpBlockDirective)
+ NODE(parser::OmpBlockDirective, Master)
+ NODE(parser::OmpBlockDirective, Ordered)
+ NODE(parser::OmpBlockDirective, Parallel)
+ NODE(parser::OmpBlockDirective, ParallelWorkshare)
+ NODE(parser, OpenMPSingleConstruct)
+ NODE(parser, OmpEndSingle)
+ NODE(parser, OpenMPWorkshareConstruct)
+ NODE(parser, OmpEndDo)
+ NODE(parser, OmpEndDoSimd)
+ NODE(parser::OmpBlockDirective, Target)
+ NODE(parser::OmpBlockDirective, TargetData)
+ NODE(parser::OmpBlockDirective, TargetParallel)
+ NODE(parser::OmpBlockDirective, TargetTeams)
+ NODE(parser::OmpBlockDirective, Task)
+ NODE(parser::OmpBlockDirective, Taskgroup)
+ NODE(parser::OmpBlockDirective, Teams)
NODE(parser, OmpClause)
+ NODE(parser, OmpClauseList)
NODE(parser::OmpClause, Collapse)
NODE(parser::OmpClause, Copyin)
NODE(parser::OmpClause, Copyprivate)
NODE(parser::OmpClause, Grainsize)
NODE(parser::OmpClause, Inbranch)
NODE(parser::OmpClause, Lastprivate)
- NODE(parser::OmpClause, Link)
NODE(parser::OmpClause, Mergeable)
NODE(parser::OmpClause, Nogroup)
NODE(parser::OmpClause, Notinbranch)
- NODE(parser::OmpClause, Nowait)
NODE(parser::OmpClause, NumTasks)
NODE(parser::OmpClause, NumTeams)
NODE(parser::OmpClause, NumThreads)
NODE(parser::OmpDependenceType, Type)
NODE(parser, OmpDependSinkVec)
NODE(parser, OmpDependSinkVecLength)
- NODE(parser, OmpEndDirective)
+ NODE(parser, OmpEndBlockDirective)
+ NODE(parser, OmpIfClause)
+ NODE(parser::OmpIfClause, DirectiveNameModifier)
NODE(parser, OmpLinearClause)
NODE(parser::OmpLinearClause, WithModifier)
NODE(parser::OmpLinearClause, WithoutModifier)
NODE(parser, OmpLinearModifier)
NODE(parser::OmpLinearModifier, Type)
+ NODE(parser, OpenMPDeclareReductionConstruct)
+ NODE(parser, OmpReductionInitializerClause)
+ NODE(parser, OmpReductionCombiner)
+ NODE(parser::OmpReductionCombiner, FunctionCombiner)
+ NODE(parser, OpenMPDeclareSimdConstruct)
+ NODE(parser, OmpDeclareTargetMapType)
+ NODE(parser::OmpDeclareTargetMapType, Type)
+ NODE(parser, OpenMPEndLoopDirective)
+ NODE(parser, OpenMPDeclareTargetConstruct)
+ NODE(parser::OpenMPDeclareTargetConstruct, Implicit)
+ NODE(parser::OpenMPDeclareTargetConstruct, WithClause)
+ NODE(parser::OpenMPDeclareTargetConstruct, WithExtendedList)
+ NODE(parser::OpenMPDeclarativeConstruct, Threadprivate)
+ NODE(parser, OpenMPLoopConstruct)
NODE(parser, OmpLoopDirective)
NODE(parser::OmpLoopDirective, Distribute)
NODE(parser::OmpLoopDirective, DistributeParallelDo)
NODE(parser::OmpLoopDirective, DistributeParallelDoSimd)
NODE(parser::OmpLoopDirective, DistributeSimd)
- NODE(parser::OmpLoopDirective, Do)
- NODE(parser::OmpLoopDirective, DoSimd)
NODE(parser::OmpLoopDirective, ParallelDo)
NODE(parser::OmpLoopDirective, ParallelDoSimd)
+ NODE(parser::OmpLoopDirective, DoSimd)
+ NODE(parser::OmpLoopDirective, Do)
NODE(parser::OmpLoopDirective, Simd)
NODE(parser::OmpLoopDirective, TargetParallelDo)
NODE(parser::OmpLoopDirective, TargetParallelDoSimd)
NODE(parser::OmpLoopDirective, TeamsDistributeParallelDo)
NODE(parser::OmpLoopDirective, TeamsDistributeParallelDoSimd)
NODE(parser::OmpLoopDirective, TeamsDistributeSimd)
- NODE(parser, OmpIfClause)
- NODE(parser::OmpIfClause, DirectiveNameModifier)
+ NODE(parser, OmpNowait)
NODE(parser, OmpScheduleClause)
NODE(parser::OmpScheduleClause, ScheduleType)
NODE(parser, OmpScheduleModifier)
NODE(parser, OmpScheduleModifierType)
NODE(parser::OmpScheduleModifierType, ModType)
NODE(parser, OmpMapClause)
- NODE(parser::OmpMapClause, Type)
- NODE(parser, OmpNameList)
- NODE(parser::OmpNameList, Kind)
+ NODE(parser, OmpMapType)
+ NODE(parser::OmpMapType, Always)
+ NODE(parser::OmpMapType, Type)
+ NODE(parser, OmpObject)
+ NODE(parser::OmpObject, Kind)
+ NODE(parser, OmpObjectList)
NODE(parser, OmpProcBindClause)
NODE(parser::OmpProcBindClause, Type)
NODE(parser, OmpReductionOperator)
- NODE(parser::OmpReductionOperator, ProcedureOperator)
- NODE(parser::OmpReductionOperator, BinaryOperator)
+ NODE(parser, OmpSection)
NODE(parser, OmpStandaloneDirective)
- NODE(parser::OmpStandaloneDirective, Barrier)
- NODE(parser::OmpStandaloneDirective, Cancel)
- NODE(parser::OmpStandaloneDirective, CancellationPoint)
- NODE(parser::OmpStandaloneDirective, Flush)
+ NODE(parser, OpenMPCancellationPointConstruct)
+ NODE(parser, OpenMPCancelConstruct)
+ NODE(parser::OpenMPCancelConstruct, If)
+ NODE(parser, OmpCancelType)
+ NODE(parser::OmpCancelType, Type)
+ NODE(parser, OpenMPFlushConstruct)
NODE(parser::OmpStandaloneDirective, TargetEnterData)
NODE(parser::OmpStandaloneDirective, TargetExitData)
NODE(parser::OmpStandaloneDirective, TargetUpdate)
- NODE(parser::OmpStandaloneDirective, Taskwait)
- NODE(parser::OmpStandaloneDirective, Taskyield)
+ NODE(parser, OpenMPBarrierConstruct)
+ NODE(parser, OpenMPTaskwaitConstruct)
+ NODE(parser, OpenMPTaskyieldConstruct)
NODE(parser, OpenMPConstruct)
- NODE(parser, OpenMPLoopConstruct)
+ NODE(parser, OpenMPBlockConstruct)
+ NODE(parser, OpenMPDeclarativeConstruct)
NODE(parser, OpenMPStandaloneConstruct)
NODE(parser, OmpReductionClause)
+ NODE(parser, OpenMPSectionsConstruct)
+ NODE(parser, OpenMPParallelSectionsConstruct)
+ NODE(parser, OmpEndSections)
+ NODE(parser, OmpEndParallelSections)
NODE(parser, Only)
NODE(parser, OpenStmt)
NODE(parser, Optional)