[flang-commits] [flang] [llvm] [OpenMP][flang] Use auto-generated data for modifier verification (PR #215648)

via flang-commits flang-commits at lists.llvm.org
Tue Aug 11 13:10:31 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-openmp

Author: Krzysztof Parzyszek (kparzysz)

<details>
<summary>Changes</summary>

Introduce descriptors of OpenMP clauses and modifiers, auto-generated from OpenMP specification data[*].

This replaces the preexisting modifier descriptors used in flang, the code using it is adjusted to use the new definitions.

[*] This does not contain any actual auto-generation infrastructure. The descriptors were generated by a custom script from the exported OpenMP definitions.

---

Patch is 233.01 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/215648.diff


19 Files Affected:

- (modified) flang/include/flang/Semantics/openmp-modifiers.h (+140-113) 
- (modified) flang/lib/Semantics/CMakeLists.txt (-1) 
- (modified) flang/lib/Semantics/check-omp-loop.cpp (+4-4) 
- (modified) flang/lib/Semantics/check-omp-structure.cpp (+9-25) 
- (removed) flang/lib/Semantics/openmp-modifiers.cpp (-791) 
- (modified) flang/test/Parser/OpenMP/map-modifiers.f90 (+10-19) 
- (modified) flang/test/Semantics/OpenMP/allocate-clause01.f90 (+1-1) 
- (modified) flang/test/Semantics/OpenMP/device-clause01.f90 (+1-1) 
- (modified) flang/test/Semantics/OpenMP/from-clause-v45.f90 (-8) 
- (modified) flang/test/Semantics/OpenMP/linear-clause01.f90 (+7-2) 
- (modified) flang/test/Semantics/OpenMP/map-modifiers.f90 (+4-10) 
- (modified) flang/test/Semantics/OpenMP/scan1.f90 (+1-1) 
- (modified) flang/test/Semantics/OpenMP/simd-linear-array.f90 (+2-1) 
- (modified) flang/test/Semantics/OpenMP/to-clause-v45.f90 (-8) 
- (added) llvm/include/llvm/Frontend/OpenMP/OMPDescriptors.h (+125) 
- (added) llvm/include/llvm/Frontend/OpenMP/OMPDescriptors.h.inc (+116) 
- (modified) llvm/lib/Frontend/OpenMP/CMakeLists.txt (+1) 
- (added) llvm/lib/Frontend/OpenMP/OMPDescriptors.cpp (+80) 
- (added) llvm/lib/Frontend/OpenMP/OMPDescriptors.inc (+2370) 


``````````diff
diff --git a/flang/include/flang/Semantics/openmp-modifiers.h b/flang/include/flang/Semantics/openmp-modifiers.h
index 41a4a87f60949..8932b7ab32403 100644
--- a/flang/include/flang/Semantics/openmp-modifiers.h
+++ b/flang/include/flang/Semantics/openmp-modifiers.h
@@ -16,6 +16,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Frontend/OpenMP/OMP.h"
+#include "llvm/Frontend/OpenMP/OMPDescriptors.h"
 
 #include <cassert>
 #include <map>
@@ -39,77 +40,87 @@ namespace Fortran::semantics {
 // Argument defaults: Required,     Unique, Compatible, Free
 // Modifier defaults: Optional,     Unique, Compatible, Free
 //
-// ---
-// Each modifier is used as either pre-modifier (i.e. modifier: item),
-// or post-modifier (i.e. item: modifier). The default is pre-.
-// Add an additional property that reflects the type of modifier.
-
-ENUM_CLASS(OmpProperty, Required, Unique, Exclusive, Ultimate, Post)
-using OmpProperties = common::EnumSet<OmpProperty, OmpProperty_enumSize>;
-using OmpClauses =
-    llvm::omp::EnumSet<llvm::omp::Clause, llvm::omp::Clause_enumSize>;
-
-struct OmpModifierDescriptor {
-  // Modifier name for use in diagnostic messages.
-  const OmpProperties &props(unsigned version) const;
-  const OmpClauses &clauses(unsigned version) const;
-  unsigned since(llvm::omp::Clause id) const;
-
-  const llvm::StringRef name;
-  // Version-dependent properties of the modifier.
-  const std::map<unsigned, OmpProperties> props_;
-  // Version-dependent set of clauses to which the modifier can apply.
-  const std::map<unsigned, OmpClauses> clauses_;
-};
+template <typename SpecificTy> llvm::omp::Modifier OmpGetModifierId();
+template <typename SpecificTy>
+const llvm::omp::descriptor::Modifier &OmpGetDescriptor();
+
+#define DECLARE_DESCRIPTOR(name, id) \
+  template <> inline llvm::omp::Modifier OmpGetModifierId<name>() { \
+    return id; \
+  } \
+  template <> \
+  inline const llvm::omp::descriptor::Modifier &OmpGetDescriptor<name>() { \
+    return llvm::omp::getDescriptor(OmpGetModifierId<name>()); \
+  }
 
-template <typename SpecificTy> const OmpModifierDescriptor &OmpGetDescriptor();
-
-#define DECLARE_DESCRIPTOR(name) \
-  template <> const OmpModifierDescriptor &OmpGetDescriptor<name>()
-
-DECLARE_DESCRIPTOR(parser::OmpAccessGroup);
-DECLARE_DESCRIPTOR(parser::OmpAlignment);
-DECLARE_DESCRIPTOR(parser::OmpAlignModifier);
-DECLARE_DESCRIPTOR(parser::OmpAllocatorComplexModifier);
-DECLARE_DESCRIPTOR(parser::OmpAllocatorSimpleModifier);
-DECLARE_DESCRIPTOR(parser::OmpAlwaysModifier);
-DECLARE_DESCRIPTOR(parser::OmpAttachModifier);
-DECLARE_DESCRIPTOR(parser::OmpAutomapModifier);
-DECLARE_DESCRIPTOR(parser::OmpChunkModifier);
-DECLARE_DESCRIPTOR(parser::OmpCloseModifier);
-DECLARE_DESCRIPTOR(parser::OmpContextSelector);
-DECLARE_DESCRIPTOR(parser::OmpDeleteModifier);
-DECLARE_DESCRIPTOR(parser::OmpDependenceType);
-DECLARE_DESCRIPTOR(parser::OmpDepinfoModifier);
-DECLARE_DESCRIPTOR(parser::OmpDeviceModifier);
-DECLARE_DESCRIPTOR(parser::OmpDimsModifier);
-DECLARE_DESCRIPTOR(parser::OmpDirectiveNameModifier);
-DECLARE_DESCRIPTOR(parser::OmpExpectation);
-DECLARE_DESCRIPTOR(parser::OmpFallbackModifier);
-DECLARE_DESCRIPTOR(parser::OmpInteropType);
-DECLARE_DESCRIPTOR(parser::OmpIterator);
-DECLARE_DESCRIPTOR(parser::OmpLastprivateModifier);
-DECLARE_DESCRIPTOR(parser::OmpLinearModifier);
-DECLARE_DESCRIPTOR(parser::OmpLinearStep);
-DECLARE_DESCRIPTOR(parser::OmpLoopModifier);
-DECLARE_DESCRIPTOR(parser::OmpLowerBound);
-DECLARE_DESCRIPTOR(parser::OmpMapper);
-DECLARE_DESCRIPTOR(parser::OmpMapType);
-DECLARE_DESCRIPTOR(parser::OmpMapTypeModifier);
-DECLARE_DESCRIPTOR(parser::OmpOrderModifier);
-DECLARE_DESCRIPTOR(parser::OmpOrderingModifier);
-DECLARE_DESCRIPTOR(parser::OmpPreferType);
-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);
+DECLARE_DESCRIPTOR(parser::OmpAccessGroup, llvm::omp::Modifier::AccessGroup)
+DECLARE_DESCRIPTOR(parser::OmpAlignment, llvm::omp::Modifier::Alignment)
+DECLARE_DESCRIPTOR(parser::OmpAlignModifier, llvm::omp::Modifier::AlignModifier)
+DECLARE_DESCRIPTOR(parser::OmpAllocatorComplexModifier,
+    llvm::omp::Modifier::AllocatorComplexModifier)
+DECLARE_DESCRIPTOR(parser::OmpAllocatorSimpleModifier,
+    llvm::omp::Modifier::AllocatorSimpleModifier)
+DECLARE_DESCRIPTOR(
+    parser::OmpAlwaysModifier, llvm::omp::Modifier::AlwaysModifier)
+DECLARE_DESCRIPTOR(
+    parser::OmpAttachModifier, llvm::omp::Modifier::AttachModifier)
+DECLARE_DESCRIPTOR(
+    parser::OmpAutomapModifier, llvm::omp::Modifier::AutomapModifier)
+DECLARE_DESCRIPTOR(parser::OmpChunkModifier, llvm::omp::Modifier::ChunkModifier)
+DECLARE_DESCRIPTOR(parser::OmpCloseModifier, llvm::omp::Modifier::CloseModifier)
+DECLARE_DESCRIPTOR(
+    parser::OmpContextSelector, llvm::omp::Modifier::ContextSelector)
+DECLARE_DESCRIPTOR(
+    parser::OmpDeleteModifier, llvm::omp::Modifier::DeleteModifier)
+DECLARE_DESCRIPTOR(
+    parser::OmpDependenceType, llvm::omp::Modifier::DependenceType)
+DECLARE_DESCRIPTOR(
+    parser::OmpDepinfoModifier, llvm::omp::Modifier::DepinfoModifier)
+DECLARE_DESCRIPTOR(
+    parser::OmpDeviceModifier, llvm::omp::Modifier::DeviceModifier)
+DECLARE_DESCRIPTOR(parser::OmpDimsModifier, llvm::omp::Modifier::DimsModifier)
+DECLARE_DESCRIPTOR(parser::OmpDirectiveNameModifier,
+    llvm::omp::Modifier::DirectiveNameModifier)
+DECLARE_DESCRIPTOR(parser::OmpExpectation, llvm::omp::Modifier::Expectation)
+DECLARE_DESCRIPTOR(
+    parser::OmpFallbackModifier, llvm::omp::Modifier::FallbackModifier)
+DECLARE_DESCRIPTOR(parser::OmpInteropType, llvm::omp::Modifier::InteropType)
+DECLARE_DESCRIPTOR(parser::OmpIterator, llvm::omp::Modifier::Iterator)
+DECLARE_DESCRIPTOR(
+    parser::OmpLastprivateModifier, llvm::omp::Modifier::LastprivateModifier)
+DECLARE_DESCRIPTOR(
+    parser::OmpLinearModifier, llvm::omp::Modifier::LinearModifier)
+DECLARE_DESCRIPTOR(parser::OmpLinearStep, llvm::omp::Modifier::LinearStep)
+DECLARE_DESCRIPTOR(parser::OmpLoopModifier, llvm::omp::Modifier::LoopModifier)
+DECLARE_DESCRIPTOR(parser::OmpLowerBound, llvm::omp::Modifier::LowerBound)
+DECLARE_DESCRIPTOR(parser::OmpMapper, llvm::omp::Modifier::Mapper)
+DECLARE_DESCRIPTOR(parser::OmpMapType, llvm::omp::Modifier::MapType)
+DECLARE_DESCRIPTOR(
+    parser::OmpMapTypeModifier, llvm::omp::Modifier::MapTypeModifier)
+DECLARE_DESCRIPTOR(parser::OmpOrderModifier, llvm::omp::Modifier::OrderModifier)
+DECLARE_DESCRIPTOR(
+    parser::OmpOrderingModifier, llvm::omp::Modifier::OrderingModifier)
+DECLARE_DESCRIPTOR(parser::OmpPreferType, llvm::omp::Modifier::PreferType)
+DECLARE_DESCRIPTOR(
+    parser::OmpPrescriptiveness, llvm::omp::Modifier::Prescriptiveness)
+DECLARE_DESCRIPTOR(
+    parser::OmpPresentModifier, llvm::omp::Modifier::PresentModifier)
+DECLARE_DESCRIPTOR(
+    parser::OmpReductionIdentifier, llvm::omp::Modifier::ReductionIdentifier)
+DECLARE_DESCRIPTOR(
+    parser::OmpReductionModifier, llvm::omp::Modifier::ReductionModifier)
+DECLARE_DESCRIPTOR(parser::OmpRefModifier, llvm::omp::Modifier::RefModifier)
+DECLARE_DESCRIPTOR(parser::OmpSelfModifier, llvm::omp::Modifier::SelfModifier)
+DECLARE_DESCRIPTOR(
+    parser::OmpStepComplexModifier, llvm::omp::Modifier::StepComplexModifier)
+DECLARE_DESCRIPTOR(
+    parser::OmpStepSimpleModifier, llvm::omp::Modifier::StepSimpleModifier)
+DECLARE_DESCRIPTOR(
+    parser::OmpTaskDependenceType, llvm::omp::Modifier::TaskDependenceType)
+DECLARE_DESCRIPTOR(
+    parser::OmpVariableCategory, llvm::omp::Modifier::VariableCategory)
+DECLARE_DESCRIPTOR(
+    parser::OmpxHoldModifier, llvm::omp::Modifier::OmpxHoldModifier)
 
 #undef DECLARE_DESCRIPTOR
 
@@ -140,7 +151,8 @@ DECLARE_DESCRIPTOR(parser::OmpxHoldModifier);
 //               "Specific2".
 
 template <typename UnionTy>
-const OmpModifierDescriptor &OmpGetDescriptor(const UnionTy &modifier) {
+const llvm::omp::descriptor::Modifier &OmpGetDescriptor(
+    const UnionTy &modifier) {
   return common::visit(
       [](auto &&m) -> decltype(auto) {
         using SpecificTy = llvm::remove_cvref_t<decltype(m)>;
@@ -281,18 +293,31 @@ bool verifyVersions(const std::optional<std::list<UnionTy>> &modifiers,
   unsigned version{semaCtx.langOptions().OpenMPVersion};
   bool result{true};
   for (auto &m : *modifiers) {
-    const OmpModifierDescriptor &desc{OmpGetDescriptor(m)};
-    unsigned since{desc.since(id)};
+    const llvm::omp::descriptor::Modifier &desc{OmpGetDescriptor(m)};
+    const auto &versions{desc.getVersions()};
+    if (llvm::is_contained(versions, std::max(version, 45u))) {
+      if (desc.getClauses(version).test(id)) {
+        continue;
+      }
+    }
+    // Find the next higher version that allows this modifier on this clause.
+    unsigned since{~0u};
+    for (unsigned v : versions) {
+      if (v > version && desc.getClauses(v).test(id)) {
+        since = v;
+        break;
+      }
+    }
     if (since == ~0u) {
       // This shouldn't really happen, but have it just in case.
       semaCtx.Say(m.source,
           "'%s' modifier is not supported on %s clause"_err_en_US,
-          desc.name.str(),
+          desc.getName().str(),
           parser::ToUpperCaseLetters(llvm::omp::getOpenMPClauseName(id)));
     } else if (version < since) {
       semaCtx.Say(m.source,
           "'%s' modifier is not supported in OpenMP v%d.%d, try -fopenmp-version=%d"_warn_en_US,
-          desc.name.str(), version / 10, version % 10, since);
+          desc.getName().str(), version / 10, version % 10, since);
       result = false;
     }
   }
@@ -308,8 +333,8 @@ bool verifyIfRequired(const SpecificTy *,
     const std::optional<std::list<UnionTy>> &modifiers,
     parser::CharBlock clauseSource, SemanticsContext &semaCtx) {
   unsigned version{semaCtx.langOptions().OpenMPVersion};
-  const OmpModifierDescriptor &desc{OmpGetDescriptor<SpecificTy>()};
-  if (!desc.props(version).test(OmpProperty::Required)) {
+  const llvm::omp::descriptor::Modifier &desc{OmpGetDescriptor<SpecificTy>()};
+  if (!desc.getProperties(version).test(llvm::omp::Property::Required)) {
     // If the modifier is not required, there is nothing to do.
     return true;
   }
@@ -318,8 +343,8 @@ bool verifyIfRequired(const SpecificTy *,
     return std::holds_alternative<SpecificTy>(m.u);
   });
   if (!present) {
-    semaCtx.Say(
-        clauseSource, "'%s' modifier is required"_err_en_US, desc.name.str());
+    semaCtx.Say(clauseSource, "'%s' modifier is required"_err_en_US,
+        desc.getName().str());
   }
   return present;
 }
@@ -362,10 +387,10 @@ bool verifyIfUnique(const SpecificTy *,
   assert(specific != end && "`specific` must be a valid location");
 
   unsigned version{semaCtx.langOptions().OpenMPVersion};
-  const OmpModifierDescriptor &desc{OmpGetDescriptor<SpecificTy>()};
+  const llvm::omp::descriptor::Modifier &desc{OmpGetDescriptor<SpecificTy>()};
   // Ultimate implies Unique.
-  if (!desc.props(version).test(OmpProperty::Unique) &&
-      !desc.props(version).test(OmpProperty::Ultimate)) {
+  if (!desc.getProperties(version).test(llvm::omp::Property::Unique) &&
+      !desc.getProperties(version).test(llvm::omp::Property::Ultimate)) {
     return true;
   }
   if (std::next(specific) != end) {
@@ -374,7 +399,7 @@ bool verifyIfUnique(const SpecificTy *,
     if (next != end) {
       semaCtx.Say(next->source,
           "'%s' modifier cannot occur multiple times"_err_en_US,
-          desc.name.str());
+          desc.getName().str());
     }
   }
   return true;
@@ -421,28 +446,30 @@ bool verifyUltimate(const std::optional<std::list<UnionTy>> &modifiers,
   // Walk over the list, and if a given item has the Ultimate property but is
   // not at the right position, mark it as an error.
   for (auto it{first}, end{modifiers->cend()}; it != end; ++it) {
-    result =
-        common::visit(
-            [&](auto &&m) {
-              using SpecificTy = llvm::remove_cvref_t<decltype(m)>;
-              const OmpModifierDescriptor &desc{OmpGetDescriptor<SpecificTy>()};
-              auto &props{desc.props(version)};
-
-              if (props.test(OmpProperty::Ultimate)) {
-                bool isPre = !props.test(OmpProperty::Post);
-                if (it == (isPre ? last : first)) {
-                  // Skip, since this is the correct place for this modifier.
-                  return true;
-                }
-                llvm::StringRef where{isPre ? "last" : "first"};
-                semaCtx.Say(it->source,
-                    "'%s' should be the %s modifier"_err_en_US, desc.name.str(),
-                    where.str());
-                return false;
-              }
-              return true;
-            },
-            it->u) &&
+    result = common::visit(
+                 [&](auto &&m) {
+                   using SpecificTy = llvm::remove_cvref_t<decltype(m)>;
+                   const llvm::omp::descriptor::Modifier &desc{
+                       OmpGetDescriptor<SpecificTy>()};
+                   const auto &props{desc.getProperties(version)};
+
+                   if (props.test(llvm::omp::Property::Ultimate)) {
+                     bool isPre = !llvm::omp::getProperties(id, version)
+                                       .test(llvm::omp::Property::PostModified);
+                     if (it == (isPre ? last : first)) {
+                       // Skip, since this is the correct place for this
+                       // modifier.
+                       return true;
+                     }
+                     llvm::StringRef where{isPre ? "last" : "first"};
+                     semaCtx.Say(it->source,
+                         "'%s' should be the %s modifier"_err_en_US,
+                         desc.getName().str(), where.str());
+                     return false;
+                   }
+                   return true;
+                 },
+                 it->u) &&
         result;
   }
   return result;
@@ -459,24 +486,24 @@ bool verifyExclusive(const std::optional<std::list<UnionTy>> &modifiers,
   }
   unsigned version{semaCtx.langOptions().OpenMPVersion};
   const UnionTy &front{modifiers->front()};
-  const OmpModifierDescriptor &frontDesc{OmpGetDescriptor(front)};
+  const llvm::omp::descriptor::Modifier &frontDesc{OmpGetDescriptor(front)};
 
   auto second{std::next(modifiers->cbegin())};
   auto end{modifiers->end()};
 
   auto emitErrorMessage{[&](const UnionTy &excl, const UnionTy &other) {
-    const OmpModifierDescriptor &descExcl{OmpGetDescriptor(excl)};
-    const OmpModifierDescriptor &descOther{OmpGetDescriptor(other)};
+    const llvm::omp::descriptor::Modifier &descExcl{OmpGetDescriptor(excl)};
+    const llvm::omp::descriptor::Modifier &descOther{OmpGetDescriptor(other)};
     parser::MessageFormattedText txt(
         "An exclusive '%s' modifier cannot be specified together with a modifier of a different type"_err_en_US,
-        descExcl.name.str());
+        descExcl.getName().str());
     parser::Message message(excl.source, txt);
     message.Attach(
-        other.source, "'%s' provided here"_en_US, descOther.name.str());
+        other.source, "'%s' provided here"_en_US, descOther.getName().str());
     semaCtx.Say(std::move(message));
   }};
 
-  if (frontDesc.props(version).test(OmpProperty::Exclusive)) {
+  if (frontDesc.getProperties(version).test(llvm::omp::Property::Exclusive)) {
     // If the first item has the Exclusive property, then check if there is
     // another item in the rest of the list with a different SpecificTy as
     // the alternative, and mark it as an error. This allows multiple Exclusive
@@ -497,8 +524,8 @@ bool verifyExclusive(const std::optional<std::list<UnionTy>> &modifiers,
     // mark it as an error if so.
     bool result{true};
     for (auto it{second}; it != end; ++it) {
-      const OmpModifierDescriptor &desc{OmpGetDescriptor(*it)};
-      if (desc.props(version).test(OmpProperty::Exclusive)) {
+      const llvm::omp::descriptor::Modifier &desc{OmpGetDescriptor(*it)};
+      if (desc.getProperties(version).test(llvm::omp::Property::Exclusive)) {
         emitErrorMessage(*it, front);
         result = false;
         break;
diff --git a/flang/lib/Semantics/CMakeLists.txt b/flang/lib/Semantics/CMakeLists.txt
index efe3c5fa875dc..649314a023704 100644
--- a/flang/lib/Semantics/CMakeLists.txt
+++ b/flang/lib/Semantics/CMakeLists.txt
@@ -36,7 +36,6 @@ add_flang_library(FortranSemantics
   expression.cpp
   mod-file.cpp
   openmp-dsa.cpp
-  openmp-modifiers.cpp
   openmp-utils.cpp
   pointer-assignment.cpp
   program-tree.cpp
diff --git a/flang/lib/Semantics/check-omp-loop.cpp b/flang/lib/Semantics/check-omp-loop.cpp
index 3c9cdfac450dc..f6a960dac67e6 100644
--- a/flang/lib/Semantics/check-omp-loop.cpp
+++ b/flang/lib/Semantics/check-omp-loop.cpp
@@ -735,7 +735,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Linear &x) {
       auto &desc{OmpGetDescriptor<parser::OmpLinearModifier>()};
       context_.Say(source,
           "The list item '%s' specified without the REF '%s' must be of INTEGER type"_err_en_US,
-          symbol->name(), desc.name.str());
+          symbol->name(), desc.getName().str());
     }
   }};
 
@@ -761,7 +761,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Linear &x) {
           if (dir != llvm::omp::Directive::OMPD_declare_simd) {
             context_.Say(modSource,
                 "A REF or UVAL '%s' may not be specified in a LINEAR clause on the %s directive"_err_en_US,
-                desc.name.str(), parser::omp::GetUpperName(dir, version));
+                desc.getName().str(), parser::omp::GetUpperName(dir, version));
             valid = false;
           }
         }
@@ -781,7 +781,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Linear &x) {
                 !IsPolymorphic(*symbol)) {
               context_.Say(source,
                   "The list item `%s` specified with the REF '%s' must be polymorphic variable, assumed-shape array, or a variable with the `ALLOCATABLE` attribute"_err_en_US,
-                  symbol->name(), desc.name.str());
+                  symbol->name(), desc.getName().str());
             }
           }
           if (linearMod->v == parser::OmpLinearModifier::Value::Ref ||
@@ -789,7 +789,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Linear &x) {
             if (!IsDummy(*symbol) || IsValue(*symbol)) {
               context_.Say(source,
                   "If the `%s` is REF or UVAL, the list item '%s' must be a dummy argument without the VALUE attribute"_err_en_US,
-                  desc.name.str(), symbol->name());
+                  desc.getName().str(), symbol->name());
             }
           }
         } // for (symbol, source)
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 93c7359efae27..02069dcc933e0 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -2130,19 +2130,20 @@ void OmpStructureChecker::CheckInitOnDepobj(
       auto &desc{OmpGetDescriptor<parser::OmpDepinfoModifier>()};
       context_.Say(OmpGetModifierSource(modifiers, depInfo),
           "'%s' is not an allowed value of the '%s' modifier"_err_en_US,
-          parser::ToUpperCaseLetters(EnumToString(depKind)), desc.name.str());
+          parser::ToUpperCaseLetters(EnumToString(depKind)),
+          desc.getName().str());
     }
   } else {
     auto &desc{OmpGetDescriptor<parser::OmpDepinfoModifier>()};
     context_.Say(initClause.source,
         "The '%s' modifier is required on a DEPOBJ construct"_err_en_US,
-        desc.name.str());
+        desc.getName().str());
   }
   if (auto *prefType{OmpGetUniqueModifier<parser::OmpPreferType>(modifiers)}) {
     auto &desc{OmpGetDescriptor<parser::OmpPreferType>()};
     context_.Say(OmpGetModifierSource(modifiers, prefType),
         "The '%s' modifier is not allowed on a DEPOBJ construct"_err_en_US,
-        desc.name.str());
+        de...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/215648


More information about the flang-commits mailing list