1 //===-- lib/Parser/openmp-parsers.cpp -------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // Top-level grammar specification for OpenMP. 10 // See OpenMP-4.5-grammar.txt for documentation. 11 12 #include "basic-parsers.h" 13 #include "expr-parsers.h" 14 #include "misc-parsers.h" 15 #include "stmt-parser.h" 16 #include "token-parsers.h" 17 #include "type-parser-implementation.h" 18 #include "flang/Parser/parse-tree.h" 19 20 // OpenMP Directives and Clauses 21 namespace Fortran::parser { 22 23 constexpr auto startOmpLine = skipStuffBeforeStatement >> "!$OMP "_sptok; 24 constexpr auto endOmpLine = space >> endOfLine; 25 26 // OpenMP Clauses 27 // 2.15.3.1 DEFAULT (PRIVATE | FIRSTPRIVATE | SHARED | NONE) 28 TYPE_PARSER(construct<OmpDefaultClause>( 29 "PRIVATE" >> pure(OmpDefaultClause::Type::Private) || 30 "FIRSTPRIVATE" >> pure(OmpDefaultClause::Type::Firstprivate) || 31 "SHARED" >> pure(OmpDefaultClause::Type::Shared) || 32 "NONE" >> pure(OmpDefaultClause::Type::None))) 33 34 // 2.5 PROC_BIND (MASTER | CLOSE | SPREAD) 35 TYPE_PARSER(construct<OmpProcBindClause>( 36 "CLOSE" >> pure(OmpProcBindClause::Type::Close) || 37 "MASTER" >> pure(OmpProcBindClause::Type::Master) || 38 "SPREAD" >> pure(OmpProcBindClause::Type::Spread))) 39 40 // 2.15.5.1 MAP ([ [ALWAYS[,]] map-type : ] variable-name-list) 41 // map-type -> TO | FROM | TOFROM | ALLOC | RELEASE | DELETE 42 TYPE_PARSER(construct<OmpMapType>( 43 maybe("ALWAYS" >> construct<OmpMapType::Always>() / maybe(","_tok)), 44 ("TO"_id >> pure(OmpMapType::Type::To) || 45 "FROM" >> pure(OmpMapType::Type::From) || 46 "TOFROM" >> pure(OmpMapType::Type::Tofrom) || 47 "ALLOC" >> pure(OmpMapType::Type::Alloc) || 48 "RELEASE" >> pure(OmpMapType::Type::Release) || 49 "DELETE" >> pure(OmpMapType::Type::Delete)) / 50 ":")) 51 52 TYPE_PARSER(construct<OmpMapClause>( 53 maybe(Parser<OmpMapType>{}), Parser<OmpObjectList>{})) 54 55 // [OpenMP 5.0] 56 // 2.19.7.2 defaultmap(implicit-behavior[:variable-category]) 57 // implicit-behavior -> ALLOC | TO | FROM | TOFROM | FIRSRTPRIVATE | NONE | 58 // DEFAULT 59 // variable-category -> SCALAR | AGGREGATE | ALLOCATABLE | POINTER 60 TYPE_PARSER(construct<OmpDefaultmapClause>( 61 construct<OmpDefaultmapClause::ImplicitBehavior>( 62 "ALLOC" >> pure(OmpDefaultmapClause::ImplicitBehavior::Alloc) || 63 "TO"_id >> pure(OmpDefaultmapClause::ImplicitBehavior::To) || 64 "FROM" >> pure(OmpDefaultmapClause::ImplicitBehavior::From) || 65 "TOFROM" >> pure(OmpDefaultmapClause::ImplicitBehavior::Tofrom) || 66 "FIRSTPRIVATE" >> 67 pure(OmpDefaultmapClause::ImplicitBehavior::Firstprivate) || 68 "NONE" >> pure(OmpDefaultmapClause::ImplicitBehavior::None) || 69 "DEFAULT" >> pure(OmpDefaultmapClause::ImplicitBehavior::Default)), 70 maybe(":" >> 71 construct<OmpDefaultmapClause::VariableCategory>( 72 "SCALAR" >> pure(OmpDefaultmapClause::VariableCategory::Scalar) || 73 "AGGREGATE" >> 74 pure(OmpDefaultmapClause::VariableCategory::Aggregate) || 75 "ALLOCATABLE" >> 76 pure(OmpDefaultmapClause::VariableCategory::Allocatable) || 77 "POINTER" >> 78 pure(OmpDefaultmapClause::VariableCategory::Pointer))))) 79 80 // 2.7.1 SCHEDULE ([modifier1 [, modifier2]:]kind[, chunk_size]) 81 // Modifier -> MONITONIC | NONMONOTONIC | SIMD 82 // kind -> STATIC | DYNAMIC | GUIDED | AUTO | RUNTIME 83 // chunk_size -> ScalarIntExpr 84 TYPE_PARSER(construct<OmpScheduleModifierType>( 85 "MONOTONIC" >> pure(OmpScheduleModifierType::ModType::Monotonic) || 86 "NONMONOTONIC" >> pure(OmpScheduleModifierType::ModType::Nonmonotonic) || 87 "SIMD" >> pure(OmpScheduleModifierType::ModType::Simd))) 88 89 TYPE_PARSER(construct<OmpScheduleModifier>(Parser<OmpScheduleModifierType>{}, 90 maybe("," >> Parser<OmpScheduleModifierType>{}) / ":")) 91 92 TYPE_PARSER(construct<OmpScheduleClause>(maybe(Parser<OmpScheduleModifier>{}), 93 "STATIC" >> pure(OmpScheduleClause::ScheduleType::Static) || 94 "DYNAMIC" >> pure(OmpScheduleClause::ScheduleType::Dynamic) || 95 "GUIDED" >> pure(OmpScheduleClause::ScheduleType::Guided) || 96 "AUTO" >> pure(OmpScheduleClause::ScheduleType::Auto) || 97 "RUNTIME" >> pure(OmpScheduleClause::ScheduleType::Runtime), 98 maybe("," >> scalarIntExpr))) 99 100 // 2.12 IF (directive-name-modifier: scalar-logical-expr) 101 TYPE_PARSER(construct<OmpIfClause>( 102 maybe( 103 ("PARALLEL" >> pure(OmpIfClause::DirectiveNameModifier::Parallel) || 104 "TARGET ENTER DATA" >> 105 pure(OmpIfClause::DirectiveNameModifier::TargetEnterData) || 106 "TARGET EXIT DATA" >> 107 pure(OmpIfClause::DirectiveNameModifier::TargetExitData) || 108 "TARGET DATA" >> 109 pure(OmpIfClause::DirectiveNameModifier::TargetData) || 110 "TARGET UPDATE" >> 111 pure(OmpIfClause::DirectiveNameModifier::TargetUpdate) || 112 "TARGET" >> pure(OmpIfClause::DirectiveNameModifier::Target) || 113 "TASK"_id >> pure(OmpIfClause::DirectiveNameModifier::Task) || 114 "TASKLOOP" >> pure(OmpIfClause::DirectiveNameModifier::Taskloop)) / 115 ":"), 116 scalarLogicalExpr)) 117 118 // 2.15.3.6 REDUCTION (reduction-identifier: variable-name-list) 119 TYPE_PARSER(construct<OmpReductionOperator>(Parser<DefinedOperator>{}) || 120 construct<OmpReductionOperator>(Parser<ProcedureDesignator>{})) 121 122 TYPE_PARSER(construct<OmpReductionClause>( 123 Parser<OmpReductionOperator>{} / ":", Parser<OmpObjectList>{})) 124 125 // OMP 5.0 2.19.5.6 IN_REDUCTION (reduction-identifier: variable-name-list) 126 TYPE_PARSER(construct<OmpInReductionClause>( 127 Parser<OmpReductionOperator>{} / ":", Parser<OmpObjectList>{})) 128 129 // OMP 5.0 2.11.4 ALLOCATE ([allocator:] variable-name-list) 130 TYPE_PARSER(construct<OmpAllocateClause>( 131 maybe(construct<OmpAllocateClause::Allocator>(scalarIntExpr) / ":"), 132 Parser<OmpObjectList>{})) 133 134 // 2.13.9 DEPEND (SOURCE | SINK : vec | (IN | OUT | INOUT) : list 135 TYPE_PARSER(construct<OmpDependSinkVecLength>( 136 Parser<DefinedOperator>{}, scalarIntConstantExpr)) 137 138 TYPE_PARSER( 139 construct<OmpDependSinkVec>(name, maybe(Parser<OmpDependSinkVecLength>{}))) 140 141 TYPE_PARSER( 142 construct<OmpDependenceType>("IN"_id >> pure(OmpDependenceType::Type::In) || 143 "INOUT" >> pure(OmpDependenceType::Type::Inout) || 144 "OUT" >> pure(OmpDependenceType::Type::Out))) 145 146 TYPE_CONTEXT_PARSER("Omp Depend clause"_en_US, 147 construct<OmpDependClause>(construct<OmpDependClause::Sink>( 148 "SINK :" >> nonemptyList(Parser<OmpDependSinkVec>{}))) || 149 construct<OmpDependClause>( 150 construct<OmpDependClause::Source>("SOURCE"_tok)) || 151 construct<OmpDependClause>(construct<OmpDependClause::InOut>( 152 Parser<OmpDependenceType>{}, ":" >> nonemptyList(designator)))) 153 154 // 2.15.3.7 LINEAR (linear-list: linear-step) 155 // linear-list -> list | modifier(list) 156 // linear-modifier -> REF | VAL | UVAL 157 TYPE_PARSER( 158 construct<OmpLinearModifier>("REF" >> pure(OmpLinearModifier::Type::Ref) || 159 "VAL" >> pure(OmpLinearModifier::Type::Val) || 160 "UVAL" >> pure(OmpLinearModifier::Type::Uval))) 161 162 TYPE_CONTEXT_PARSER("Omp LINEAR clause"_en_US, 163 construct<OmpLinearClause>( 164 construct<OmpLinearClause>(construct<OmpLinearClause::WithModifier>( 165 Parser<OmpLinearModifier>{}, parenthesized(nonemptyList(name)), 166 maybe(":" >> scalarIntConstantExpr))) || 167 construct<OmpLinearClause>(construct<OmpLinearClause::WithoutModifier>( 168 nonemptyList(name), maybe(":" >> scalarIntConstantExpr))))) 169 170 // 2.8.1 ALIGNED (list: alignment) 171 TYPE_PARSER(construct<OmpAlignedClause>( 172 nonemptyList(name), maybe(":" >> scalarIntConstantExpr))) 173 174 TYPE_PARSER( 175 construct<OmpObject>(designator) || construct<OmpObject>("/" >> name / "/")) 176 177 TYPE_PARSER( 178 "ACQUIRE" >> construct<OmpClause>(construct<OmpClause::Acquire>()) || 179 "ACQ_REL" >> construct<OmpClause>(construct<OmpClause::AcqRel>()) || 180 "ALIGNED" >> construct<OmpClause>(construct<OmpClause::Aligned>( 181 parenthesized(Parser<OmpAlignedClause>{}))) || 182 "ALLOCATE" >> construct<OmpClause>(construct<OmpClause::Allocate>( 183 parenthesized(Parser<OmpAllocateClause>{}))) || 184 "ALLOCATOR" >> construct<OmpClause>(construct<OmpClause::Allocator>( 185 parenthesized(scalarIntExpr))) || 186 "COLLAPSE" >> construct<OmpClause>(construct<OmpClause::Collapse>( 187 parenthesized(scalarIntConstantExpr))) || 188 "COPYIN" >> construct<OmpClause>(construct<OmpClause::Copyin>( 189 parenthesized(Parser<OmpObjectList>{}))) || 190 "COPYPRIVATE" >> construct<OmpClause>(construct<OmpClause::Copyprivate>( 191 (parenthesized(Parser<OmpObjectList>{})))) || 192 "DEFAULT"_id >> construct<OmpClause>(construct<OmpClause::Default>( 193 parenthesized(Parser<OmpDefaultClause>{}))) || 194 "DEFAULTMAP" >> construct<OmpClause>(construct<OmpClause::Defaultmap>( 195 parenthesized(Parser<OmpDefaultmapClause>{}))) || 196 "DEPEND" >> construct<OmpClause>(construct<OmpClause::Depend>( 197 parenthesized(Parser<OmpDependClause>{}))) || 198 "DEVICE" >> construct<OmpClause>(construct<OmpClause::Device>( 199 parenthesized(scalarIntExpr))) || 200 "DIST_SCHEDULE" >> 201 construct<OmpClause>(construct<OmpClause::DistSchedule>( 202 parenthesized("STATIC" >> maybe("," >> scalarIntExpr)))) || 203 "FINAL" >> construct<OmpClause>(construct<OmpClause::Final>( 204 parenthesized(scalarLogicalExpr))) || 205 "FIRSTPRIVATE" >> construct<OmpClause>(construct<OmpClause::Firstprivate>( 206 parenthesized(Parser<OmpObjectList>{}))) || 207 "FROM" >> construct<OmpClause>(construct<OmpClause::From>( 208 parenthesized(Parser<OmpObjectList>{}))) || 209 "GRAINSIZE" >> construct<OmpClause>(construct<OmpClause::Grainsize>( 210 parenthesized(scalarIntExpr))) || 211 "HINT" >> construct<OmpClause>( 212 construct<OmpClause::Hint>(parenthesized(constantExpr))) || 213 "IF" >> construct<OmpClause>(construct<OmpClause::If>( 214 parenthesized(Parser<OmpIfClause>{}))) || 215 "INBRANCH" >> construct<OmpClause>(construct<OmpClause::Inbranch>()) || 216 "IS_DEVICE_PTR" >> construct<OmpClause>(construct<OmpClause::IsDevicePtr>( 217 parenthesized(nonemptyList(name)))) || 218 "LASTPRIVATE" >> construct<OmpClause>(construct<OmpClause::Lastprivate>( 219 parenthesized(Parser<OmpObjectList>{}))) || 220 "LINEAR" >> construct<OmpClause>(construct<OmpClause::Linear>( 221 parenthesized(Parser<OmpLinearClause>{}))) || 222 "LINK" >> construct<OmpClause>(construct<OmpClause::Link>( 223 parenthesized(Parser<OmpObjectList>{}))) || 224 "MAP" >> construct<OmpClause>(construct<OmpClause::Map>( 225 parenthesized(Parser<OmpMapClause>{}))) || 226 "MERGEABLE" >> construct<OmpClause>(construct<OmpClause::Mergeable>()) || 227 "NOGROUP" >> construct<OmpClause>(construct<OmpClause::Nogroup>()) || 228 "NONTEMPORAL" >> construct<OmpClause>(construct<OmpClause::Nontemporal>( 229 parenthesized(nonemptyList(name)))) || 230 "NOTINBRANCH" >> 231 construct<OmpClause>(construct<OmpClause::Notinbranch>()) || 232 "NOWAIT" >> construct<OmpClause>(construct<OmpClause::Nowait>()) || 233 "NUM_TASKS" >> construct<OmpClause>(construct<OmpClause::NumTasks>( 234 parenthesized(scalarIntExpr))) || 235 "NUM_TEAMS" >> construct<OmpClause>(construct<OmpClause::NumTeams>( 236 parenthesized(scalarIntExpr))) || 237 "NUM_THREADS" >> construct<OmpClause>(construct<OmpClause::NumThreads>( 238 parenthesized(scalarIntExpr))) || 239 "ORDERED" >> construct<OmpClause>(construct<OmpClause::Ordered>( 240 maybe(parenthesized(scalarIntConstantExpr)))) || 241 "PRIORITY" >> construct<OmpClause>(construct<OmpClause::Priority>( 242 parenthesized(scalarIntExpr))) || 243 "PRIVATE" >> construct<OmpClause>(construct<OmpClause::Private>( 244 parenthesized(Parser<OmpObjectList>{}))) || 245 "PROC_BIND" >> construct<OmpClause>(construct<OmpClause::ProcBind>( 246 parenthesized(Parser<OmpProcBindClause>{}))) || 247 "REDUCTION" >> construct<OmpClause>(construct<OmpClause::Reduction>( 248 parenthesized(Parser<OmpReductionClause>{}))) || 249 "IN_REDUCTION" >> construct<OmpClause>(construct<OmpClause::InReduction>( 250 parenthesized(Parser<OmpInReductionClause>{}))) || 251 "TASK_REDUCTION" >> 252 construct<OmpClause>(construct<OmpClause::TaskReduction>( 253 parenthesized(Parser<OmpReductionClause>{}))) || 254 "RELAXED" >> construct<OmpClause>(construct<OmpClause::Relaxed>()) || 255 "RELEASE" >> construct<OmpClause>(construct<OmpClause::Release>()) || 256 "SAFELEN" >> construct<OmpClause>(construct<OmpClause::Safelen>( 257 parenthesized(scalarIntConstantExpr))) || 258 "SCHEDULE" >> construct<OmpClause>(construct<OmpClause::Schedule>( 259 parenthesized(Parser<OmpScheduleClause>{}))) || 260 "SEQ_CST" >> construct<OmpClause>(construct<OmpClause::SeqCst>()) || 261 "SHARED" >> construct<OmpClause>(construct<OmpClause::Shared>( 262 parenthesized(Parser<OmpObjectList>{}))) || 263 "SIMD"_id >> construct<OmpClause>(construct<OmpClause::Simd>()) || 264 "SIMDLEN" >> construct<OmpClause>(construct<OmpClause::Simdlen>( 265 parenthesized(scalarIntConstantExpr))) || 266 "THREADS" >> construct<OmpClause>(construct<OmpClause::Threads>()) || 267 "THREAD_LIMIT" >> construct<OmpClause>(construct<OmpClause::ThreadLimit>( 268 parenthesized(scalarIntExpr))) || 269 "TO" >> construct<OmpClause>(construct<OmpClause::To>( 270 parenthesized(Parser<OmpObjectList>{}))) || 271 "USE_DEVICE_PTR" >> construct<OmpClause>(construct<OmpClause::UseDevicePtr>( 272 parenthesized(nonemptyList(name)))) || 273 "UNIFORM" >> construct<OmpClause>(construct<OmpClause::Uniform>( 274 parenthesized(nonemptyList(name)))) || 275 "UNTIED" >> construct<OmpClause>(construct<OmpClause::Untied>())) 276 277 // [Clause, [Clause], ...] 278 TYPE_PARSER(sourced(construct<OmpClauseList>( 279 many(maybe(","_tok) >> sourced(Parser<OmpClause>{}))))) 280 281 // 2.1 (variable | /common-block | array-sections) 282 TYPE_PARSER(construct<OmpObjectList>(nonemptyList(Parser<OmpObject>{}))) 283 284 // Omp directives enclosing do loop 285 TYPE_PARSER(sourced(construct<OmpLoopDirective>(first( 286 "DISTRIBUTE PARALLEL DO SIMD" >> 287 pure(llvm::omp::Directive::OMPD_distribute_parallel_do_simd), 288 "DISTRIBUTE PARALLEL DO" >> 289 pure(llvm::omp::Directive::OMPD_distribute_parallel_do), 290 "DISTRIBUTE SIMD" >> pure(llvm::omp::Directive::OMPD_distribute_simd), 291 "DISTRIBUTE" >> pure(llvm::omp::Directive::OMPD_distribute), 292 "DO SIMD" >> pure(llvm::omp::Directive::OMPD_do_simd), 293 "DO" >> pure(llvm::omp::Directive::OMPD_do), 294 "PARALLEL DO SIMD" >> pure(llvm::omp::Directive::OMPD_parallel_do_simd), 295 "PARALLEL DO" >> pure(llvm::omp::Directive::OMPD_parallel_do), 296 "SIMD" >> pure(llvm::omp::Directive::OMPD_simd), 297 "TARGET PARALLEL DO SIMD" >> 298 pure(llvm::omp::Directive::OMPD_target_parallel_do_simd), 299 "TARGET PARALLEL DO" >> pure(llvm::omp::Directive::OMPD_target_parallel_do), 300 "TARGET SIMD" >> pure(llvm::omp::Directive::OMPD_target_simd), 301 "TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD" >> 302 pure(llvm::omp::Directive:: 303 OMPD_target_teams_distribute_parallel_do_simd), 304 "TARGET TEAMS DISTRIBUTE PARALLEL DO" >> 305 pure(llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do), 306 "TARGET TEAMS DISTRIBUTE SIMD" >> 307 pure(llvm::omp::Directive::OMPD_target_teams_distribute_simd), 308 "TARGET TEAMS DISTRIBUTE" >> 309 pure(llvm::omp::Directive::OMPD_target_teams_distribute), 310 "TASKLOOP SIMD" >> pure(llvm::omp::Directive::OMPD_taskloop_simd), 311 "TASKLOOP" >> pure(llvm::omp::Directive::OMPD_taskloop), 312 "TEAMS DISTRIBUTE PARALLEL DO SIMD" >> 313 pure(llvm::omp::Directive::OMPD_teams_distribute_parallel_do_simd), 314 "TEAMS DISTRIBUTE PARALLEL DO" >> 315 pure(llvm::omp::Directive::OMPD_teams_distribute_parallel_do), 316 "TEAMS DISTRIBUTE SIMD" >> 317 pure(llvm::omp::Directive::OMPD_teams_distribute_simd), 318 "TEAMS DISTRIBUTE" >> pure(llvm::omp::Directive::OMPD_teams_distribute))))) 319 320 TYPE_PARSER(sourced(construct<OmpBeginLoopDirective>( 321 sourced(Parser<OmpLoopDirective>{}), Parser<OmpClauseList>{}))) 322 323 // 2.14.1 construct-type-clause -> PARALLEL | SECTIONS | DO | TASKGROUP 324 TYPE_PARSER(sourced(construct<OmpCancelType>( 325 first("PARALLEL" >> pure(OmpCancelType::Type::Parallel), 326 "SECTIONS" >> pure(OmpCancelType::Type::Sections), 327 "DO" >> pure(OmpCancelType::Type::Do), 328 "TASKGROUP" >> pure(OmpCancelType::Type::Taskgroup))))) 329 330 // 2.14.2 Cancellation Point construct 331 TYPE_PARSER(sourced(construct<OpenMPCancellationPointConstruct>( 332 verbatim("CANCELLATION POINT"_tok), Parser<OmpCancelType>{}))) 333 334 // 2.14.1 Cancel construct 335 TYPE_PARSER(sourced(construct<OpenMPCancelConstruct>(verbatim("CANCEL"_tok), 336 Parser<OmpCancelType>{}, maybe("IF" >> parenthesized(scalarLogicalExpr))))) 337 338 // 2.17.7 Atomic construct/2.17.8 Flush construct [OpenMP 5.0] 339 // memory-order-clause -> 340 // seq_cst 341 // acq_rel 342 // release 343 // acquire 344 // relaxed 345 TYPE_PARSER(sourced(construct<OmpMemoryOrderClause>( 346 sourced("SEQ_CST" >> construct<OmpClause>(construct<OmpClause::SeqCst>()) || 347 "ACQ_REL" >> construct<OmpClause>(construct<OmpClause::AcqRel>()) || 348 "RELEASE" >> construct<OmpClause>(construct<OmpClause::Release>()) || 349 "ACQUIRE" >> construct<OmpClause>(construct<OmpClause::Acquire>()) || 350 "RELAXED" >> construct<OmpClause>(construct<OmpClause::Relaxed>()))))) 351 352 // 2.17.7 Atomic construct 353 // atomic-clause -> memory-order-clause | HINT(hint-expression) 354 TYPE_PARSER(sourced(construct<OmpAtomicClause>( 355 construct<OmpAtomicClause>(Parser<OmpMemoryOrderClause>{}) || 356 construct<OmpAtomicClause>("HINT" >> 357 sourced(construct<OmpClause>( 358 construct<OmpClause::Hint>(parenthesized(constantExpr)))))))) 359 360 // atomic-clause-list -> [atomic-clause, [atomic-clause], ...] 361 TYPE_PARSER(sourced(construct<OmpAtomicClauseList>( 362 many(maybe(","_tok) >> sourced(Parser<OmpAtomicClause>{}))))) 363 364 TYPE_PARSER(sourced(construct<OpenMPFlushConstruct>(verbatim("FLUSH"_tok), 365 many(maybe(","_tok) >> sourced(Parser<OmpMemoryOrderClause>{})), 366 maybe(parenthesized(Parser<OmpObjectList>{}))))) 367 368 // Simple Standalone Directives 369 TYPE_PARSER(sourced(construct<OmpSimpleStandaloneDirective>(first( 370 "BARRIER" >> pure(llvm::omp::Directive::OMPD_barrier), 371 "ORDERED" >> pure(llvm::omp::Directive::OMPD_ordered), 372 "TARGET ENTER DATA" >> pure(llvm::omp::Directive::OMPD_target_enter_data), 373 "TARGET EXIT DATA" >> pure(llvm::omp::Directive::OMPD_target_exit_data), 374 "TARGET UPDATE" >> pure(llvm::omp::Directive::OMPD_target_update), 375 "TASKWAIT" >> pure(llvm::omp::Directive::OMPD_taskwait), 376 "TASKYIELD" >> pure(llvm::omp::Directive::OMPD_taskyield))))) 377 378 TYPE_PARSER(sourced(construct<OpenMPSimpleStandaloneConstruct>( 379 Parser<OmpSimpleStandaloneDirective>{}, Parser<OmpClauseList>{}))) 380 381 // Standalone Constructs 382 TYPE_PARSER( 383 sourced(construct<OpenMPStandaloneConstruct>( 384 Parser<OpenMPSimpleStandaloneConstruct>{}) || 385 construct<OpenMPStandaloneConstruct>(Parser<OpenMPFlushConstruct>{}) || 386 construct<OpenMPStandaloneConstruct>(Parser<OpenMPCancelConstruct>{}) || 387 construct<OpenMPStandaloneConstruct>( 388 Parser<OpenMPCancellationPointConstruct>{})) / 389 endOfLine) 390 391 // Directives enclosing structured-block 392 TYPE_PARSER(construct<OmpBlockDirective>(first( 393 "MASTER" >> pure(llvm::omp::Directive::OMPD_master), 394 "ORDERED" >> pure(llvm::omp::Directive::OMPD_ordered), 395 "PARALLEL WORKSHARE" >> pure(llvm::omp::Directive::OMPD_parallel_workshare), 396 "PARALLEL" >> pure(llvm::omp::Directive::OMPD_parallel), 397 "SINGLE" >> pure(llvm::omp::Directive::OMPD_single), 398 "TARGET DATA" >> pure(llvm::omp::Directive::OMPD_target_data), 399 "TARGET PARALLEL" >> pure(llvm::omp::Directive::OMPD_target_parallel), 400 "TARGET TEAMS" >> pure(llvm::omp::Directive::OMPD_target_teams), 401 "TARGET" >> pure(llvm::omp::Directive::OMPD_target), 402 "TASK"_id >> pure(llvm::omp::Directive::OMPD_task), 403 "TASKGROUP" >> pure(llvm::omp::Directive::OMPD_taskgroup), 404 "TEAMS" >> pure(llvm::omp::Directive::OMPD_teams), 405 "WORKSHARE" >> pure(llvm::omp::Directive::OMPD_workshare)))) 406 407 TYPE_PARSER(sourced(construct<OmpBeginBlockDirective>( 408 sourced(Parser<OmpBlockDirective>{}), Parser<OmpClauseList>{}))) 409 410 TYPE_PARSER(construct<OmpReductionInitializerClause>( 411 "INITIALIZER" >> parenthesized("OMP_PRIV =" >> expr))) 412 413 // 2.16 Declare Reduction Construct 414 TYPE_PARSER(sourced(construct<OpenMPDeclareReductionConstruct>( 415 verbatim("DECLARE REDUCTION"_tok), 416 "(" >> Parser<OmpReductionOperator>{} / ":", 417 nonemptyList(Parser<DeclarationTypeSpec>{}) / ":", 418 Parser<OmpReductionCombiner>{} / ")", 419 maybe(Parser<OmpReductionInitializerClause>{})))) 420 421 // declare-target with list 422 TYPE_PARSER(sourced(construct<OmpDeclareTargetWithList>( 423 parenthesized(Parser<OmpObjectList>{})))) 424 425 // declare-target with clause 426 TYPE_PARSER( 427 sourced(construct<OmpDeclareTargetWithClause>(Parser<OmpClauseList>{}))) 428 429 // declare-target-specifier 430 TYPE_PARSER( 431 construct<OmpDeclareTargetSpecifier>(Parser<OmpDeclareTargetWithList>{}) || 432 construct<OmpDeclareTargetSpecifier>(Parser<OmpDeclareTargetWithClause>{})) 433 434 // 2.10.6 Declare Target Construct 435 TYPE_PARSER(sourced(construct<OpenMPDeclareTargetConstruct>( 436 verbatim("DECLARE TARGET"_tok), Parser<OmpDeclareTargetSpecifier>{}))) 437 438 TYPE_PARSER(construct<OmpReductionCombiner>(Parser<AssignmentStmt>{}) || 439 construct<OmpReductionCombiner>( 440 construct<OmpReductionCombiner::FunctionCombiner>( 441 construct<Call>(Parser<ProcedureDesignator>{}, 442 parenthesized(optionalList(actualArgSpec)))))) 443 444 // 2.17.7 atomic -> ATOMIC [clause [,]] atomic-clause [[,] clause] | 445 // ATOMIC [clause] 446 // clause -> memory-order-clause | HINT(hint-expression) 447 // memory-order-clause -> SEQ_CST | ACQ_REL | RELEASE | ACQUIRE | RELAXED 448 // atomic-clause -> READ | WRITE | UPDATE | CAPTURE 449 450 // OMP END ATOMIC 451 TYPE_PARSER(construct<OmpEndAtomic>(startOmpLine >> "END ATOMIC"_tok)) 452 453 // OMP ATOMIC [MEMORY-ORDER-CLAUSE-LIST] READ [MEMORY-ORDER-CLAUSE-LIST] 454 TYPE_PARSER("ATOMIC" >> 455 construct<OmpAtomicRead>(Parser<OmpAtomicClauseList>{} / maybe(","_tok), 456 verbatim("READ"_tok), Parser<OmpAtomicClauseList>{} / endOmpLine, 457 statement(assignmentStmt), maybe(Parser<OmpEndAtomic>{} / endOmpLine))) 458 459 // OMP ATOMIC [MEMORY-ORDER-CLAUSE-LIST] CAPTURE [MEMORY-ORDER-CLAUSE-LIST] 460 TYPE_PARSER("ATOMIC" >> 461 construct<OmpAtomicCapture>(Parser<OmpAtomicClauseList>{} / maybe(","_tok), 462 verbatim("CAPTURE"_tok), Parser<OmpAtomicClauseList>{} / endOmpLine, 463 statement(assignmentStmt), statement(assignmentStmt), 464 Parser<OmpEndAtomic>{} / endOmpLine)) 465 466 // OMP ATOMIC [MEMORY-ORDER-CLAUSE-LIST] UPDATE [MEMORY-ORDER-CLAUSE-LIST] 467 TYPE_PARSER("ATOMIC" >> 468 construct<OmpAtomicUpdate>(Parser<OmpAtomicClauseList>{} / maybe(","_tok), 469 verbatim("UPDATE"_tok), Parser<OmpAtomicClauseList>{} / endOmpLine, 470 statement(assignmentStmt), maybe(Parser<OmpEndAtomic>{} / endOmpLine))) 471 472 // OMP ATOMIC [atomic-clause-list] 473 TYPE_PARSER(construct<OmpAtomic>(verbatim("ATOMIC"_tok), 474 Parser<OmpAtomicClauseList>{} / endOmpLine, statement(assignmentStmt), 475 maybe(Parser<OmpEndAtomic>{} / endOmpLine))) 476 477 // OMP ATOMIC [MEMORY-ORDER-CLAUSE-LIST] WRITE [MEMORY-ORDER-CLAUSE-LIST] 478 TYPE_PARSER("ATOMIC" >> 479 construct<OmpAtomicWrite>(Parser<OmpAtomicClauseList>{} / maybe(","_tok), 480 verbatim("WRITE"_tok), Parser<OmpAtomicClauseList>{} / endOmpLine, 481 statement(assignmentStmt), maybe(Parser<OmpEndAtomic>{} / endOmpLine))) 482 483 // Atomic Construct 484 TYPE_PARSER(construct<OpenMPAtomicConstruct>(Parser<OmpAtomicRead>{}) || 485 construct<OpenMPAtomicConstruct>(Parser<OmpAtomicCapture>{}) || 486 construct<OpenMPAtomicConstruct>(Parser<OmpAtomicWrite>{}) || 487 construct<OpenMPAtomicConstruct>(Parser<OmpAtomicUpdate>{}) || 488 construct<OpenMPAtomicConstruct>(Parser<OmpAtomic>{})) 489 490 // 2.13.2 OMP CRITICAL 491 TYPE_PARSER(startOmpLine >> 492 sourced(construct<OmpEndCriticalDirective>( 493 verbatim("END CRITICAL"_tok), maybe(parenthesized(name)))) / 494 endOmpLine) 495 TYPE_PARSER(sourced(construct<OmpCriticalDirective>(verbatim("CRITICAL"_tok), 496 maybe(parenthesized(name)), Parser<OmpClauseList>{})) / 497 endOmpLine) 498 499 TYPE_PARSER(construct<OpenMPCriticalConstruct>( 500 Parser<OmpCriticalDirective>{}, block, Parser<OmpEndCriticalDirective>{})) 501 502 // 2.11.3 Executable Allocate directive 503 TYPE_PARSER( 504 sourced(construct<OpenMPExecutableAllocate>(verbatim("ALLOCATE"_tok), 505 maybe(parenthesized(Parser<OmpObjectList>{})), Parser<OmpClauseList>{}, 506 maybe(nonemptyList(Parser<OpenMPDeclarativeAllocate>{})) / endOmpLine, 507 statement(allocateStmt)))) 508 509 // 2.8.2 Declare Simd construct 510 TYPE_PARSER( 511 sourced(construct<OpenMPDeclareSimdConstruct>(verbatim("DECLARE SIMD"_tok), 512 maybe(parenthesized(name)), Parser<OmpClauseList>{}))) 513 514 // 2.15.2 Threadprivate directive 515 TYPE_PARSER(sourced(construct<OpenMPThreadprivate>( 516 verbatim("THREADPRIVATE"_tok), parenthesized(Parser<OmpObjectList>{})))) 517 518 // 2.11.3 Declarative Allocate directive 519 TYPE_PARSER( 520 sourced(construct<OpenMPDeclarativeAllocate>(verbatim("ALLOCATE"_tok), 521 parenthesized(Parser<OmpObjectList>{}), Parser<OmpClauseList>{})) / 522 lookAhead(endOmpLine / !statement(allocateStmt))) 523 524 // Declarative constructs 525 TYPE_PARSER(startOmpLine >> 526 sourced(construct<OpenMPDeclarativeConstruct>( 527 Parser<OpenMPDeclareReductionConstruct>{}) || 528 construct<OpenMPDeclarativeConstruct>( 529 Parser<OpenMPDeclareSimdConstruct>{}) || 530 construct<OpenMPDeclarativeConstruct>( 531 Parser<OpenMPDeclareTargetConstruct>{}) || 532 construct<OpenMPDeclarativeConstruct>( 533 Parser<OpenMPDeclarativeAllocate>{}) || 534 construct<OpenMPDeclarativeConstruct>(Parser<OpenMPThreadprivate>{})) / 535 endOmpLine) 536 537 // Block Construct 538 TYPE_PARSER(construct<OpenMPBlockConstruct>( 539 Parser<OmpBeginBlockDirective>{} / endOmpLine, block, 540 Parser<OmpEndBlockDirective>{} / endOmpLine)) 541 542 // OMP SECTIONS Directive 543 TYPE_PARSER(construct<OmpSectionsDirective>(first( 544 "SECTIONS" >> pure(llvm::omp::Directive::OMPD_sections), 545 "PARALLEL SECTIONS" >> pure(llvm::omp::Directive::OMPD_parallel_sections)))) 546 547 // OMP BEGIN and END SECTIONS Directive 548 TYPE_PARSER(sourced(construct<OmpBeginSectionsDirective>( 549 sourced(Parser<OmpSectionsDirective>{}), Parser<OmpClauseList>{}))) 550 TYPE_PARSER( 551 startOmpLine >> sourced(construct<OmpEndSectionsDirective>( 552 sourced("END"_tok >> Parser<OmpSectionsDirective>{}), 553 Parser<OmpClauseList>{}))) 554 555 // OMP SECTION-BLOCK 556 557 TYPE_PARSER(construct<OpenMPSectionConstruct>(block)) 558 559 TYPE_PARSER(maybe(startOmpLine >> "SECTION"_tok / endOmpLine) >> 560 construct<OmpSectionBlocks>(nonemptySeparated( 561 construct<OpenMPConstruct>(sourced(Parser<OpenMPSectionConstruct>{})), 562 startOmpLine >> "SECTION"_tok / endOmpLine))) 563 564 // OMP SECTIONS (OpenMP 5.0 - 2.8.1), PARALLEL SECTIONS (OpenMP 5.0 - 2.13.3) 565 TYPE_PARSER(construct<OpenMPSectionsConstruct>( 566 Parser<OmpBeginSectionsDirective>{} / endOmpLine, 567 Parser<OmpSectionBlocks>{}, Parser<OmpEndSectionsDirective>{} / endOmpLine)) 568 569 TYPE_CONTEXT_PARSER("OpenMP construct"_en_US, 570 startOmpLine >> 571 first(construct<OpenMPConstruct>(Parser<OpenMPSectionsConstruct>{}), 572 construct<OpenMPConstruct>(Parser<OpenMPLoopConstruct>{}), 573 construct<OpenMPConstruct>(Parser<OpenMPBlockConstruct>{}), 574 // OpenMPBlockConstruct is attempted before 575 // OpenMPStandaloneConstruct to resolve !$OMP ORDERED 576 construct<OpenMPConstruct>(Parser<OpenMPStandaloneConstruct>{}), 577 construct<OpenMPConstruct>(Parser<OpenMPAtomicConstruct>{}), 578 construct<OpenMPConstruct>(Parser<OpenMPExecutableAllocate>{}), 579 construct<OpenMPConstruct>(Parser<OpenMPDeclarativeAllocate>{}), 580 construct<OpenMPConstruct>(Parser<OpenMPCriticalConstruct>{}))) 581 582 // END OMP Block directives 583 TYPE_PARSER( 584 startOmpLine >> sourced(construct<OmpEndBlockDirective>( 585 sourced("END"_tok >> Parser<OmpBlockDirective>{}), 586 Parser<OmpClauseList>{}))) 587 588 // END OMP Loop directives 589 TYPE_PARSER( 590 startOmpLine >> sourced(construct<OmpEndLoopDirective>( 591 sourced("END"_tok >> Parser<OmpLoopDirective>{}), 592 Parser<OmpClauseList>{}))) 593 594 TYPE_PARSER(construct<OpenMPLoopConstruct>( 595 Parser<OmpBeginLoopDirective>{} / endOmpLine)) 596 } // namespace Fortran::parser 597