forked from OSchip/llvm-project
[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:
parent
698581c784
commit
08b2684271
|
@ -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)))};
|
||||
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue