[flang] Merge pull request flang-compiler/f18#137 from flang-compiler/omppar

Omppar

Original-commit: flang-compiler/f18@d341464e7f
Reviewed-on: https://github.com/flang-compiler/f18/pull/137

Due to a conflicting rebase during the linearizing of flang-compiler/f18, this commit squashes a number of other commits:

flang-compiler/f18@cfbc8bd16b Add OpenMP Block directives and some declarative directive(TBD:declare reduction and declare target)
flang-compiler/f18@d198352f84 Removed extra code from resolveing conflict of the merge.
flang-compiler/f18@85911a0e80 fix some grammar and unparsing.
flang-compiler/f18@43bcfb7cd3 OpenMP declartive directive can be after function declaration line. OpenMP Loop construct will be treated as if statement instead of block because currently parser cannot construct the loop if loop end with Label [Continue] Use DefinedOperator and ProcedureDesignator instead of create a new Parser and postpone the validity of operator in semantic.
flang-compiler/f18@5d83b50ad3 Merge branch 'master' into omppar
flang-compiler/f18@8c666436a5 remove "HEAD" code and resolve conflict.
This commit is contained in:
hsuauthai 2018-07-20 15:49:19 -07:00 committed by GitHub
parent 698581c784
commit 08b2684271
8 changed files with 1295 additions and 492 deletions

View File

@ -49,7 +49,7 @@ namespace Fortran::parser {
// 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{
@ -96,7 +96,7 @@ TYPE_CONTEXT_PARSER("specification construct"_en_US,
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 ->
@ -263,7 +263,7 @@ TYPE_PARSER(construct<ProgramUnit>(indirect(functionSubprogram)) ||
// [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)))
@ -274,7 +274,7 @@ TYPE_CONTEXT_PARSER("specification part"_en_US,
// 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)))};
@ -391,6 +391,7 @@ constexpr auto executableConstruct{
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)))};

View File

@ -39,10 +39,9 @@
// 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) ||
@ -59,15 +58,17 @@ TYPE_PARSER(construct<OmpProcBindClause>(
// 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
@ -87,45 +88,29 @@ TYPE_PARSER(construct<OmpScheduleClause>(maybe(Parser<OmpScheduleModifier>{}),
"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)))
@ -138,9 +123,9 @@ TYPE_PARSER(
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>(
@ -150,12 +135,13 @@ TYPE_CONTEXT_PARSER("Omp Depend clause"_en_US,
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>(
@ -168,187 +154,437 @@ TYPE_CONTEXT_PARSER("Omp LINEAR clause"_en_US,
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<OmpObject>(pure(OmpObject::Kind::Object), designator) ||
construct<OmpObject>(
"/" >> pure(OmpObject::Kind::Common), designator / "/"))
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("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>{})))
"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>{})))
TYPE_PARSER(skipStuffBeforeStatement >> "!$OMP END"_sptok >>
(construct<OmpEndDirective>(Parser<OmpLoopDirective>{})))
// [Clause, [Clause], ...]
TYPE_PARSER(
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(
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("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>()))
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>{}))))
// 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_

View File

@ -672,7 +672,6 @@ void Walk(format::IntrinsicTypeDataEditDesc &x, M &mutator) {
mutator.Post(x);
}
}
template<typename V>
void Walk(const OmpLinearClause::WithModifier &x, V &visitor) {
if (visitor.Pre(x)) {
@ -706,6 +705,35 @@ void Walk(OmpLinearClause::WithoutModifier &x, M &mutator) {
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_

View File

@ -249,10 +249,9 @@ struct AssignStmt;
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 *;
@ -260,7 +259,7 @@ 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 {
@ -365,7 +364,8 @@ struct SpecificationConstruct {
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;
};
@ -403,7 +403,8 @@ struct DeclarationConstruct {
// 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;
@ -487,7 +488,8 @@ struct ExecutableConstruct {
common::Indirection<SelectTypeConstruct>,
common::Indirection<WhereConstruct>, common::Indirection<ForallConstruct>,
common::Indirection<CompilerDirective>,
common::Indirection<OpenMPConstruct>>
common::Indirection<OpenMPConstruct>,
common::Indirection<OpenMPEndLoopDirective>>
u;
};
@ -829,7 +831,7 @@ struct LiteralConstant {
};
// 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;
@ -3236,18 +3238,27 @@ struct OmpDefaultClause {
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;
};
// MAP((TO | FROM | TOFROM | ALLOC | RELEASE | DELETE) : list)
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 ( 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
@ -3293,7 +3304,7 @@ struct OmpLinearModifier {
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 {
@ -3316,13 +3327,11 @@ struct OmpLinearClause {
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)
@ -3331,16 +3340,13 @@ struct OmpReductionClause {
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;
@ -3351,6 +3357,7 @@ struct OmpDependenceType {
WRAPPER_CLASS_BOILERPLATE(OmpDependenceType, Type);
};
// DEPEND(SOURCE | SINK: vec | DEPEND((IN | OUT | INOUT) : list)
struct OmpDependClause {
UNION_CLASS_BOILERPLATE(OmpDependClause);
EMPTY_CLASS(Source);
@ -3362,6 +3369,9 @@ struct OmpDependClause {
std::variant<Source, Sink, InOut> u;
};
// NOWAIT
EMPTY_CLASS(OmpNowait);
// OpenMP Clauses
struct OmpClause {
UNION_CLASS_BOILERPLATE(OmpClause);
@ -3370,35 +3380,33 @@ struct 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,
@ -3406,32 +3414,202 @@ struct OmpClause {
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,
@ -3440,40 +3618,81 @@ struct OmpLoopDirective {
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;
};

View File

@ -77,7 +77,8 @@ constexpr auto stmtErrorRecoveryStart{ignoredStatementPrefix};
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_

View File

@ -143,6 +143,8 @@ constexpr Parser<EntryStmt> entryStmt; // R1541
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_

View File

@ -1673,15 +1673,16 @@ public:
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) {
@ -1689,48 +1690,36 @@ public:
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), ",");
@ -1745,35 +1734,48 @@ public:
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);
@ -1781,12 +1783,12 @@ public:
}
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) {
@ -1806,7 +1808,7 @@ public:
}
void Unparse(const OmpClause::Firstprivate &x) {
Word("FIRSTPRIVATE(");
Walk(x.v, ",");
Walk(x.v);
Put(")");
}
void Unparse(const OmpClause::From &x) {
@ -1821,12 +1823,7 @@ public:
}
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) {
@ -1855,7 +1852,7 @@ public:
}
void Unparse(const OmpClause::Private &x) {
Word("PRIVATE(");
Walk(x.v, ",");
Walk(x.v);
Put(")");
}
void Unparse(const OmpClause::Safelen &x) {
@ -1875,7 +1872,7 @@ public:
}
void Unparse(const OmpClause::Shared &x) {
Word("SHARED(");
Walk(x.v, ",");
Walk(x.v);
Put(")");
}
void Unparse(const OmpClause::To &x) {
@ -1896,159 +1893,401 @@ public:
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 OmpEndDirective &x) {
Outdent();
std::visit(common::visitors{[&](const OmpLoopDirective &y) {
Word("!$OMP END ");
Walk(y);
}},
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 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 Unparse(const OpenMPStandaloneConstruct &x) {
Outdent();
Word("!$OMP ");
Walk(x.v);
void Post(const OpenMPDeclarativeConstruct &x) {
Put("\n");
EndOpenMP();
}
bool Pre(const OpenMPLoopConstruct &x) {
Outdent();
Word("!$OMP ");
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) {
BeginOpenMP();
Word("!$OMP ");
Walk(std::get<OmpStandaloneDirective>(x.t));
Walk(std::get<OmpClauseList>(x.t));
Put("\n");
EndOpenMP();
}
void Unparse(const OpenMPBlockConstruct &x) {
BeginOpenMP();
Word("!$OMP ");
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));
@ -2116,13 +2355,13 @@ public:
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); }
@ -2139,6 +2378,8 @@ private:
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) {
@ -2208,11 +2449,16 @@ private:
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;
@ -2228,10 +2474,18 @@ void UnparseVisitor::Put(char ch) {
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) {

View File

@ -394,7 +394,46 @@ public:
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)
@ -407,11 +446,9 @@ public:
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)
@ -436,21 +473,37 @@ public:
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)
@ -465,8 +518,7 @@ public:
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)
@ -475,28 +527,38 @@ public:
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)