[llvm-branch-commits] [flang] [flang][OpenMP] Pass OpenMP version to getOpenMPDirectiveName (PR #139131)

Krzysztof Parzyszek via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu May 8 12:13:03 PDT 2025


https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/139131

>From 9566bf6fd60d2b4f1dac86f6646002b2541e6736 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Wed, 7 May 2025 15:32:28 -0500
Subject: [PATCH 1/4] [flang][OpenMP] Pass OpenMP version to
 getOpenMPDirectiveName

The OpenMP version is stored in LangOptions in SemanticsContext. Use the
fallback version where SemanticsContext is unavailable (mostly in case of
debug dumps).

RFC: https://discourse.llvm.org/t/rfc-alternative-spellings-of-openmp-directives/85507
---
 .../FlangOmpReport/FlangOmpReportVisitor.cpp  |  5 ++-
 flang/include/flang/Parser/dump-parse-tree.h  |  5 ++-
 flang/include/flang/Parser/unparse.h          |  7 ++++
 .../flang/Semantics/unparse-with-symbols.h    |  5 +++
 flang/lib/Frontend/ParserActions.cpp          |  3 +-
 flang/lib/Lower/OpenMP/ClauseProcessor.h      |  4 +-
 flang/lib/Lower/OpenMP/Decomposer.cpp         |  3 +-
 flang/lib/Lower/OpenMP/OpenMP.cpp             |  6 ++-
 flang/lib/Parser/openmp-parsers.cpp           |  3 +-
 flang/lib/Parser/parse-tree.cpp               |  5 ++-
 flang/lib/Parser/unparse.cpp                  | 39 ++++++++++++-------
 flang/lib/Semantics/check-omp-structure.cpp   | 18 ++++-----
 flang/lib/Semantics/mod-file.cpp              | 11 +++---
 flang/lib/Semantics/resolve-directives.cpp    | 25 +++++++-----
 flang/lib/Semantics/unparse-with-symbols.cpp  |  6 +--
 15 files changed, 93 insertions(+), 52 deletions(-)

diff --git a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp
index dbbf86a6c6151..bf66151d59950 100644
--- a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp
+++ b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp
@@ -267,8 +267,9 @@ void OpenMPCounterVisitor::Post(const OmpScheduleClause::Kind &c) {
       "type=" + std::string{OmpScheduleClause::EnumToString(c)} + ";";
 }
 void OpenMPCounterVisitor::Post(const OmpDirectiveNameModifier &c) {
-  clauseDetails +=
-      "name_modifier=" + llvm::omp::getOpenMPDirectiveName(c.v).str() + ";";
+  clauseDetails += "name_modifier=" +
+      llvm::omp::getOpenMPDirectiveName(c.v, llvm::omp::FallbackVersion).str() +
+      ";";
 }
 void OpenMPCounterVisitor::Post(const OmpClause &c) {
   PostClauseCommon(normalize_clause_name(c.source.ToString()));
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index a3721bc8410ba..df9278697346f 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -17,6 +17,7 @@
 #include "flang/Common/idioms.h"
 #include "flang/Common/indirection.h"
 #include "flang/Support/Fortran.h"
+#include "llvm/Frontend/OpenMP/OMP.h"
 #include "llvm/Support/raw_ostream.h"
 #include <string>
 #include <type_traits>
@@ -545,8 +546,8 @@ class ParseTreeDumper {
   NODE(parser, OmpBeginSectionsDirective)
   NODE(parser, OmpBlockDirective)
   static std::string GetNodeName(const llvm::omp::Directive &x) {
-    return llvm::Twine(
-        "llvm::omp::Directive = ", llvm::omp::getOpenMPDirectiveName(x))
+    return llvm::Twine("llvm::omp::Directive = ",
+        llvm::omp::getOpenMPDirectiveName(x, llvm::omp::FallbackVersion))
         .str();
   }
   NODE(parser, OmpClause)
diff --git a/flang/include/flang/Parser/unparse.h b/flang/include/flang/Parser/unparse.h
index 40094ecbc85e5..349597213d904 100644
--- a/flang/include/flang/Parser/unparse.h
+++ b/flang/include/flang/Parser/unparse.h
@@ -18,6 +18,10 @@ namespace llvm {
 class raw_ostream;
 }
 
+namespace Fortran::common {
+class LangOptions;
+}
+
 namespace Fortran::evaluate {
 struct GenericExprWrapper;
 struct GenericAssignmentWrapper;
@@ -47,14 +51,17 @@ struct AnalyzedObjectsAsFortran {
 // Converts parsed program (or fragment) to out as Fortran.
 template <typename A>
 void Unparse(llvm::raw_ostream &out, const A &root,
+    const common::LangOptions &langOpts,
     Encoding encoding = Encoding::UTF_8, bool capitalizeKeywords = true,
     bool backslashEscapes = true, preStatementType *preStatement = nullptr,
     AnalyzedObjectsAsFortran * = nullptr);
 
 extern template void Unparse(llvm::raw_ostream &out, const Program &program,
+    const common::LangOptions &langOpts,
     Encoding encoding, bool capitalizeKeywords, bool backslashEscapes,
     preStatementType *preStatement, AnalyzedObjectsAsFortran *);
 extern template void Unparse(llvm::raw_ostream &out, const Expr &expr,
+    const common::LangOptions &langOpts,
     Encoding encoding, bool capitalizeKeywords, bool backslashEscapes,
     preStatementType *preStatement, AnalyzedObjectsAsFortran *);
 } // namespace Fortran::parser
diff --git a/flang/include/flang/Semantics/unparse-with-symbols.h b/flang/include/flang/Semantics/unparse-with-symbols.h
index 5e18b3fc3063d..702911bbab627 100644
--- a/flang/include/flang/Semantics/unparse-with-symbols.h
+++ b/flang/include/flang/Semantics/unparse-with-symbols.h
@@ -16,6 +16,10 @@ namespace llvm {
 class raw_ostream;
 }
 
+namespace Fortran::common {
+class LangOptions;
+}
+
 namespace Fortran::parser {
 struct Program;
 }
@@ -23,6 +27,7 @@ struct Program;
 namespace Fortran::semantics {
 class SemanticsContext;
 void UnparseWithSymbols(llvm::raw_ostream &, const parser::Program &,
+    const common::LangOptions &,
     parser::Encoding encoding = parser::Encoding::UTF_8);
 void UnparseWithModules(llvm::raw_ostream &, SemanticsContext &,
     const parser::Program &,
diff --git a/flang/lib/Frontend/ParserActions.cpp b/flang/lib/Frontend/ParserActions.cpp
index cc7e72f696f96..4fe575b06d29f 100644
--- a/flang/lib/Frontend/ParserActions.cpp
+++ b/flang/lib/Frontend/ParserActions.cpp
@@ -119,7 +119,7 @@ void debugUnparseNoSema(CompilerInstance &ci, llvm::raw_ostream &out) {
   auto &parseTree{ci.getParsing().parseTree()};
 
   // TODO: Options should come from CompilerInvocation
-  Unparse(out, *parseTree,
+  Unparse(out, *parseTree, ci.getInvocation().getLangOpts(),
           /*encoding=*/parser::Encoding::UTF_8,
           /*capitalizeKeywords=*/true, /*backslashEscapes=*/false,
           /*preStatement=*/nullptr,
@@ -131,6 +131,7 @@ void debugUnparseWithSymbols(CompilerInstance &ci) {
   auto &parseTree{*ci.getParsing().parseTree()};
 
   semantics::UnparseWithSymbols(llvm::outs(), parseTree,
+                                ci.getInvocation().getLangOpts(),
                                 /*encoding=*/parser::Encoding::UTF_8);
 }
 
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h
index 3d3f26f06da26..593c9f478c73e 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.h
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h
@@ -196,9 +196,11 @@ void ClauseProcessor::processTODO(mlir::Location currentLocation,
   auto checkUnhandledClause = [&](llvm::omp::Clause id, const auto *x) {
     if (!x)
       return;
+    unsigned version = semaCtx.langOptions().OpenMPVersion;
     TODO(currentLocation,
          "Unhandled clause " + llvm::omp::getOpenMPClauseName(id).upper() +
-             " in " + llvm::omp::getOpenMPDirectiveName(directive).upper() +
+             " in " +
+             llvm::omp::getOpenMPDirectiveName(directive, version).upper() +
              " construct");
   };
 
diff --git a/flang/lib/Lower/OpenMP/Decomposer.cpp b/flang/lib/Lower/OpenMP/Decomposer.cpp
index 33568bf96b5df..0c7f485d94820 100644
--- a/flang/lib/Lower/OpenMP/Decomposer.cpp
+++ b/flang/lib/Lower/OpenMP/Decomposer.cpp
@@ -16,6 +16,7 @@
 #include "Utils.h"
 #include "flang/Lower/PFTBuilder.h"
 #include "flang/Semantics/semantics.h"
+#include "flang/Support/LangOptions.h"
 #include "flang/Tools/CrossToolHelpers.h"
 #include "mlir/IR/BuiltinOps.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -70,7 +71,7 @@ struct ConstructDecomposition {
 namespace Fortran::lower::omp {
 LLVM_DUMP_METHOD llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
                                                const UnitConstruct &uc) {
-  os << llvm::omp::getOpenMPDirectiveName(uc.id);
+  os << llvm::omp::getOpenMPDirectiveName(uc.id, llvm::omp::FallbackVersion);
   for (auto [index, clause] : llvm::enumerate(uc.clauses)) {
     os << (index == 0 ? '\t' : ' ');
     os << llvm::omp::getOpenMPClauseName(clause.id);
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 099d5c604060f..efdf5c6f545fe 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -3751,9 +3751,11 @@ static void genOMPDispatch(lower::AbstractConverter &converter,
                        item);
     break;
   case llvm::omp::Directive::OMPD_tile:
-  case llvm::omp::Directive::OMPD_unroll:
+  case llvm::omp::Directive::OMPD_unroll: {
+    unsigned version = semaCtx.langOptions().OpenMPVersion;
     TODO(loc, "Unhandled loop directive (" +
-                  llvm::omp::getOpenMPDirectiveName(dir) + ")");
+                  llvm::omp::getOpenMPDirectiveName(dir, version) + ")");
+  }
   // case llvm::omp::Directive::OMPD_workdistribute:
   case llvm::omp::Directive::OMPD_workshare:
     newOp = genWorkshareOp(converter, symTable, stmtCtx, semaCtx, eval, loc,
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index c4728e0fabe61..ffee57144f7fb 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -125,7 +125,8 @@ OmpDirectiveNameParser::directives() const {
 void OmpDirectiveNameParser::initTokens(NameWithId *table) const {
   for (size_t i{0}, e{llvm::omp::Directive_enumSize}; i != e; ++i) {
     auto id{static_cast<llvm::omp::Directive>(i)};
-    llvm::StringRef name{llvm::omp::getOpenMPDirectiveName(id)};
+    llvm::StringRef name{
+        llvm::omp::getOpenMPDirectiveName(id, llvm::omp::FallbackVersion)};
     table[i] = std::make_pair(name.str(), id);
   }
   // Sort the table with respect to the directive name length in a descending
diff --git a/flang/lib/Parser/parse-tree.cpp b/flang/lib/Parser/parse-tree.cpp
index 5839e7862b38b..3dd87ad9a3650 100644
--- a/flang/lib/Parser/parse-tree.cpp
+++ b/flang/lib/Parser/parse-tree.cpp
@@ -11,6 +11,7 @@
 #include "flang/Common/indirection.h"
 #include "flang/Parser/tools.h"
 #include "flang/Parser/user-state.h"
+#include "llvm/Frontend/OpenMP/OMP.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
 
@@ -305,7 +306,9 @@ std::string OmpTraitSelectorName::ToString() const {
             return std::string(EnumToString(v));
           },
           [&](llvm::omp::Directive d) {
-            return llvm::omp::getOpenMPDirectiveName(d).str();
+            return llvm::omp::getOpenMPDirectiveName(
+                d, llvm::omp::FallbackVersion)
+                .str();
           },
           [&](const std::string &s) { //
             return s;
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 1ee9096fcda56..3747665f6320b 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -17,6 +17,7 @@
 #include "flang/Parser/parse-tree.h"
 #include "flang/Parser/tools.h"
 #include "flang/Support/Fortran.h"
+#include "flang/Support/LangOptions.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
 #include <cinttypes>
@@ -27,12 +28,14 @@ namespace Fortran::parser {
 
 class UnparseVisitor {
 public:
-  UnparseVisitor(llvm::raw_ostream &out, int indentationAmount,
-      Encoding encoding, bool capitalize, bool backslashEscapes,
-      preStatementType *preStatement, AnalyzedObjectsAsFortran *asFortran)
-      : out_{out}, indentationAmount_{indentationAmount}, encoding_{encoding},
-        capitalizeKeywords_{capitalize}, backslashEscapes_{backslashEscapes},
-        preStatement_{preStatement}, asFortran_{asFortran} {}
+  UnparseVisitor(llvm::raw_ostream &out, const common::LangOptions &langOpts,
+      int indentationAmount, Encoding encoding, bool capitalize,
+      bool backslashEscapes, preStatementType *preStatement,
+      AnalyzedObjectsAsFortran *asFortran)
+      : out_{out}, langOpts_{langOpts}, indentationAmount_{indentationAmount},
+        encoding_{encoding}, capitalizeKeywords_{capitalize},
+        backslashEscapes_{backslashEscapes}, preStatement_{preStatement},
+        asFortran_{asFortran} {}
 
   // In nearly all cases, this code avoids defining Boolean-valued Pre()
   // callbacks for the parse tree walking framework in favor of two void
@@ -2102,7 +2105,8 @@ class UnparseVisitor {
     Walk(":", std::get<std::optional<OmpReductionCombiner>>(x.t));
   }
   void Unparse(const llvm::omp::Directive &x) {
-    Word(llvm::omp::getOpenMPDirectiveName(x).str());
+    unsigned OMPVersion{langOpts_.OpenMPVersion};
+    Word(llvm::omp::getOpenMPDirectiveName(x, OMPVersion).str());
   }
   void Unparse(const OmpDirectiveSpecification &x) {
     auto unparseArgs{[&]() {
@@ -2167,7 +2171,8 @@ class UnparseVisitor {
         x.u);
   }
   void Unparse(const OmpDirectiveNameModifier &x) {
-    Word(llvm::omp::getOpenMPDirectiveName(x.v));
+    unsigned OMPVersion{langOpts_.OpenMPVersion};
+    Word(llvm::omp::getOpenMPDirectiveName(x.v, OMPVersion));
   }
   void Unparse(const OmpIteratorSpecifier &x) {
     Walk(std::get<TypeDeclarationStmt>(x.t));
@@ -3249,6 +3254,7 @@ class UnparseVisitor {
   }
 
   llvm::raw_ostream &out_;
+  const common::LangOptions &langOpts_;
   int indent_{0};
   const int indentationAmount_{1};
   int column_{1};
@@ -3341,17 +3347,20 @@ void UnparseVisitor::Word(const std::string_view &str) {
 }
 
 template <typename A>
-void Unparse(llvm::raw_ostream &out, const A &root, Encoding encoding,
+void Unparse(llvm::raw_ostream &out, const A &root,
+    const common::LangOptions &langOpts, Encoding encoding,
     bool capitalizeKeywords, bool backslashEscapes,
     preStatementType *preStatement, AnalyzedObjectsAsFortran *asFortran) {
-  UnparseVisitor visitor{out, 1, encoding, capitalizeKeywords, backslashEscapes,
-      preStatement, asFortran};
+  UnparseVisitor visitor{out, langOpts, 1, encoding, capitalizeKeywords,
+      backslashEscapes, preStatement, asFortran};
   Walk(root, visitor);
   visitor.Done();
 }
 
-template void Unparse<Program>(llvm::raw_ostream &, const Program &, Encoding,
-    bool, bool, preStatementType *, AnalyzedObjectsAsFortran *);
-template void Unparse<Expr>(llvm::raw_ostream &, const Expr &, Encoding, bool,
-    bool, preStatementType *, AnalyzedObjectsAsFortran *);
+template void Unparse<Program>(llvm::raw_ostream &, const Program &,
+    const common::LangOptions &, Encoding, bool, bool, preStatementType *,
+    AnalyzedObjectsAsFortran *);
+template void Unparse<Expr>(llvm::raw_ostream &, const Expr &,
+    const common::LangOptions &, Encoding, bool, bool, preStatementType *,
+    AnalyzedObjectsAsFortran *);
 } // namespace Fortran::parser
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index f17de42ca2466..f2c1197097f09 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -2434,8 +2434,7 @@ void OmpStructureChecker::Enter(
     break;
   default:
     context_.Say(dirName.source, "%s is not a cancellable construct"_err_en_US,
-        parser::ToUpperCaseLetters(
-            llvm::omp::getOpenMPDirectiveName(dirName.v).str()));
+        parser::ToUpperCaseLetters(getDirectiveName(dirName.v).str()));
     break;
   }
 }
@@ -2468,7 +2467,7 @@ std::optional<llvm::omp::Directive> OmpStructureChecker::GetCancelType(
   // Given clauses from CANCEL or CANCELLATION_POINT, identify the construct
   // to which the cancellation applies.
   std::optional<llvm::omp::Directive> cancelee;
-  llvm::StringRef cancelName{llvm::omp::getOpenMPDirectiveName(cancelDir)};
+  llvm::StringRef cancelName{getDirectiveName(cancelDir)};
 
   for (const parser::OmpClause &clause : maybeClauses->v) {
     using CancellationConstructType =
@@ -2496,7 +2495,7 @@ std::optional<llvm::omp::Directive> OmpStructureChecker::GetCancelType(
 
 void OmpStructureChecker::CheckCancellationNest(
     const parser::CharBlock &source, llvm::omp::Directive type) {
-  llvm::StringRef typeName{llvm::omp::getOpenMPDirectiveName(type)};
+  llvm::StringRef typeName{getDirectiveName(type)};
 
   if (CurrentDirectiveIsNested()) {
     // If construct-type-clause is taskgroup, the cancellation construct must be
@@ -4002,10 +4001,10 @@ void OmpStructureChecker::Enter(const parser::OmpClause::If &x) {
     if (auto *dnm{OmpGetUniqueModifier<parser::OmpDirectiveNameModifier>(
             modifiers)}) {
       llvm::omp::Directive sub{dnm->v};
-      std::string subName{parser::ToUpperCaseLetters(
-          llvm::omp::getOpenMPDirectiveName(sub).str())};
-      std::string dirName{parser::ToUpperCaseLetters(
-          llvm::omp::getOpenMPDirectiveName(dir).str())};
+      std::string subName{
+          parser::ToUpperCaseLetters(getDirectiveName(sub).str())};
+      std::string dirName{
+          parser::ToUpperCaseLetters(getDirectiveName(dir).str())};
 
       parser::CharBlock modifierSource{OmpGetModifierSource(modifiers, dnm)};
       auto desc{OmpGetDescriptor<parser::OmpDirectiveNameModifier>()};
@@ -5348,7 +5347,8 @@ llvm::StringRef OmpStructureChecker::getClauseName(llvm::omp::Clause clause) {
 
 llvm::StringRef OmpStructureChecker::getDirectiveName(
     llvm::omp::Directive directive) {
-  return llvm::omp::getOpenMPDirectiveName(directive);
+  unsigned version{context_.langOptions().OpenMPVersion};
+  return llvm::omp::getOpenMPDirectiveName(directive, version);
 }
 
 const Symbol *OmpStructureChecker::GetObjectSymbol(
diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp
index ee356e56e4458..12fc553518cfd 100644
--- a/flang/lib/Semantics/mod-file.cpp
+++ b/flang/lib/Semantics/mod-file.cpp
@@ -50,7 +50,7 @@ static void CollectSymbols(
     const Scope &, SymbolVector &, SymbolVector &, SourceOrderedSymbolSet &);
 static void PutPassName(llvm::raw_ostream &, const std::optional<SourceName> &);
 static void PutInit(llvm::raw_ostream &, const Symbol &, const MaybeExpr &,
-    const parser::Expr *);
+    const parser::Expr *, SemanticsContext &);
 static void PutInit(llvm::raw_ostream &, const MaybeIntExpr &);
 static void PutBound(llvm::raw_ostream &, const Bound &);
 static void PutShapeSpec(llvm::raw_ostream &, const ShapeSpec &);
@@ -605,7 +605,7 @@ void ModFileWriter::PutDECStructure(
         }
         decls_ << ref->name();
         PutShape(decls_, object->shape(), '(', ')');
-        PutInit(decls_, *ref, object->init(), nullptr);
+        PutInit(decls_, *ref, object->init(), nullptr, context_);
         emittedDECFields_.insert(*ref);
       } else if (any) {
         break; // any later use of this structure will use RECORD/str/
@@ -944,7 +944,8 @@ void ModFileWriter::PutObjectEntity(
       getSymbolAttrsToWrite(symbol));
   PutShape(os, details.shape(), '(', ')');
   PutShape(os, details.coshape(), '[', ']');
-  PutInit(os, symbol, details.init(), details.unanalyzedPDTComponentInit());
+  PutInit(os, symbol, details.init(), details.unanalyzedPDTComponentInit(),
+      context_);
   os << '\n';
   if (auto tkr{GetIgnoreTKR(symbol)}; !tkr.empty()) {
     os << "!dir$ ignore_tkr(";
@@ -1036,11 +1037,11 @@ void ModFileWriter::PutTypeParam(llvm::raw_ostream &os, const Symbol &symbol) {
 }
 
 void PutInit(llvm::raw_ostream &os, const Symbol &symbol, const MaybeExpr &init,
-    const parser::Expr *unanalyzed) {
+    const parser::Expr *unanalyzed, SemanticsContext &context) {
   if (IsNamedConstant(symbol) || symbol.owner().IsDerivedType()) {
     const char *assign{symbol.attrs().test(Attr::POINTER) ? "=>" : "="};
     if (unanalyzed) {
-      parser::Unparse(os << assign, *unanalyzed);
+      parser::Unparse(os << assign, *unanalyzed, context.langOptions());
     } else if (init) {
       init->AsFortran(os << assign);
     }
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 8b1caca34a6a7..60531538e6d59 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1887,6 +1887,7 @@ std::int64_t OmpAttributeVisitor::GetAssociatedLoopLevelFromClauses(
 //     construct with multiple associated do-loops are lastprivate.
 void OmpAttributeVisitor::PrivatizeAssociatedLoopIndexAndCheckLoopLevel(
     const parser::OpenMPLoopConstruct &x) {
+  unsigned version{context_.langOptions().OpenMPVersion};
   std::int64_t level{GetContext().associatedLoopLevel};
   if (level <= 0) {
     return;
@@ -1922,7 +1923,8 @@ void OmpAttributeVisitor::PrivatizeAssociatedLoopIndexAndCheckLoopLevel(
     context_.Say(GetContext().directiveSource,
         "A DO loop must follow the %s directive"_err_en_US,
         parser::ToUpperCaseLetters(
-            llvm::omp::getOpenMPDirectiveName(GetContext().directive).str()));
+            llvm::omp::getOpenMPDirectiveName(GetContext().directive, version)
+                .str()));
   }
 }
 void OmpAttributeVisitor::CheckAssocLoopLevel(
@@ -2442,6 +2444,7 @@ static bool SymbolOrEquivalentIsInNamelist(const Symbol &symbol) {
 
 void OmpAttributeVisitor::ResolveOmpObject(
     const parser::OmpObject &ompObject, Symbol::Flag ompFlag) {
+  unsigned version{context_.langOptions().OpenMPVersion};
   common::visit(
       common::visitors{
           [&](const parser::Designator &designator) {
@@ -2464,7 +2467,7 @@ void OmpAttributeVisitor::ResolveOmpObject(
                             Symbol::OmpFlagToClauseName(secondOmpFlag),
                             parser::ToUpperCaseLetters(
                                 llvm::omp::getOpenMPDirectiveName(
-                                    GetContext().directive)
+                                    GetContext().directive, version)
                                     .str()));
                       }
                     };
@@ -2500,7 +2503,7 @@ void OmpAttributeVisitor::ResolveOmpObject(
                       "in which the %s directive appears"_err_en_US,
                       parser::ToUpperCaseLetters(
                           llvm::omp::getOpenMPDirectiveName(
-                              GetContext().directive)
+                              GetContext().directive, version)
                               .str()));
                 }
                 if (ompFlag == Symbol::Flag::OmpReduction) {
@@ -2924,6 +2927,7 @@ void OmpAttributeVisitor::CheckSourceLabel(const parser::Label &label) {
 void OmpAttributeVisitor::CheckLabelContext(const parser::CharBlock source,
     const parser::CharBlock target, std::optional<DirContext> sourceContext,
     std::optional<DirContext> targetContext) {
+  unsigned version{context_.langOptions().OpenMPVersion};
   if (targetContext &&
       (!sourceContext ||
           (sourceContext->scope != targetContext->scope &&
@@ -2932,8 +2936,8 @@ void OmpAttributeVisitor::CheckLabelContext(const parser::CharBlock source,
     context_
         .Say(source, "invalid branch into an OpenMP structured block"_err_en_US)
         .Attach(target, "In the enclosing %s directive branched into"_en_US,
-            parser::ToUpperCaseLetters(
-                llvm::omp::getOpenMPDirectiveName(targetContext->directive)
+            parser::ToUpperCaseLetters(llvm::omp::getOpenMPDirectiveName(
+                targetContext->directive, version)
                     .str()));
   }
   if (sourceContext &&
@@ -2945,8 +2949,8 @@ void OmpAttributeVisitor::CheckLabelContext(const parser::CharBlock source,
         .Say(source,
             "invalid branch leaving an OpenMP structured block"_err_en_US)
         .Attach(target, "Outside the enclosing %s directive"_en_US,
-            parser::ToUpperCaseLetters(
-                llvm::omp::getOpenMPDirectiveName(sourceContext->directive)
+            parser::ToUpperCaseLetters(llvm::omp::getOpenMPDirectiveName(
+                sourceContext->directive, version)
                     .str()));
   }
 }
@@ -2979,12 +2983,14 @@ void OmpAttributeVisitor::CheckNameInAllocateStmt(
       }
     }
   }
+  unsigned version{context_.langOptions().OpenMPVersion};
   context_.Say(source,
       "Object '%s' in %s directive not "
       "found in corresponding ALLOCATE statement"_err_en_US,
       name.ToString(),
       parser::ToUpperCaseLetters(
-          llvm::omp::getOpenMPDirectiveName(GetContext().directive).str()));
+          llvm::omp::getOpenMPDirectiveName(GetContext().directive, version)
+              .str()));
 }
 
 void OmpAttributeVisitor::AddOmpRequiresToScope(Scope &scope,
@@ -3030,9 +3036,10 @@ void OmpAttributeVisitor::IssueNonConformanceWarning(
     llvm::omp::Directive D, parser::CharBlock source) {
   std::string warnStr;
   llvm::raw_string_ostream warnStrOS(warnStr);
+  unsigned version{context_.langOptions().OpenMPVersion};
   warnStrOS << "OpenMP directive "
             << parser::ToUpperCaseLetters(
-                   llvm::omp::getOpenMPDirectiveName(D).str())
+                   llvm::omp::getOpenMPDirectiveName(D, version).str())
             << " has been deprecated";
 
   auto setAlternativeStr = [&warnStrOS](llvm::StringRef alt) {
diff --git a/flang/lib/Semantics/unparse-with-symbols.cpp b/flang/lib/Semantics/unparse-with-symbols.cpp
index 2716d88efb9fb..634d46b8ccf40 100644
--- a/flang/lib/Semantics/unparse-with-symbols.cpp
+++ b/flang/lib/Semantics/unparse-with-symbols.cpp
@@ -107,13 +107,13 @@ void SymbolDumpVisitor::Post(const parser::Name &name) {
 }
 
 void UnparseWithSymbols(llvm::raw_ostream &out, const parser::Program &program,
-    parser::Encoding encoding) {
+    const common::LangOptions &langOpts, parser::Encoding encoding) {
   SymbolDumpVisitor visitor;
   parser::Walk(program, visitor);
   parser::preStatementType preStatement{
       [&](const parser::CharBlock &location, llvm::raw_ostream &out,
           int indent) { visitor.PrintSymbols(location, out, indent); }};
-  parser::Unparse(out, program, encoding, false, true, &preStatement);
+  parser::Unparse(out, program, langOpts, encoding, false, true, &preStatement);
 }
 
 // UnparseWithModules()
@@ -150,6 +150,6 @@ void UnparseWithModules(llvm::raw_ostream &out, SemanticsContext &context,
   for (SymbolRef moduleRef : visitor.modulesUsed()) {
     writer.WriteClosure(out, *moduleRef, nonIntrinsicModulesWritten);
   }
-  parser::Unparse(out, program, encoding, false, true);
+  parser::Unparse(out, program, context.langOptions(), encoding, false, true);
 }
 } // namespace Fortran::semantics

>From 9a45513089d39b480eefe853371eb0ab3062e037 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Thu, 8 May 2025 14:06:08 -0500
Subject: [PATCH 2/4] Remove leftover include

---
 flang/lib/Lower/OpenMP/Decomposer.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/flang/lib/Lower/OpenMP/Decomposer.cpp b/flang/lib/Lower/OpenMP/Decomposer.cpp
index 0c7f485d94820..251cba9204adc 100644
--- a/flang/lib/Lower/OpenMP/Decomposer.cpp
+++ b/flang/lib/Lower/OpenMP/Decomposer.cpp
@@ -16,7 +16,6 @@
 #include "Utils.h"
 #include "flang/Lower/PFTBuilder.h"
 #include "flang/Semantics/semantics.h"
-#include "flang/Support/LangOptions.h"
 #include "flang/Tools/CrossToolHelpers.h"
 #include "mlir/IR/BuiltinOps.h"
 #include "llvm/ADT/ArrayRef.h"

>From 808a15f6a6085badf9d49fd5557356378c2ca9d4 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Thu, 8 May 2025 14:08:40 -0500
Subject: [PATCH 3/4] OMPVersion -> ompVersion in unparse.cpp

---
 flang/lib/Parser/unparse.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 3747665f6320b..a626888b7dfe5 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2105,8 +2105,8 @@ class UnparseVisitor {
     Walk(":", std::get<std::optional<OmpReductionCombiner>>(x.t));
   }
   void Unparse(const llvm::omp::Directive &x) {
-    unsigned OMPVersion{langOpts_.OpenMPVersion};
-    Word(llvm::omp::getOpenMPDirectiveName(x, OMPVersion).str());
+    unsigned ompVersion{langOpts_.OpenMPVersion};
+    Word(llvm::omp::getOpenMPDirectiveName(x, ompVersion).str());
   }
   void Unparse(const OmpDirectiveSpecification &x) {
     auto unparseArgs{[&]() {
@@ -2171,8 +2171,8 @@ class UnparseVisitor {
         x.u);
   }
   void Unparse(const OmpDirectiveNameModifier &x) {
-    unsigned OMPVersion{langOpts_.OpenMPVersion};
-    Word(llvm::omp::getOpenMPDirectiveName(x.v, OMPVersion));
+    unsigned ompVersion{langOpts_.OpenMPVersion};
+    Word(llvm::omp::getOpenMPDirectiveName(x.v, ompVersion));
   }
   void Unparse(const OmpIteratorSpecifier &x) {
     Walk(std::get<TypeDeclarationStmt>(x.t));

>From d3a32ff82f43f0b936177434c4c812d84b2b7769 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Thu, 8 May 2025 14:12:50 -0500
Subject: [PATCH 4/4] format

---
 flang/include/flang/Parser/unparse.h | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/flang/include/flang/Parser/unparse.h b/flang/include/flang/Parser/unparse.h
index 349597213d904..d796109ca8f86 100644
--- a/flang/include/flang/Parser/unparse.h
+++ b/flang/include/flang/Parser/unparse.h
@@ -51,18 +51,18 @@ struct AnalyzedObjectsAsFortran {
 // Converts parsed program (or fragment) to out as Fortran.
 template <typename A>
 void Unparse(llvm::raw_ostream &out, const A &root,
-    const common::LangOptions &langOpts,
-    Encoding encoding = Encoding::UTF_8, bool capitalizeKeywords = true,
-    bool backslashEscapes = true, preStatementType *preStatement = nullptr,
+    const common::LangOptions &langOpts, Encoding encoding = Encoding::UTF_8,
+    bool capitalizeKeywords = true, bool backslashEscapes = true,
+    preStatementType *preStatement = nullptr,
     AnalyzedObjectsAsFortran * = nullptr);
 
 extern template void Unparse(llvm::raw_ostream &out, const Program &program,
-    const common::LangOptions &langOpts,
-    Encoding encoding, bool capitalizeKeywords, bool backslashEscapes,
+    const common::LangOptions &langOpts, Encoding encoding,
+    bool capitalizeKeywords, bool backslashEscapes,
     preStatementType *preStatement, AnalyzedObjectsAsFortran *);
 extern template void Unparse(llvm::raw_ostream &out, const Expr &expr,
-    const common::LangOptions &langOpts,
-    Encoding encoding, bool capitalizeKeywords, bool backslashEscapes,
+    const common::LangOptions &langOpts, Encoding encoding,
+    bool capitalizeKeywords, bool backslashEscapes,
     preStatementType *preStatement, AnalyzedObjectsAsFortran *);
 } // namespace Fortran::parser
 



More information about the llvm-branch-commits mailing list