aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Semantics/canonicalize-omp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Semantics/canonicalize-omp.cpp')
-rw-r--r--flang/lib/Semantics/canonicalize-omp.cpp54
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