diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index 32b6ca45609b6..23e35d106c077 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -529,6 +529,8 @@ class ParseTreeDumper { NODE(parser, OmpAlignClause) NODE(parser, OmpAlignedClause) NODE(OmpAlignedClause, Modifier) + NODE(parser, OmpAlwaysModifier) + NODE_ENUM(OmpAlwaysModifier, Value) NODE(parser, OmpAtClause) NODE_ENUM(OmpAtClause, ActionTime) NODE_ENUM(OmpSeverityClause, Severity) @@ -546,6 +548,8 @@ class ParseTreeDumper { #include "llvm/Frontend/OpenMP/OMP.inc" NODE(parser, OmpClauseList) NODE(parser, OmpCancellationConstructTypeClause) + NODE(parser, OmpCloseModifier) + NODE_ENUM(OmpCloseModifier, Value) NODE(parser, OmpContainsClause) NODE(parser, OmpCriticalDirective) NODE(parser, OmpErrorDirective) @@ -561,6 +565,8 @@ class ParseTreeDumper { NODE(parser, OmpDefaultmapClause) NODE_ENUM(OmpDefaultmapClause, ImplicitBehavior) NODE(OmpDefaultmapClause, Modifier) + NODE(parser, OmpDeleteModifier) + NODE_ENUM(OmpDeleteModifier, Value) NODE(parser, OmpDependenceType) NODE_ENUM(OmpDependenceType, Value) NODE(parser, OmpTaskDependenceType) @@ -628,6 +634,8 @@ class ParseTreeDumper { NODE(OmpNumTasksClause, Modifier) NODE(parser, OmpBindClause) NODE_ENUM(OmpBindClause, Binding) + NODE(parser, OmpPresentModifier) + NODE_ENUM(OmpPresentModifier, Value) NODE(parser, OmpProcBindClause) NODE_ENUM(OmpProcBindClause, AffinityPolicy) NODE(parser, OmpReductionModifier) @@ -637,6 +645,10 @@ class ParseTreeDumper { NODE(parser, OmpInReductionClause) NODE(OmpInReductionClause, Modifier) NODE(parser, OmpReductionCombiner) + NODE(parser, OmpRefModifier) + NODE_ENUM(OmpRefModifier, Value) + NODE(parser, OmpSelfModifier) + NODE_ENUM(OmpSelfModifier, Value) NODE(parser, OmpTaskReductionClause) NODE(OmpTaskReductionClause, Modifier) NODE(parser, OmpInitializerProc) @@ -673,6 +685,8 @@ class ParseTreeDumper { NODE(parser, OmpSectionsDirective) NODE(parser, OmpToClause) NODE(OmpToClause, Modifier) + NODE(parser, OmpxHoldModifier) + NODE_ENUM(OmpxHoldModifier, Value) NODE(parser, Only) NODE(parser, OpenACCAtomicConstruct) NODE(parser, OpenACCBlockConstruct) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index cc1d032f94d4a..0b3dec1010312 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3756,6 +3756,19 @@ struct OmpAllocatorComplexModifier { WRAPPER_CLASS_BOILERPLATE(OmpAllocatorComplexModifier, ScalarIntExpr); }; +// Ref: [4.5:216-219], [5.0:315-324], [5.1:347-355], [5.2:150-158], +// [6.0:279-288] +// +// always-modifier -> +// ALWAYS // since 4.5 +// +// Until 5.2, it was a part of map-type-modifier. Since 6.0 the +// map-type-modifier has been split into individual modifiers. +struct OmpAlwaysModifier { + ENUM_CLASS(Value, Always) + WRAPPER_CLASS_BOILERPLATE(OmpAlwaysModifier, Value); +}; + // Ref: [5.2:252-254] // // chunk-modifier -> @@ -3767,17 +3780,29 @@ struct OmpChunkModifier { WRAPPER_CLASS_BOILERPLATE(OmpChunkModifier, Value); }; -// Ref: [5.0:47-49], [5.1:49-51], [5.2:67-69] +// Ref: [4.5:216-219], [5.0:315-324], [5.1:347-355], [5.2:150-158], +// [6.0:279-288] // -// iterator-specifier -> -// [iterator-type] iterator-identifier -// = range-specification | // since 5.0 -// [iterator-type ::] iterator-identifier -// = range-specification // since 5.2 -struct OmpIteratorSpecifier { - TUPLE_CLASS_BOILERPLATE(OmpIteratorSpecifier); - CharBlock source; - std::tuple t; +// close-modifier -> +// CLOSE // since 5.0 +// +// Until 5.2, it was a part of map-type-modifier. Since 6.0 the +// map-type-modifier has been split into individual modifiers. +struct OmpCloseModifier { + ENUM_CLASS(Value, Close) + WRAPPER_CLASS_BOILERPLATE(OmpCloseModifier, Value); +}; + +// Ref: [4.5:216-219], [5.0:315-324], [5.1:347-355], [5.2:150-158], +// [6.0:279-288] +// +// delete-modifier -> +// DELETE // since 6.0 +// +// Until 5.2, it was a part of map-type. +struct OmpDeleteModifier { + ENUM_CLASS(Value, Delete) + WRAPPER_CLASS_BOILERPLATE(OmpDeleteModifier, Value); }; // Ref: [4.5:169-170], [5.0:255-256], [5.1:288-289] @@ -3867,6 +3892,19 @@ struct OmpInteropType { WRAPPER_CLASS_BOILERPLATE(OmpInteropType, Value); }; +// Ref: [5.0:47-49], [5.1:49-51], [5.2:67-69] +// +// iterator-specifier -> +// [iterator-type] iterator-identifier +// = range-specification | // since 5.0 +// [iterator-type ::] iterator-identifier +// = range-specification // since 5.2 +struct OmpIteratorSpecifier { + TUPLE_CLASS_BOILERPLATE(OmpIteratorSpecifier); + CharBlock source; + std::tuple t; +}; + // Ref: [5.0:47-49], [5.1:49-51], [5.2:67-69] // // iterator-modifier -> @@ -3901,21 +3939,28 @@ struct OmpMapper { WRAPPER_CLASS_BOILERPLATE(OmpMapper, Name); }; -// Ref: [4.5:216-219], [5.0:315-324], [5.1:347-355], [5.2:150-158] +// Ref: [4.5:216-219], [5.0:315-324], [5.1:347-355], [5.2:150-158], +// [6.0:279-288] // // map-type -> -// ALLOC | DELETE | FROM | RELEASE | TO | TOFROM // since 4.5 +// ALLOC | DELETE | RELEASE | // since 4.5, until 5.2 +// FROM | TO | TOFROM | // since 4.5 +// STORAGE // since 6.0 +// +// Since 6.0 DELETE is a separate delete-modifier. struct OmpMapType { - ENUM_CLASS(Value, Alloc, Delete, From, Release, To, Tofrom); + ENUM_CLASS(Value, Alloc, Delete, From, Release, Storage, To, Tofrom); WRAPPER_CLASS_BOILERPLATE(OmpMapType, Value); }; // Ref: [4.5:216-219], [5.0:315-324], [5.1:347-355], [5.2:150-158] // // map-type-modifier -> -// ALWAYS | // since 4.5 -// CLOSE | // since 5.0 -// PRESENT // since 5.1 +// ALWAYS | // since 4.5, until 5.2 +// CLOSE | // since 5.0, until 5.2 +// PRESENT // since 5.1, until 5.2 +// Since 6.0 the map-type-modifier has been split into individual modifiers. +// struct OmpMapTypeModifier { ENUM_CLASS(Value, Always, Close, Present, Ompx_Hold) WRAPPER_CLASS_BOILERPLATE(OmpMapTypeModifier, Value); @@ -3954,6 +3999,19 @@ struct OmpPrescriptiveness { WRAPPER_CLASS_BOILERPLATE(OmpPrescriptiveness, Value); }; +// Ref: [4.5:216-219], [5.0:315-324], [5.1:347-355], [5.2:150-158], +// [6.0:279-288] +// +// present-modifier -> +// PRESENT // since 5.1 +// +// Until 5.2, it was a part of map-type-modifier. Since 6.0 the +// map-type-modifier has been split into individual modifiers. +struct OmpPresentModifier { + ENUM_CLASS(Value, Present) + WRAPPER_CLASS_BOILERPLATE(OmpPresentModifier, Value); +}; + // Ref: [5.0:300-302], [5.1:332-334], [5.2:134-137] // // reduction-modifier -> @@ -3963,6 +4021,26 @@ struct OmpReductionModifier { WRAPPER_CLASS_BOILERPLATE(OmpReductionModifier, Value); }; +// Ref: [6.0:279-288] +// +// ref-modifier -> +// REF_PTEE | REF_PTR | REF_PTR_PTEE // since 6.0 +// +struct OmpRefModifier { + ENUM_CLASS(Value, Ref_Ptee, Ref_Ptr, Ref_Ptr_Ptee) + WRAPPER_CLASS_BOILERPLATE(OmpRefModifier, Value); +}; + +// Ref: [6.0:279-288] +// +// self-modifier -> +// SELF // since 6.0 +// +struct OmpSelfModifier { + ENUM_CLASS(Value, Self) + WRAPPER_CLASS_BOILERPLATE(OmpSelfModifier, Value); +}; + // Ref: [5.2:117-120] // // step-complex-modifier -> @@ -4001,6 +4079,19 @@ struct OmpVariableCategory { WRAPPER_CLASS_BOILERPLATE(OmpVariableCategory, Value); }; +// Extension: +// https://openmp.llvm.org//openacc/OpenMPExtensions.html#ompx-hold +// +// ompx-hold-modifier -> +// OMPX_HOLD // since 4.5 +// +// Until 5.2, it was a part of map-type-modifier. Since 6.0 the +// map-type-modifier has been split into individual modifiers. +struct OmpxHoldModifier { + ENUM_CLASS(Value, Ompx_Hold) + WRAPPER_CLASS_BOILERPLATE(OmpxHoldModifier, Value); +}; + // context-selector using OmpContextSelector = traits::OmpContextSelectorSpecification; } // namespace modifier @@ -4376,13 +4467,25 @@ struct OmpLinearClause { // map-clause -> // MAP([modifier...:] locator-list) // since 4.5 // modifier -> -// map-type-modifier | // since 4.5 +// map-type-modifier [replaced] | // since 4.5, until 5.2 +// always-modifier | // since 6.0 +// close-modifier | // since 6.0 +// delete-modifier | // since 6.0 +// present-modifier | // since 6.0 +// ref-modifier | // since 6.0 +// self-modifier | // since 6.0 // mapper | // since 5.0 // iterator | // since 5.1 // map-type // since 4.5 +// ompx-hold-modifier | // since 6.0 +// +// Since 6.0 the map-type-modifier has been split into individual modifiers, +// and delete-modifier has been split from map-type. struct OmpMapClause { TUPLE_CLASS_BOILERPLATE(OmpMapClause); - MODIFIER_BOILERPLATE(OmpMapTypeModifier, OmpMapper, OmpIterator, OmpMapType); + MODIFIER_BOILERPLATE(OmpAlwaysModifier, OmpCloseModifier, OmpDeleteModifier, + OmpMapTypeModifier, OmpPresentModifier, OmpRefModifier, OmpSelfModifier, + OmpMapper, OmpIterator, OmpMapType, OmpxHoldModifier); std::tuple t; }; diff --git a/flang/include/flang/Semantics/openmp-modifiers.h b/flang/include/flang/Semantics/openmp-modifiers.h index 4fbd80f989e72..a9fe911ef8807 100644 --- a/flang/include/flang/Semantics/openmp-modifiers.h +++ b/flang/include/flang/Semantics/openmp-modifiers.h @@ -71,8 +71,11 @@ DECLARE_DESCRIPTOR(parser::OmpAlignment); DECLARE_DESCRIPTOR(parser::OmpAlignModifier); DECLARE_DESCRIPTOR(parser::OmpAllocatorComplexModifier); DECLARE_DESCRIPTOR(parser::OmpAllocatorSimpleModifier); +DECLARE_DESCRIPTOR(parser::OmpAlwaysModifier); DECLARE_DESCRIPTOR(parser::OmpChunkModifier); +DECLARE_DESCRIPTOR(parser::OmpCloseModifier); DECLARE_DESCRIPTOR(parser::OmpContextSelector); +DECLARE_DESCRIPTOR(parser::OmpDeleteModifier); DECLARE_DESCRIPTOR(parser::OmpDependenceType); DECLARE_DESCRIPTOR(parser::OmpDeviceModifier); DECLARE_DESCRIPTOR(parser::OmpDirectiveNameModifier); @@ -88,12 +91,16 @@ DECLARE_DESCRIPTOR(parser::OmpMapTypeModifier); DECLARE_DESCRIPTOR(parser::OmpOrderModifier); DECLARE_DESCRIPTOR(parser::OmpOrderingModifier); DECLARE_DESCRIPTOR(parser::OmpPrescriptiveness); +DECLARE_DESCRIPTOR(parser::OmpPresentModifier); DECLARE_DESCRIPTOR(parser::OmpReductionIdentifier); DECLARE_DESCRIPTOR(parser::OmpReductionModifier); +DECLARE_DESCRIPTOR(parser::OmpRefModifier); +DECLARE_DESCRIPTOR(parser::OmpSelfModifier); DECLARE_DESCRIPTOR(parser::OmpStepComplexModifier); DECLARE_DESCRIPTOR(parser::OmpStepSimpleModifier); DECLARE_DESCRIPTOR(parser::OmpTaskDependenceType); DECLARE_DESCRIPTOR(parser::OmpVariableCategory); +DECLARE_DESCRIPTOR(parser::OmpxHoldModifier); #undef DECLARE_DESCRIPTOR diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 76c9499410017..d349d8ceb0bb5 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -274,6 +274,10 @@ TYPE_PARSER( // construct(Parser{}) || construct(Parser{})) +// 2.15.3.6 REDUCTION (reduction-identifier: variable-name-list) +TYPE_PARSER(construct(Parser{}) || + construct(Parser{})) + TYPE_PARSER(construct( // Parser{}, ":"_tok >> nonemptyList(Parser{}), @@ -442,9 +446,18 @@ TYPE_PARSER(construct( TYPE_PARSER(construct(scalarIntExpr)) +TYPE_PARSER(construct( // + "ALWAYS" >> pure(OmpAlwaysModifier::Value::Always))) + TYPE_PARSER(construct( // "SIMD" >> pure(OmpChunkModifier::Value::Simd))) +TYPE_PARSER(construct( // + "CLOSE" >> pure(OmpCloseModifier::Value::Close))) + +TYPE_PARSER(construct( // + "DELETE" >> pure(OmpDeleteModifier::Value::Delete))) + TYPE_PARSER(construct( "SINK" >> pure(OmpDependenceType::Value::Sink) || "SOURCE" >> pure(OmpDependenceType::Value::Source))) @@ -502,26 +515,16 @@ TYPE_PARSER(construct( // TYPE_PARSER(construct( // "MAPPER"_tok >> parenthesized(Parser{}))) -// map-type -> ALLOC | DELETE | FROM | RELEASE | TO | TOFROM +// map-type -> ALLOC | DELETE | FROM | RELEASE | STORAGE | TO | TOFROM TYPE_PARSER(construct( // "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( - "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(Parser{}) || - construct(Parser{})) - TYPE_PARSER(construct( "REPRODUCIBLE" >> pure(OmpOrderModifier::Value::Reproducible) || "UNCONSTRAINED" >> pure(OmpOrderModifier::Value::Unconstrained))) @@ -534,11 +537,22 @@ TYPE_PARSER(construct( TYPE_PARSER(construct( "STRICT" >> pure(OmpPrescriptiveness::Value::Strict))) +TYPE_PARSER(construct( // + "PRESENT" >> pure(OmpPresentModifier::Value::Present))) + TYPE_PARSER(construct( "INSCAN" >> pure(OmpReductionModifier::Value::Inscan) || "TASK" >> pure(OmpReductionModifier::Value::Task) || "DEFAULT" >> pure(OmpReductionModifier::Value::Default))) +TYPE_PARSER(construct( // + "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( // + "SELF" >> pure(OmpSelfModifier::Value::Self))) + TYPE_PARSER(construct( // "STEP" >> parenthesized(scalarIntExpr))) @@ -559,6 +573,9 @@ TYPE_PARSER(construct( "POINTER" >> pure(OmpVariableCategory::Value::Pointer) || "SCALAR" >> pure(OmpVariableCategory::Value::Scalar))) +TYPE_PARSER(construct( // + "OMPX_HOLD" >> pure(OmpxHoldModifier::Value::Ompx_Hold))) + // This could be auto-generated. TYPE_PARSER( sourced(construct(Parser{}))) @@ -611,10 +628,16 @@ TYPE_PARSER(sourced( construct(Parser{}))) TYPE_PARSER(sourced(construct( - sourced(construct(Parser{}) || + sourced(construct(Parser{}) || + construct(Parser{}) || + construct(Parser{}) || + construct(Parser{}) || + construct(Parser{}) || + construct(Parser{}) || construct(Parser{}) || construct(Parser{}) || - construct(Parser{}))))) + construct(Parser{}) || + construct(Parser{}))))) TYPE_PARSER( sourced(construct(Parser{}))) diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index fbe89c668fc13..8ed16905b5099 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -3007,8 +3007,15 @@ class UnparseVisitor { WALK_NESTED_ENUM(OmpPrescriptiveness, Value) // OMP prescriptiveness WALK_NESTED_ENUM(OmpMapType, Value) // OMP map-type WALK_NESTED_ENUM(OmpMapTypeModifier, Value) // OMP map-type-modifier + WALK_NESTED_ENUM(OmpAlwaysModifier, Value) + WALK_NESTED_ENUM(OmpCloseModifier, Value) + WALK_NESTED_ENUM(OmpDeleteModifier, Value) + WALK_NESTED_ENUM(OmpPresentModifier, Value) + WALK_NESTED_ENUM(OmpRefModifier, Value) + WALK_NESTED_ENUM(OmpSelfModifier, Value) WALK_NESTED_ENUM(OmpTraitSelectorName, Value) WALK_NESTED_ENUM(OmpTraitSetSelectorName, Value) + WALK_NESTED_ENUM(OmpxHoldModifier, Value) #undef WALK_NESTED_ENUM void Unparse(const ReductionOperator::Operator x) { diff --git a/flang/lib/Semantics/canonicalize-omp.cpp b/flang/lib/Semantics/canonicalize-omp.cpp index cf05d8463277f..bba4d72a702e9 100644 --- a/flang/lib/Semantics/canonicalize-omp.cpp +++ b/flang/lib/Semantics/canonicalize-omp.cpp @@ -88,6 +88,8 @@ class CanonicalizationOfOmp { CanonicalizeUtilityConstructs(spec); } + void Post(parser::OmpMapClause &map) { CanonicalizeMapModifiers(map); } + private: template T *GetConstructIf(parser::ExecutionPartConstruct &x) { if (auto *y{std::get_if(&x.u)}) { @@ -390,6 +392,42 @@ class CanonicalizationOfOmp { omps.erase(rlast.base(), omps.end()); } + // Map clause modifiers are parsed as per OpenMP 6.0 spec. That spec has + // changed properties of some of the modifiers, for example it has expanded + // map-type-modifier into 3 individual modifiers (one for each of the + // possible values of the original modifier), and the "map-type" modifier + // is no longer ultimate. + // To utilize the modifier validation framework for semantic checks, + // if the specified OpenMP version is less than 6.0, rewrite the affected + // modifiers back into the pre-6.0 forms. + void CanonicalizeMapModifiers(parser::OmpMapClause &map) { + // Omp{Always, Close, Present, xHold}Modifier -> OmpMapTypeModifier + // OmpDeleteModifier -> OmpMapType + using Modifier = parser::OmpMapClause::Modifier; + using Modifiers = std::optional>; + auto &modifiers{std::get(map.t)}; + if (!modifiers) { + return; + } + + using MapTypeModifier = parser::OmpMapTypeModifier; + using MapType = parser::OmpMapType; + + for (auto &mod : *modifiers) { + if (std::holds_alternative(mod.u)) { + mod.u = MapTypeModifier(MapTypeModifier::Value::Always); + } else if (std::holds_alternative(mod.u)) { + mod.u = MapTypeModifier(MapTypeModifier::Value::Close); + } else if (std::holds_alternative(mod.u)) { + mod.u = MapTypeModifier(MapTypeModifier::Value::Present); + } else if (std::holds_alternative(mod.u)) { + mod.u = MapTypeModifier(MapTypeModifier::Value::Ompx_Hold); + } else if (std::holds_alternative(mod.u)) { + mod.u = MapType(MapType::Value::Delete); + } + } + } + // Mapping from the specification parts to the blocks that follow in the // same construct. This is for converting utility constructs to executable // constructs. diff --git a/flang/lib/Semantics/canonicalize-omp.h b/flang/lib/Semantics/canonicalize-omp.h index c45d6bbbf9062..23350c522a775 100644 --- a/flang/lib/Semantics/canonicalize-omp.h +++ b/flang/lib/Semantics/canonicalize-omp.h @@ -15,7 +15,9 @@ class Messages; } // namespace Fortran::parser namespace Fortran::semantics { +class SemanticsContext; + bool CanonicalizeOmp(parser::Messages &messages, parser::Program &program); -} +} // namespace Fortran::semantics #endif // FORTRAN_SEMANTICS_CANONICALIZE_OMP_H_ diff --git a/flang/lib/Semantics/openmp-modifiers.cpp b/flang/lib/Semantics/openmp-modifiers.cpp index c84e832ee52a1..336ce4beb24ba 100644 --- a/flang/lib/Semantics/openmp-modifiers.cpp +++ b/flang/lib/Semantics/openmp-modifiers.cpp @@ -140,6 +140,22 @@ OmpGetDescriptor() { return desc; } +template <> +const OmpModifierDescriptor &OmpGetDescriptor() { + static const OmpModifierDescriptor desc{ + /*name=*/"always-modifier", + /*props=*/ + { + {45, {OmpProperty::Unique}}, + }, + /*clauses=*/ + { + {45, {Clause::OMPC_map}}, + }, + }; + return desc; +} + template <> const OmpModifierDescriptor &OmpGetDescriptor() { static const OmpModifierDescriptor desc{ @@ -156,6 +172,22 @@ const OmpModifierDescriptor &OmpGetDescriptor() { return desc; } +template <> +const OmpModifierDescriptor &OmpGetDescriptor() { + static const OmpModifierDescriptor desc{ + /*name=*/"close-modifier", + /*props=*/ + { + {50, {OmpProperty::Unique}}, + }, + /*clauses=*/ + { + {50, {Clause::OMPC_map}}, + }, + }; + return desc; +} + template <> const OmpModifierDescriptor &OmpGetDescriptor() { static const OmpModifierDescriptor desc{ @@ -173,6 +205,23 @@ const OmpModifierDescriptor &OmpGetDescriptor() { return desc; } +template <> +const OmpModifierDescriptor &OmpGetDescriptor() { + static const OmpModifierDescriptor desc{ + /*name=*/"delete-modifier", + /*props=*/ + { + {45, {OmpProperty::Unique, OmpProperty::Ultimate}}, + {60, {OmpProperty::Unique}}, + }, + /*clauses=*/ + { + {45, {Clause::OMPC_map}}, + }, + }; + return desc; +} + template <> const OmpModifierDescriptor &OmpGetDescriptor() { static const OmpModifierDescriptor desc{ @@ -347,6 +396,7 @@ const OmpModifierDescriptor &OmpGetDescriptor() { /*props=*/ { {45, {OmpProperty::Ultimate}}, + {60, {OmpProperty::Unique}}, }, /*clauses=*/ { @@ -367,6 +417,7 @@ const OmpModifierDescriptor &OmpGetDescriptor() { /*clauses=*/ { {45, {Clause::OMPC_map}}, + {60, {}}, }, }; return desc; @@ -420,6 +471,22 @@ const OmpModifierDescriptor &OmpGetDescriptor() { return desc; } +template <> +const OmpModifierDescriptor &OmpGetDescriptor() { + static const OmpModifierDescriptor desc{ + /*name=*/"present-modifier", + /*props=*/ + { + {51, {OmpProperty::Unique}}, + }, + /*clauses=*/ + { + {51, {Clause::OMPC_map}}, + }, + }; + return desc; +} + template <> const OmpModifierDescriptor & OmpGetDescriptor() { @@ -456,6 +523,38 @@ const OmpModifierDescriptor &OmpGetDescriptor() { return desc; } +template <> +const OmpModifierDescriptor &OmpGetDescriptor() { + static const OmpModifierDescriptor desc{ + /*name=*/"ref-modifier", + /*props=*/ + { + {60, {OmpProperty::Unique}}, + }, + /*clauses=*/ + { + {60, {Clause::OMPC_map}}, + }, + }; + return desc; +} + +template <> +const OmpModifierDescriptor &OmpGetDescriptor() { + static const OmpModifierDescriptor desc{ + /*name=*/"self-modifier", + /*props=*/ + { + {60, {OmpProperty::Unique}}, + }, + /*clauses=*/ + { + {60, {Clause::OMPC_map}}, + }, + }; + return desc; +} + template <> const OmpModifierDescriptor & OmpGetDescriptor() { @@ -522,4 +621,20 @@ const OmpModifierDescriptor &OmpGetDescriptor() { }; return desc; } + +template <> +const OmpModifierDescriptor &OmpGetDescriptor() { + static const OmpModifierDescriptor desc{ + /*name=*/"ompx-hold-modifier", + /*props=*/ + { + {45, {OmpProperty::Unique}}, + }, + /*clauses=*/ + { + {45, {Clause::OMPC_map}}, + }, + }; + return desc; +} } // namespace Fortran::semantics diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index 521c7432d9fbb..332291a2aefe8 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -749,6 +749,8 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor { case parser::OmpMapType::Value::Delete: ompFlag = Symbol::Flag::OmpMapDelete; break; + default: + break; } } const auto &ompObjList{std::get(x.t)}; diff --git a/flang/test/Parser/OpenMP/map-modifiers-v60.f90 b/flang/test/Parser/OpenMP/map-modifiers-v60.f90 new file mode 100644 index 0000000000000..bc80886780d46 --- /dev/null +++ b/flang/test/Parser/OpenMP/map-modifiers-v60.f90 @@ -0,0 +1,113 @@ +!RUN: %flang_fc1 -fdebug-unparse-no-sema -fopenmp -fopenmp-version=60 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s +!RUN: %flang_fc1 -fdebug-dump-parse-tree-no-sema -fopenmp -fopenmp-version=60 %s | FileCheck --check-prefix="PARSE-TREE" %s + +subroutine f00(x) + integer :: x + !$omp target map(always, close, delete, present, ompx_hold: x) + x = x + 1 + !$omp end target +end + +!UNPARSE: SUBROUTINE f00 (x) +!UNPARSE: INTEGER x +!UNPARSE: !$OMP TARGET MAP(ALWAYS, CLOSE, DELETE, PRESENT, OMPX_HOLD: x) +!UNPARSE: x = x+1 +!UNPARSE: !$OMP END TARGET +!UNPARSE: END SUBROUTINE + +!PARSE-TREE: OmpBeginBlockDirective +!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target +!PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause +!PARSE-TREE: | | Modifier -> OmpAlwaysModifier -> Value = Always +!PARSE-TREE: | | Modifier -> OmpCloseModifier -> Value = Close +!PARSE-TREE: | | Modifier -> OmpDeleteModifier -> Value = Delete +!PARSE-TREE: | | Modifier -> OmpPresentModifier -> Value = Present +!PARSE-TREE: | | Modifier -> OmpxHoldModifier -> Value = Ompx_Hold +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: | | bool = 'true' + +subroutine f01(x) + integer :: x + !$omp target map(self, storage: x) + x = x + 1 + !$omp end target +end + +!UNPARSE: !$OMP TARGET MAP(SELF, STORAGE: x) +!UNPARSE: x = x+1 +!UNPARSE: !$OMP END TARGET +!UNPARSE: END SUBROUTINE + +!PARSE-TREE: OmpBeginBlockDirective +!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target +!PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause +!PARSE-TREE: | | Modifier -> OmpSelfModifier -> Value = Self +!PARSE-TREE: | | Modifier -> OmpMapType -> Value = Storage +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: | | bool = 'true' + +subroutine f02(x) + integer, pointer :: x + !$omp target map(ref_ptr, to: x) + x = x + 1 + !$omp end target +end + +!UNPARSE: SUBROUTINE f02 (x) +!UNPARSE: INTEGER, POINTER :: x +!UNPARSE: !$OMP TARGET MAP(REF_PTR, TO: x) +!UNPARSE: x = x+1 +!UNPARSE: !$OMP END TARGET +!UNPARSE: END SUBROUTINE + +!PARSE-TREE: OmpBeginBlockDirective +!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target +!PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause +!PARSE-TREE: | | Modifier -> OmpRefModifier -> Value = Ref_Ptr +!PARSE-TREE: | | Modifier -> OmpMapType -> Value = To +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: | | bool = 'true' + +subroutine f03(x) + integer, pointer :: x + !$omp target map(ref_ptee, to: x) + x = x + 1 + !$omp end target +end + +!UNPARSE: SUBROUTINE f03 (x) +!UNPARSE: INTEGER, POINTER :: x +!UNPARSE: !$OMP TARGET MAP(REF_PTEE, TO: x) +!UNPARSE: x = x+1 +!UNPARSE: !$OMP END TARGET +!UNPARSE: END SUBROUTINE + +!PARSE-TREE: OmpBeginBlockDirective +!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target +!PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause +!PARSE-TREE: | | Modifier -> OmpRefModifier -> Value = Ref_Ptee +!PARSE-TREE: | | Modifier -> OmpMapType -> Value = To +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: | | bool = 'true' + +subroutine f04(x) + integer, pointer :: x + !$omp target map(ref_ptr_ptee, to: x) + x = x + 1 + !$omp end target +end + +!UNPARSE: SUBROUTINE f04 (x) +!UNPARSE: INTEGER, POINTER :: x +!UNPARSE: !$OMP TARGET MAP(REF_PTR_PTEE, TO: x) +!UNPARSE: x = x+1 +!UNPARSE: !$OMP END TARGET +!UNPARSE: END SUBROUTINE + +!PARSE-TREE: OmpBeginBlockDirective +!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target +!PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause +!PARSE-TREE: | | Modifier -> OmpRefModifier -> Value = Ref_Ptr_Ptee +!PARSE-TREE: | | Modifier -> OmpMapType -> Value = To +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: | | bool = 'true'