diff options
Diffstat (limited to 'flang/lib/Semantics/canonicalize-omp.cpp')
-rw-r--r-- | flang/lib/Semantics/canonicalize-omp.cpp | 54 |
1 files changed, 50 insertions, 4 deletions
diff --git a/flang/lib/Semantics/canonicalize-omp.cpp b/flang/lib/Semantics/canonicalize-omp.cpp index cf05d84..9722eca 100644 --- a/flang/lib/Semantics/canonicalize-omp.cpp +++ b/flang/lib/Semantics/canonicalize-omp.cpp @@ -9,6 +9,7 @@ #include "canonicalize-omp.h" #include "flang/Parser/parse-tree-visitor.h" #include "flang/Parser/parse-tree.h" +#include "flang/Semantics/semantics.h" // After Loop Canonicalization, rewrite OpenMP parse tree to make OpenMP // Constructs more structured which provide explicit scopes for later @@ -27,7 +28,8 @@ class CanonicalizationOfOmp { public: template <typename T> bool Pre(T &) { return true; } template <typename T> void Post(T &) {} - CanonicalizationOfOmp(parser::Messages &messages) : messages_{messages} {} + CanonicalizationOfOmp(SemanticsContext &context) + : context_{context}, messages_{context.messages()} {} void Post(parser::Block &block) { for (auto it{block.begin()}; it != block.end(); ++it) { @@ -88,6 +90,8 @@ public: CanonicalizeUtilityConstructs(spec); } + void Post(parser::OmpMapClause &map) { CanonicalizeMapModifiers(map); } + private: template <typename T> T *GetConstructIf(parser::ExecutionPartConstruct &x) { if (auto *y{std::get_if<parser::ExecutableConstruct>(&x.u)}) { @@ -390,16 +394,58 @@ private: 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) { + unsigned version{context_.langOptions().OpenMPVersion}; + if (version >= 60) { + return; + } + + // Omp{Always, Close, Present, xHold}Modifier -> OmpMapTypeModifier + // OmpDeleteModifier -> OmpMapType + using Modifier = parser::OmpMapClause::Modifier; + using Modifiers = std::optional<std::list<Modifier>>; + auto &modifiers{std::get<Modifiers>(map.t)}; + if (!modifiers) { + return; + } + + using MapTypeModifier = parser::OmpMapTypeModifier; + using MapType = parser::OmpMapType; + + for (auto &mod : *modifiers) { + if (std::holds_alternative<parser::OmpAlwaysModifier>(mod.u)) { + mod.u = MapTypeModifier(MapTypeModifier::Value::Always); + } else if (std::holds_alternative<parser::OmpCloseModifier>(mod.u)) { + mod.u = MapTypeModifier(MapTypeModifier::Value::Close); + } else if (std::holds_alternative<parser::OmpPresentModifier>(mod.u)) { + mod.u = MapTypeModifier(MapTypeModifier::Value::Present); + } else if (std::holds_alternative<parser::OmpxHoldModifier>(mod.u)) { + mod.u = MapTypeModifier(MapTypeModifier::Value::Ompx_Hold); + } else if (std::holds_alternative<parser::OmpDeleteModifier>(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. std::map<parser::SpecificationPart *, parser::Block *> blockForSpec_; + SemanticsContext &context_; parser::Messages &messages_; }; -bool CanonicalizeOmp(parser::Messages &messages, parser::Program &program) { - CanonicalizationOfOmp omp{messages}; +bool CanonicalizeOmp(SemanticsContext &context, parser::Program &program) { + CanonicalizationOfOmp omp{context}; Walk(program, omp); - return !messages.AnyFatalError(); + return !context.messages().AnyFatalError(); } } // namespace Fortran::semantics |