diff options
Diffstat (limited to 'flang/lib/Parser/openmp-parsers.cpp')
-rw-r--r-- | flang/lib/Parser/openmp-parsers.cpp | 124 |
1 files changed, 101 insertions, 23 deletions
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 76c9499..25a692d 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -274,6 +274,10 @@ TYPE_PARSER( // construct<OmpTypeSpecifier>(Parser<DeclarationTypeSpec>{}) || construct<OmpTypeSpecifier>(Parser<TypeSpec>{})) +// 2.15.3.6 REDUCTION (reduction-identifier: variable-name-list) +TYPE_PARSER(construct<OmpReductionIdentifier>(Parser<DefinedOperator>{}) || + construct<OmpReductionIdentifier>(Parser<ProcedureDesignator>{})) + TYPE_PARSER(construct<OmpReductionSpecifier>( // Parser<OmpReductionIdentifier>{}, ":"_tok >> nonemptyList(Parser<OmpTypeSpecifier>{}), @@ -442,9 +446,18 @@ TYPE_PARSER(construct<OmpAllocatorComplexModifier>( TYPE_PARSER(construct<OmpAllocatorSimpleModifier>(scalarIntExpr)) +TYPE_PARSER(construct<OmpAlwaysModifier>( // + "ALWAYS" >> pure(OmpAlwaysModifier::Value::Always))) + TYPE_PARSER(construct<OmpChunkModifier>( // "SIMD" >> pure(OmpChunkModifier::Value::Simd))) +TYPE_PARSER(construct<OmpCloseModifier>( // + "CLOSE" >> pure(OmpCloseModifier::Value::Close))) + +TYPE_PARSER(construct<OmpDeleteModifier>( // + "DELETE" >> pure(OmpDeleteModifier::Value::Delete))) + TYPE_PARSER(construct<OmpDependenceType>( "SINK" >> pure(OmpDependenceType::Value::Sink) || "SOURCE" >> pure(OmpDependenceType::Value::Source))) @@ -502,26 +515,16 @@ TYPE_PARSER(construct<OmpLinearModifier>( // TYPE_PARSER(construct<OmpMapper>( // "MAPPER"_tok >> parenthesized(Parser<ObjectName>{}))) -// map-type -> ALLOC | DELETE | FROM | RELEASE | TO | TOFROM +// map-type -> ALLOC | DELETE | FROM | RELEASE | STORAGE | TO | TOFROM TYPE_PARSER(construct<OmpMapType>( // "ALLOC" >> pure(OmpMapType::Value::Alloc) || - "DELETE" >> pure(OmpMapType::Value::Delete) || + // Parse "DELETE" as OmpDeleteModifier "FROM" >> pure(OmpMapType::Value::From) || "RELEASE" >> pure(OmpMapType::Value::Release) || + "STORAGE" >> pure(OmpMapType::Value::Storage) || "TO"_id >> pure(OmpMapType::Value::To) || "TOFROM" >> pure(OmpMapType::Value::Tofrom))) -// map-type-modifier -> ALWAYS | CLOSE | OMPX_HOLD | PRESENT -TYPE_PARSER(construct<OmpMapTypeModifier>( - "ALWAYS" >> pure(OmpMapTypeModifier::Value::Always) || - "CLOSE" >> pure(OmpMapTypeModifier::Value::Close) || - "OMPX_HOLD" >> pure(OmpMapTypeModifier::Value::Ompx_Hold) || - "PRESENT" >> pure(OmpMapTypeModifier::Value::Present))) - -// 2.15.3.6 REDUCTION (reduction-identifier: variable-name-list) -TYPE_PARSER(construct<OmpReductionIdentifier>(Parser<DefinedOperator>{}) || - construct<OmpReductionIdentifier>(Parser<ProcedureDesignator>{})) - TYPE_PARSER(construct<OmpOrderModifier>( "REPRODUCIBLE" >> pure(OmpOrderModifier::Value::Reproducible) || "UNCONSTRAINED" >> pure(OmpOrderModifier::Value::Unconstrained))) @@ -534,11 +537,22 @@ TYPE_PARSER(construct<OmpOrderingModifier>( TYPE_PARSER(construct<OmpPrescriptiveness>( "STRICT" >> pure(OmpPrescriptiveness::Value::Strict))) +TYPE_PARSER(construct<OmpPresentModifier>( // + "PRESENT" >> pure(OmpPresentModifier::Value::Present))) + TYPE_PARSER(construct<OmpReductionModifier>( "INSCAN" >> pure(OmpReductionModifier::Value::Inscan) || "TASK" >> pure(OmpReductionModifier::Value::Task) || "DEFAULT" >> pure(OmpReductionModifier::Value::Default))) +TYPE_PARSER(construct<OmpRefModifier>( // + "REF_PTEE" >> pure(OmpRefModifier::Value::Ref_Ptee) || + "REF_PTR"_id >> pure(OmpRefModifier::Value::Ref_Ptr) || + "REF_PTR_PTEE" >> pure(OmpRefModifier::Value::Ref_Ptr_Ptee))) + +TYPE_PARSER(construct<OmpSelfModifier>( // + "SELF" >> pure(OmpSelfModifier::Value::Self))) + TYPE_PARSER(construct<OmpStepComplexModifier>( // "STEP" >> parenthesized(scalarIntExpr))) @@ -559,6 +573,9 @@ TYPE_PARSER(construct<OmpVariableCategory>( "POINTER" >> pure(OmpVariableCategory::Value::Pointer) || "SCALAR" >> pure(OmpVariableCategory::Value::Scalar))) +TYPE_PARSER(construct<OmpxHoldModifier>( // + "OMPX_HOLD" >> pure(OmpxHoldModifier::Value::Ompx_Hold))) + // This could be auto-generated. TYPE_PARSER( sourced(construct<OmpAffinityClause::Modifier>(Parser<OmpIterator>{}))) @@ -611,10 +628,16 @@ TYPE_PARSER(sourced( construct<OmpLinearClause::Modifier>(Parser<OmpStepSimpleModifier>{}))) TYPE_PARSER(sourced(construct<OmpMapClause::Modifier>( - sourced(construct<OmpMapClause::Modifier>(Parser<OmpMapTypeModifier>{}) || + sourced(construct<OmpMapClause::Modifier>(Parser<OmpAlwaysModifier>{}) || + construct<OmpMapClause::Modifier>(Parser<OmpCloseModifier>{}) || + construct<OmpMapClause::Modifier>(Parser<OmpDeleteModifier>{}) || + construct<OmpMapClause::Modifier>(Parser<OmpPresentModifier>{}) || + construct<OmpMapClause::Modifier>(Parser<OmpRefModifier>{}) || + construct<OmpMapClause::Modifier>(Parser<OmpSelfModifier>{}) || construct<OmpMapClause::Modifier>(Parser<OmpMapper>{}) || construct<OmpMapClause::Modifier>(Parser<OmpIterator>{}) || - construct<OmpMapClause::Modifier>(Parser<OmpMapType>{}))))) + construct<OmpMapClause::Modifier>(Parser<OmpMapType>{}) || + construct<OmpMapClause::Modifier>(Parser<OmpxHoldModifier>{}))))) TYPE_PARSER( sourced(construct<OmpOrderClause::Modifier>(Parser<OmpOrderModifier>{}))) @@ -1185,6 +1208,54 @@ TYPE_PARSER(sourced( maybe(Parser<OmpClauseList>{}), pure(OmpDirectiveSpecification::Flags::None)))) +static bool IsFortranBlockConstruct(const ExecutionPartConstruct &epc) { + // ExecutionPartConstruct -> ExecutableConstruct + // -> Indirection<BlockConstruct> + if (auto *ec{std::get_if<ExecutableConstruct>(&epc.u)}) { + return std::holds_alternative<common::Indirection<BlockConstruct>>(ec->u); + } else { + return false; + } +} + +struct StrictlyStructuredBlockParser { + using resultType = Block; + + std::optional<resultType> Parse(ParseState &state) const { + if (auto epc{Parser<ExecutionPartConstruct>{}.Parse(state)}) { + if (IsFortranBlockConstruct(*epc)) { + Block block; + block.emplace_back(std::move(*epc)); + return std::move(block); + } + } + return std::nullopt; + } +}; + +struct LooselyStructuredBlockParser { + using resultType = Block; + + std::optional<resultType> Parse(ParseState &state) const { + Block body; + if (auto epc{attempt(Parser<ExecutionPartConstruct>{}).Parse(state)}) { + if (!IsFortranBlockConstruct(*epc)) { + body.emplace_back(std::move(*epc)); + if (auto &&blk{attempt(block).Parse(state)}) { + for (auto &&s : *blk) { + body.emplace_back(std::move(s)); + } + } + } else { + // Fail if the first construct is BLOCK. + return std::nullopt; + } + } + // Empty body is ok. + return std::move(body); + } +}; + TYPE_PARSER(sourced(construct<OmpNothingDirective>("NOTHING" >> ok))) TYPE_PARSER(sourced(construct<OpenMPUtilityConstruct>( @@ -1547,12 +1618,16 @@ TYPE_PARSER( Parser<OpenMPInteropConstruct>{})) / endOfLine) +// Directive names (of non-block constructs) whose prefix is a name of +// a block-associated construct. We need to exclude them from the block +// directive parser below to avoid parsing parts of them. +static constexpr auto StandaloneDirectiveLookahead{// + "TARGET ENTER DATA"_sptok || "TARGET_ENTER_DATA"_sptok || // + "TARGET EXIT DATA"_sptok || "TARGET_EXIT"_sptok || // + "TARGET UPDATE"_sptok || "TARGET_UPDATE"_sptok}; + // Directives enclosing structured-block -TYPE_PARSER( - // In this context "TARGET UPDATE" can be parsed as a TARGET directive - // followed by an UPDATE clause. This is the only combination at the - // moment, exclude it explicitly. - (!("TARGET UPDATE"_sptok || "TARGET_UPDATE"_sptok)) >= +TYPE_PARSER((!StandaloneDirectiveLookahead) >= construct<OmpBlockDirective>(first( "MASKED" >> pure(llvm::omp::Directive::OMPD_masked), "MASTER" >> pure(llvm::omp::Directive::OMPD_master), @@ -1726,9 +1801,12 @@ TYPE_PARSER(sourced( block, maybe(Parser<OmpEndAssumeDirective>{} / endOmpLine)))) // Block Construct -TYPE_PARSER(construct<OpenMPBlockConstruct>( - Parser<OmpBeginBlockDirective>{} / endOmpLine, block, - Parser<OmpEndBlockDirective>{} / endOmpLine)) +TYPE_PARSER( // + construct<OpenMPBlockConstruct>(Parser<OmpBeginBlockDirective>{}, + StrictlyStructuredBlockParser{}, + maybe(Parser<OmpEndBlockDirective>{})) || + construct<OpenMPBlockConstruct>(Parser<OmpBeginBlockDirective>{}, + LooselyStructuredBlockParser{}, Parser<OmpEndBlockDirective>{})) // OMP SECTIONS Directive TYPE_PARSER(construct<OmpSectionsDirective>(first( |