[flang-commits] [flang] [flang][OpenMP] Utilities to get uppercase directive/clause names (PR #184853)
Krzysztof Parzyszek via flang-commits
flang-commits at lists.llvm.org
Thu Mar 5 10:52:13 PST 2026
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/184853
>From dde5e79b097cd95f644ec187f5183c0d455c3a97 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Thu, 5 Mar 2026 10:23:33 -0600
Subject: [PATCH 1/2] [flang][OpenMP] Utilities to get uppercase
directive/clause names
It is a convention to use uppercase names of directives and clauses in
diagnostic messages, but getting such names is somewhat cumbersome:
```
parser::ToUpperCaseLetters(llvm::omp::getOpenMPDirectiveName(dirId));
parser::ToUpperCaseLetters(llvm::omp::getOpenMPClauseName(clauseId));
```
Implement `GetUpperName` (overloaded for clauses and directives) to
shorten it to
```
GetUpperName(dirId, version);
GetUpperName(clauseId, version);
```
This patch replaces existing instances of this pattern, adding the
use of OpenMP version where it was previously missing.
---
flang/include/flang/Parser/openmp-utils.h | 3 +
flang/lib/Lower/OpenMP/OpenMP.cpp | 8 +-
flang/lib/Parser/openmp-utils.cpp | 12 ++
flang/lib/Semantics/check-omp-loop.cpp | 5 +-
flang/lib/Semantics/check-omp-structure.cpp | 152 ++++++++++----------
flang/lib/Semantics/resolve-directives.cpp | 22 ++-
6 files changed, 106 insertions(+), 96 deletions(-)
diff --git a/flang/include/flang/Parser/openmp-utils.h b/flang/include/flang/Parser/openmp-utils.h
index 6cfaf8bb21712..b8fb6078d59a5 100644
--- a/flang/include/flang/Parser/openmp-utils.h
+++ b/flang/include/flang/Parser/openmp-utils.h
@@ -113,6 +113,9 @@ template <typename T> OmpDirectiveName GetOmpDirectiveName(const T &x) {
return detail::DirectiveNameScope::GetOmpDirectiveName(x);
}
+std::string GetUpperName(llvm::omp::Clause id, unsigned version);
+std::string GetUpperName(llvm::omp::Directive id, unsigned version);
+
const OpenMPDeclarativeConstruct *GetOmp(const DeclarationConstruct &x);
const OpenMPConstruct *GetOmp(const ExecutionPartConstruct &x);
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 89af32121487b..3a9ed35e41cb9 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -4326,10 +4326,12 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
!std::holds_alternative<clause::TaskReduction>(clause.u) &&
!std::holds_alternative<clause::Detach>(clause.u) &&
!std::holds_alternative<clause::Device>(clause.u)) {
- std::string name =
- parser::ToUpperCaseLetters(llvm::omp::getOpenMPClauseName(clause.id));
- if (!semaCtx.langOptions().OpenMPSimd)
+ const common::LangOptions &options = semaCtx.langOptions();
+ if (!options.OpenMPSimd) {
+ std::string name =
+ parser::omp::GetUpperName(clause.id, options.OpenMPVersion);
TODO(clauseLocation, name + " clause is not implemented yet");
+ }
}
}
diff --git a/flang/lib/Parser/openmp-utils.cpp b/flang/lib/Parser/openmp-utils.cpp
index 9aa7014ccb057..c81f48f6323dd 100644
--- a/flang/lib/Parser/openmp-utils.cpp
+++ b/flang/lib/Parser/openmp-utils.cpp
@@ -16,6 +16,8 @@
#include "flang/Common/template.h"
#include "flang/Common/visit.h"
#include "flang/Parser/tools.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Frontend/OpenMP/OMP.h"
#include <tuple>
#include <type_traits>
@@ -23,6 +25,16 @@
namespace Fortran::parser::omp {
+std::string GetUpperName(llvm::omp::Clause id, unsigned version) {
+ llvm::StringRef name{llvm::omp::getOpenMPClauseName(id, version)};
+ return parser::ToUpperCaseLetters(name);
+}
+
+std::string GetUpperName(llvm::omp::Directive id, unsigned version) {
+ llvm::StringRef name{llvm::omp::getOpenMPDirectiveName(id, version)};
+ return parser::ToUpperCaseLetters(name);
+}
+
const OpenMPDeclarativeConstruct *GetOmp(const DeclarationConstruct &x) {
if (auto *y = std::get_if<SpecificationConstruct>(&x.u)) {
if (auto *z{std::get_if<common::Indirection<OpenMPDeclarativeConstruct>>(
diff --git a/flang/lib/Semantics/check-omp-loop.cpp b/flang/lib/Semantics/check-omp-loop.cpp
index de7a155dd96ef..0cad16dc3deb1 100644
--- a/flang/lib/Semantics/check-omp-loop.cpp
+++ b/flang/lib/Semantics/check-omp-loop.cpp
@@ -784,7 +784,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Linear &x) {
if (dir != llvm::omp::Directive::OMPD_declare_simd) {
context_.Say(modSource,
"A modifier may not be specified in a LINEAR clause on the %s directive"_err_en_US,
- parser::ToUpperCaseLetters(getDirectiveName(dir)));
+ parser::omp::GetUpperName(dir, version));
valid = false;
}
} else {
@@ -793,8 +793,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::ToUpperCaseLetters(getDirectiveName(dir)));
+ desc.name.str(), parser::omp::GetUpperName(dir, version));
valid = false;
}
}
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 9bdd3d1dbc231..8275b0d4913dd 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -367,12 +367,10 @@ bool OmpStructureChecker::CheckAllowedClause(llvmOmpClause clause) {
// Only report it if there is a later version that allows it.
// If it's not allowed at all, it will be reported by CheckAllowed.
if (allowedInVersion != 0) {
- auto clauseName{parser::ToUpperCaseLetters(getClauseName(clause).str())};
- auto dirName{parser::ToUpperCaseLetters(getDirectiveName(dir).str())};
-
context_.Say(dirCtx.clauseSource,
"%s clause is not allowed on directive %s in %s, %s"_err_en_US,
- clauseName, dirName, ThisVersion(version),
+ parser::omp::GetUpperName(clause, version),
+ parser::omp::GetUpperName(dir, version), ThisVersion(version),
TryVersion(allowedInVersion));
}
}
@@ -925,10 +923,10 @@ void OmpStructureChecker::CheckTargetNest(const parser::OpenMPConstruct &c) {
},
c.u);
if (!eligibleTarget) {
+ unsigned version{context_.langOptions().OpenMPVersion};
context_.Warn(common::UsageWarning::OpenMPUsage, source,
"If %s directive is nested inside TARGET region, the behaviour is unspecified"_port_en_US,
- parser::ToUpperCaseLetters(
- getDirectiveName(ineligibleTargetDir).str()));
+ parser::omp::GetUpperName(ineligibleTargetDir, version));
}
}
@@ -936,6 +934,7 @@ void OmpStructureChecker::Enter(const parser::OmpBlockConstruct &x) {
const parser::OmpDirectiveSpecification &beginSpec{x.BeginDir()};
const std::optional<parser::OmpEndDirective> &endSpec{x.EndDir()};
const parser::Block &block{std::get<parser::Block>(x.t)};
+ unsigned version{context_.langOptions().OpenMPVersion};
PushContextAndClauseSets(beginSpec.DirName().source, beginSpec.DirId());
@@ -947,7 +946,7 @@ void OmpStructureChecker::Enter(const parser::OmpBlockConstruct &x) {
llvm::omp::Directive dirId{beginSpec.DirId()};
auto &msg{context_.Say(beginSpec.source,
"Expected OpenMP END %s directive"_err_en_US,
- parser::ToUpperCaseLetters(getDirectiveName(dirId)))};
+ parser::omp::GetUpperName(dirId, version))};
// ORDERED has two variants, so be explicit about which variant we think
// this is.
if (dirId == llvm::omp::Directive::OMPD_ordered) {
@@ -1707,7 +1706,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPRequiresConstruct &x) {
if (!visitedAtomicSource_.empty()) {
parser::MessageFormattedText txt(
"REQUIRES directive with '%s' clause found lexically after atomic operation without a memory order clause"_err_en_US,
- parser::ToUpperCaseLetters(llvm::omp::getOpenMPClauseName(id)));
+ parser::omp::GetUpperName(id, version));
parser::Message message(clause.source, txt);
message.Attach(visitedAtomicSource_, "Previous atomic construct"_en_US);
context_.Say(std::move(message));
@@ -1732,9 +1731,8 @@ void OmpStructureChecker::Enter(const parser::OpenMPRequiresConstruct &x) {
if (version < 60 && hasArgument) {
context_.Say(clause.source,
"An argument to %s is an %s feature, %s"_warn_en_US,
- parser::ToUpperCaseLetters(
- llvm::omp::getOpenMPClauseName(clause.Id())),
- ThisVersion(60), TryVersion(60));
+ parser::omp::GetUpperName(clause.Id(), version), ThisVersion(60),
+ TryVersion(60));
}
}
}
@@ -2977,6 +2975,7 @@ void OmpStructureChecker::Enter(
const parser::OmpClause::CancellationConstructType &x) {
llvm::omp::Directive dir{GetContext().directive};
auto &dirName{std::get<parser::OmpDirectiveName>(x.v.t)};
+ unsigned version{context_.langOptions().OpenMPVersion};
if (dir != llvm::omp::Directive::OMPD_cancel &&
dir != llvm::omp::Directive::OMPD_cancellation_point) {
@@ -2984,8 +2983,8 @@ void OmpStructureChecker::Enter(
// it will print "CANCELLATION_CONSTRUCT_TYPE" as the clause name instead
// of the contained construct name.
context_.Say(dirName.source, "%s cannot follow %s"_err_en_US,
- parser::ToUpperCaseLetters(getDirectiveName(dirName.v)),
- parser::ToUpperCaseLetters(getDirectiveName(dir)));
+ parser::omp::GetUpperName(dirName.v, version),
+ parser::omp::GetUpperName(dir, version));
} else {
switch (dirName.v) {
case llvm::omp::Directive::OMPD_do:
@@ -2996,7 +2995,7 @@ void OmpStructureChecker::Enter(
default:
context_.Say(dirName.source,
"%s is not a cancellable construct"_err_en_US,
- parser::ToUpperCaseLetters(getDirectiveName(dirName.v)));
+ parser::omp::GetUpperName(dirName.v, version));
break;
}
}
@@ -3029,8 +3028,9 @@ std::optional<llvm::omp::Directive> OmpStructureChecker::GetCancelType(
}
// Given clauses from CANCEL or CANCELLATION_POINT, identify the construct
// to which the cancellation applies.
+ unsigned version{context_.langOptions().OpenMPVersion};
std::optional<llvm::omp::Directive> cancelee;
- llvm::StringRef cancelName{getDirectiveName(cancelDir)};
+ std::string cancelName{parser::omp::GetUpperName(cancelDir, version)};
for (const parser::OmpClause &clause : maybeClauses->v) {
using CancellationConstructType =
@@ -3039,7 +3039,7 @@ std::optional<llvm::omp::Directive> OmpStructureChecker::GetCancelType(
if (cancelee) {
context_.Say(cancelSource,
"Multiple cancel-directive-name clauses are not allowed on the %s construct"_err_en_US,
- parser::ToUpperCaseLetters(cancelName.str()));
+ cancelName);
return std::nullopt;
}
cancelee = std::get<parser::OmpDirectiveName>(cctype->v.t).v;
@@ -3049,7 +3049,7 @@ std::optional<llvm::omp::Directive> OmpStructureChecker::GetCancelType(
if (!cancelee) {
context_.Say(cancelSource,
"Missing cancel-directive-name clause on the %s construct"_err_en_US,
- parser::ToUpperCaseLetters(cancelName.str()));
+ cancelName);
return std::nullopt;
}
@@ -3058,7 +3058,8 @@ std::optional<llvm::omp::Directive> OmpStructureChecker::GetCancelType(
void OmpStructureChecker::CheckCancellationNest(
const parser::CharBlock &source, llvm::omp::Directive type) {
- llvm::StringRef typeName{getDirectiveName(type)};
+ unsigned version{context_.langOptions().OpenMPVersion};
+ std::string typeName{parser::omp::GetUpperName(type, version)};
if (CurrentDirectiveIsNested()) {
// If construct-type-clause is taskgroup, the cancellation construct must be
@@ -3099,8 +3100,7 @@ void OmpStructureChecker::CheckCancellationNest(
if (!eligibleCancellation) {
context_.Say(source,
"With %s clause, %s construct must be closely nested inside TASK or TASKLOOP construct and %s region must be closely nested inside TASKGROUP region"_err_en_US,
- parser::ToUpperCaseLetters(typeName.str()),
- ContextDirectiveAsFortran(), ContextDirectiveAsFortran());
+ typeName, ContextDirectiveAsFortran(), ContextDirectiveAsFortran());
}
return;
case llvm::omp::Directive::OMPD_sections:
@@ -3128,10 +3128,8 @@ void OmpStructureChecker::CheckCancellationNest(
if (!eligibleCancellation) {
context_.Say(source,
"With %s clause, %s construct cannot be closely nested inside %s construct"_err_en_US,
- parser::ToUpperCaseLetters(typeName.str()),
- ContextDirectiveAsFortran(),
- parser::ToUpperCaseLetters(
- getDirectiveName(GetContextParent().directive).str()));
+ typeName, ContextDirectiveAsFortran(),
+ parser::omp::GetUpperName(GetContextParent().directive, version));
}
} else {
// The cancellation directive cannot be orphaned.
@@ -3139,26 +3137,22 @@ void OmpStructureChecker::CheckCancellationNest(
case llvm::omp::Directive::OMPD_taskgroup:
context_.Say(source,
"%s %s directive is not closely nested inside TASK or TASKLOOP"_err_en_US,
- ContextDirectiveAsFortran(),
- parser::ToUpperCaseLetters(typeName.str()));
+ ContextDirectiveAsFortran(), typeName);
break;
case llvm::omp::Directive::OMPD_sections:
context_.Say(source,
"%s %s directive is not closely nested inside SECTION or SECTIONS"_err_en_US,
- ContextDirectiveAsFortran(),
- parser::ToUpperCaseLetters(typeName.str()));
+ ContextDirectiveAsFortran(), typeName);
break;
case llvm::omp::Directive::OMPD_do:
context_.Say(source,
"%s %s directive is not closely nested inside the construct that matches the DO clause type"_err_en_US,
- ContextDirectiveAsFortran(),
- parser::ToUpperCaseLetters(typeName.str()));
+ ContextDirectiveAsFortran(), typeName);
break;
case llvm::omp::Directive::OMPD_parallel:
context_.Say(source,
"%s %s directive is not closely nested inside the construct that matches the PARALLEL clause type"_err_en_US,
- ContextDirectiveAsFortran(),
- parser::ToUpperCaseLetters(typeName.str()));
+ ContextDirectiveAsFortran(), typeName);
break;
default:
// This is diagnosed later.
@@ -3209,6 +3203,8 @@ void OmpStructureChecker::Leave(const parser::OmpEndDirective &x) {
// 3. Checks on clauses which are not in 'struct OmpClause' from parse-tree.h.
void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
+ unsigned version{context_.langOptions().OpenMPVersion};
+
// 2.7.1 Loop Construct Restriction
if (llvm::omp::allDoSet.test(GetContext().directive)) {
if (auto *clause{FindClause(llvm::omp::Clause::OMPC_schedule)}) {
@@ -3299,7 +3295,6 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
if (GetContext().directive == llvm::omp::Directive::OMPD_task) {
if (auto *detachClause{FindClause(llvm::omp::Clause::OMPC_detach)}) {
- unsigned version{context_.langOptions().OpenMPVersion};
if (version == 50 || version == 51) {
// OpenMP 5.0: 2.10.1 Task construct restrictions
CheckNotAllowedIfClause(llvm::omp::Clause::OMPC_detach,
@@ -3361,7 +3356,7 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
if (sym.test(Symbol::Flag::OmpThreadprivate))
context_.Say(name.source,
"A THREADPRIVATE variable cannot be in %s clause"_err_en_US,
- parser::ToUpperCaseLetters(getClauseName(clauseTy).str()));
+ parser::omp::GetUpperName(clauseTy, version));
};
// [5.1] 2.21.2 Threadprivate Directive Restriction
@@ -3578,6 +3573,8 @@ void OmpStructureChecker::Enter(const parser::OmpClause::TaskReduction &x) {
bool OmpStructureChecker::CheckReductionOperator(
const parser::OmpReductionIdentifier &ident, parser::CharBlock source,
llvm::omp::Clause clauseId) {
+ unsigned version{context_.langOptions().OpenMPVersion};
+
auto visitOperator{[&](const parser::DefinedOperator &dOpr) {
if (const auto *intrinsicOp{
std::get_if<parser::DefinedOperator::IntrinsicOperator>(&dOpr.u)}) {
@@ -3610,7 +3607,7 @@ bool OmpStructureChecker::CheckReductionOperator(
}
}
context_.Say(source, "Invalid reduction operator in %s clause."_err_en_US,
- parser::ToUpperCaseLetters(getClauseName(clauseId).str()));
+ parser::omp::GetUpperName(clauseId, version));
return false;
}};
@@ -3628,7 +3625,7 @@ bool OmpStructureChecker::CheckReductionOperator(
if (!valid) {
context_.Say(source,
"Invalid reduction identifier in %s clause."_err_en_US,
- parser::ToUpperCaseLetters(getClauseName(clauseId).str()));
+ parser::omp::GetUpperName(clauseId, version));
}
return valid;
}};
@@ -3665,7 +3662,7 @@ void OmpStructureChecker::CheckReductionObjects(
auto source{GetObjectSource(object)};
context_.Say(source ? *source : GetContext().clauseSource,
"Common block names are not allowed in %s clause"_err_en_US,
- parser::ToUpperCaseLetters(getClauseName(clauseId).str()));
+ parser::omp::GetUpperName(clauseId, version));
}
}
@@ -3684,7 +3681,7 @@ void OmpStructureChecker::CheckReductionObjects(
auto source{GetObjectSource(object)};
context_.Say(source ? *source : GetContext().clauseSource,
"The base expression of an array element or section in %s clause must be an identifier"_err_en_US,
- parser::ToUpperCaseLetters(getClauseName(clauseId).str()));
+ parser::omp::GetUpperName(clauseId, version));
}
}
}
@@ -3695,7 +3692,7 @@ void OmpStructureChecker::CheckReductionObjects(
auto source{GetObjectSource(object)};
context_.Say(source ? *source : GetContext().clauseSource,
"Type parameter inquiry is not permitted in %s clause"_err_en_US,
- parser::ToUpperCaseLetters(getClauseName(clauseId).str()));
+ parser::omp::GetUpperName(clauseId, version));
}
}
}
@@ -3862,6 +3859,8 @@ void OmpStructureChecker::CheckReductionObjectTypes(
void OmpStructureChecker::CheckReductionModifier(
const parser::OmpReductionModifier &modifier) {
+ unsigned version{context_.langOptions().OpenMPVersion};
+
using ReductionModifier = parser::OmpReductionModifier;
if (modifier.v == ReductionModifier::Value::Default) {
// The default one is always ok.
@@ -3878,7 +3877,7 @@ void OmpStructureChecker::CheckReductionModifier(
// The reduction-modifier must be default.
context_.Say(GetContext().clauseSource,
"REDUCTION modifier on %s directive must be DEFAULT"_err_en_US,
- parser::ToUpperCaseLetters(GetContext().directiveSource.ToString()));
+ parser::omp::GetUpperName(dirCtx.directive, version));
return;
}
if (modifier.v == ReductionModifier::Value::Task) {
@@ -3931,6 +3930,7 @@ void OmpStructureChecker::CheckReductionArraySection(
void OmpStructureChecker::CheckSharedBindingInOuterContext(
const parser::OmpObjectList &redObjectList) {
+ unsigned version{context_.langOptions().OpenMPVersion};
// TODO: Verify the assumption here that the immediately enclosing region is
// the parallel region to which the worksharing construct having reduction
// binds to.
@@ -3953,12 +3953,10 @@ void OmpStructureChecker::CheckSharedBindingInOuterContext(
" be shared in the parallel regions to which any"
" of the worksharing regions arising from the "
"worksharing construct bind."_err_en_US,
- parser::ToUpperCaseLetters(
- getClauseName(llvm::omp::Clause::OMPC_reduction)
- .str()),
+ parser::omp::GetUpperName(
+ llvm::omp::Clause::OMPC_reduction, version),
symbol->name(),
- parser::ToUpperCaseLetters(
- getClauseName(type).str()));
+ parser::omp::GetUpperName(type, version));
}
}
}
@@ -4095,13 +4093,13 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Firstprivate &x) {
void OmpStructureChecker::CheckIsLoopIvPartOfClause(
llvmOmpClause clause, const parser::OmpObjectList &ompObjectList) {
+ unsigned version{context_.langOptions().OpenMPVersion};
for (const auto &ompObject : ompObjectList.v) {
if (const parser::Name *name{parser::Unwrap<parser::Name>(ompObject)}) {
if (name->symbol == GetContext().loopIV) {
context_.Say(name->source,
"DO iteration variable %s is not allowed in %s clause."_err_en_US,
- name->ToString(),
- parser::ToUpperCaseLetters(getClauseName(clause).str()));
+ name->ToString(), parser::omp::GetUpperName(clause, version));
}
}
}
@@ -4216,10 +4214,8 @@ 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(getDirectiveName(sub).str())};
- std::string dirName{
- parser::ToUpperCaseLetters(getDirectiveName(dir).str())};
+ std::string subName{parser::omp::GetUpperName(sub, version)};
+ std::string dirName{parser::omp::GetUpperName(dir, version)};
parser::CharBlock modifierSource{OmpGetModifierSource(modifiers, dnm)};
auto desc{OmpGetDescriptor<parser::OmpDirectiveNameModifier>()};
@@ -4505,6 +4501,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Device &x) {
CheckAllowedClause(llvm::omp::Clause::OMPC_device);
const parser::OmpDeviceClause &deviceClause{x.v};
const auto &device{std::get<parser::ScalarIntExpr>(deviceClause.t)};
+ unsigned version{context_.langOptions().OpenMPVersion};
RequiresPositiveParameter(
llvm::omp::Clause::OMPC_device, device, "device expression");
llvm::omp::Directive dir{GetContext().directive};
@@ -4520,7 +4517,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Device &x) {
auto name{OmpGetDescriptor<parser::OmpDeviceModifier>().name};
context_.Say(OmpGetModifierSource(modifiers, deviceMod),
"The ANCESTOR %s must not appear on the DEVICE clause on any directive other than the TARGET construct. Found on %s construct."_err_en_US,
- name.str(), parser::ToUpperCaseLetters(getDirectiveName(dir)));
+ name.str(), parser::omp::GetUpperName(dir, version));
}
}
}
@@ -4574,7 +4571,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Depend &x) {
if (doaDep) {
context_.Say(GetContext().clauseSource,
"The SINK and SOURCE dependence types can only be used with the ORDERED directive, used here in the %s construct"_err_en_US,
- parser::ToUpperCaseLetters(getDirectiveName(dir)));
+ parser::omp::GetUpperName(dir, version));
}
}
if (taskDep) {
@@ -4699,13 +4696,13 @@ void OmpStructureChecker::CheckDoacross(const parser::OmpDoacross &doa) {
void OmpStructureChecker::CheckCopyingPolymorphicAllocatable(
SymbolSourceMap &symbols, const llvm::omp::Clause clause) {
+ unsigned version{context_.langOptions().OpenMPVersion};
if (context_.ShouldWarn(common::UsageWarning::Portability)) {
for (auto &[symbol, source] : symbols) {
if (IsPolymorphicAllocatable(*symbol)) {
context_.Warn(common::UsageWarning::Portability, source,
"If a polymorphic variable with allocatable attribute '%s' is in %s clause, the behavior is unspecified"_port_en_US,
- symbol->name(),
- parser::ToUpperCaseLetters(getClauseName(clause).str()));
+ symbol->name(), parser::omp::GetUpperName(clause, version));
}
}
}
@@ -4785,6 +4782,8 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Copyin &x) {
void OmpStructureChecker::CheckStructureComponent(
const parser::OmpObjectList &objects, llvm::omp::Clause clauseId) {
+ unsigned version{context_.langOptions().OpenMPVersion};
+
auto CheckComponent{[&](const parser::Designator &designator) {
if (const parser::DataRef *dataRef{
std::get_if<parser::DataRef>(&designator.u)}) {
@@ -4795,7 +4794,7 @@ void OmpStructureChecker::CheckStructureComponent(
if (expr.has_value() && evaluate::HasStructureComponent(expr.value())) {
context_.Say(designator.source,
"A variable that is part of another variable cannot appear on the %s clause"_err_en_US,
- parser::ToUpperCaseLetters(getClauseName(clauseId).str()));
+ parser::omp::GetUpperName(clauseId, version));
}
}
}
@@ -5049,18 +5048,20 @@ void OmpStructureChecker::Enter(const parser::OmpClause::To &x) {
}
void OmpStructureChecker::Enter(const parser::OmpClause::OmpxBare &x) {
+ unsigned version{context_.langOptions().OpenMPVersion};
// Don't call CheckAllowedClause, because it allows "ompx_bare" on
// a non-combined "target" directive (for reasons of splitting combined
// directives). In source code it's only allowed on "target teams".
if (GetContext().directive != llvm::omp::Directive::OMPD_target_teams) {
context_.Say(GetContext().clauseSource,
"%s clause is only allowed on combined TARGET TEAMS"_err_en_US,
- parser::ToUpperCaseLetters(getClauseName(llvm::omp::OMPC_ompx_bare)));
+ parser::omp::GetUpperName(llvm::omp::OMPC_ompx_bare, version));
}
}
llvm::StringRef OmpStructureChecker::getClauseName(llvm::omp::Clause clause) {
- return llvm::omp::getOpenMPClauseName(clause);
+ unsigned version{context_.langOptions().OpenMPVersion};
+ return llvm::omp::getOpenMPClauseName(clause, version);
}
llvm::StringRef OmpStructureChecker::getDirectiveName(
@@ -5092,6 +5093,7 @@ void OmpStructureChecker::CheckDependList(const parser::DataRef &d) {
void OmpStructureChecker::CheckArraySection(
const parser::ArrayElement &arrayElement, const parser::Name &name,
const llvm::omp::Clause clause) {
+ unsigned version{context_.langOptions().OpenMPVersion};
// Sometimes substring operations are incorrectly parsed as array accesses.
// Detect this by looking for array accesses on character variables which are
// not arrays.
@@ -5134,8 +5136,7 @@ void OmpStructureChecker::CheckArraySection(
if (strideVal && *strideVal < 1) {
context_.Say(GetContext().clauseSource,
"'%s' in %s clause must have a positive stride"_err_en_US,
- name.ToString(),
- parser::ToUpperCaseLetters(getClauseName(clause).str()));
+ name.ToString(), parser::omp::GetUpperName(clause, version));
}
if (isSubstring) {
context_.Say(GetContext().clauseSource,
@@ -5161,7 +5162,7 @@ void OmpStructureChecker::CheckArraySection(
"'%s' in %s clause"
" is a zero size array section"_err_en_US,
name.ToString(),
- parser::ToUpperCaseLetters(getClauseName(clause).str()));
+ parser::omp::GetUpperName(clause, version));
break;
}
}
@@ -5180,24 +5181,24 @@ void OmpStructureChecker::CheckArraySection(
void OmpStructureChecker::CheckIntentInPointer(
SymbolSourceMap &symbols, llvm::omp::Clause clauseId) {
+ unsigned version{context_.langOptions().OpenMPVersion};
for (auto &[symbol, source] : symbols) {
if (IsPointer(*symbol) && IsIntentIn(*symbol)) {
context_.Say(source,
"Pointer '%s' with the INTENT(IN) attribute may not appear in a %s clause"_err_en_US,
- symbol->name(),
- parser::ToUpperCaseLetters(getClauseName(clauseId).str()));
+ symbol->name(), parser::omp::GetUpperName(clauseId, version));
}
}
}
void OmpStructureChecker::CheckProcedurePointer(
SymbolSourceMap &symbols, llvm::omp::Clause clause) {
+ unsigned version{context_.langOptions().OpenMPVersion};
for (const auto &[symbol, source] : symbols) {
if (IsProcedurePointer(*symbol)) {
context_.Say(source,
"Procedure pointer '%s' may not appear in a %s clause"_err_en_US,
- symbol->name(),
- parser::ToUpperCaseLetters(getClauseName(clause).str()));
+ symbol->name(), parser::omp::GetUpperName(clause, version));
}
}
}
@@ -5242,15 +5243,14 @@ void OmpStructureChecker::GetSymbolsInObjectList(
void OmpStructureChecker::CheckDefinableObjects(
SymbolSourceMap &symbols, const llvm::omp::Clause clause) {
+ unsigned version{context_.langOptions().OpenMPVersion};
for (auto &[symbol, source] : symbols) {
if (auto msg{WhyNotDefinable(source, context_.FindScope(source),
DefinabilityFlags{}, *symbol)}) {
- context_
- .Say(source,
- "Variable '%s' on the %s clause is not definable"_err_en_US,
- symbol->name(),
- parser::ToUpperCaseLetters(getClauseName(clause).str()))
- .Attach(std::move(msg->set_severity(parser::Severity::Because)));
+ context_.Say(source,
+ "Variable '%s' on the %s clause is not definable"_err_en_US,
+ symbol->name(), parser::omp::GetUpperName(clause, version))
+ .Attach(std::move(msg->set_severity(parser::Severity::Because)));
}
}
}
@@ -5258,6 +5258,7 @@ void OmpStructureChecker::CheckDefinableObjects(
void OmpStructureChecker::CheckPrivateSymbolsInOuterCxt(
SymbolSourceMap &currSymbols, DirectivesClauseTriple &dirClauseTriple,
const llvm::omp::Clause currClause) {
+ unsigned version{context_.langOptions().OpenMPVersion};
SymbolSourceMap enclosingSymbols;
auto range{dirClauseTriple.equal_range(GetContext().directive)};
for (auto dirIter{range.first}; dirIter != range.second; ++dirIter) {
@@ -5278,8 +5279,7 @@ void OmpStructureChecker::CheckPrivateSymbolsInOuterCxt(
if (enclosingSymbols.find(symbol) != enclosingSymbols.end()) {
context_.Say(source,
"%s variable '%s' is PRIVATE in outer context"_err_en_US,
- parser::ToUpperCaseLetters(getClauseName(currClause).str()),
- symbol->name());
+ parser::omp::GetUpperName(currClause, version), symbol->name());
}
}
}
@@ -5638,14 +5638,14 @@ void OmpStructureChecker::Leave(const parser::OpenMPInteropConstruct &) {
void OmpStructureChecker::CheckAllowedRequiresClause(llvmOmpClause clause) {
CheckAllowedClause(clause);
+ unsigned version{context_.langOptions().OpenMPVersion};
if (clause != llvm::omp::Clause::OMPC_atomic_default_mem_order) {
// Check that it does not appear after a device construct
if (deviceConstructFound_) {
context_.Say(GetContext().clauseSource,
- "REQUIRES directive with '%s' clause found lexically after device "
- "construct"_err_en_US,
- parser::ToUpperCaseLetters(getClauseName(clause).str()));
+ "REQUIRES directive with '%s' clause found lexically after device construct"_err_en_US,
+ parser::omp::GetUpperName(clause, version));
}
}
}
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index e3a14a795cbe3..c8ffa22d6bb5f 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -3140,8 +3140,7 @@ void OmpAttributeVisitor::ResolveOmpDesignator(
"Variable '%s' may not appear on both %s and %s clauses on a %s construct"_err_en_US,
symbol2->name(), Symbol::OmpFlagToClauseName(firstOmpFlag),
Symbol::OmpFlagToClauseName(secondOmpFlag),
- parser::ToUpperCaseLetters(
- llvm::omp::getOpenMPDirectiveName(directive, version)));
+ parser::omp::GetUpperName(directive, version));
}
}};
if (dataCopyingAttributeFlags.test(ompFlag)) {
@@ -3519,9 +3518,7 @@ 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, version)
- .str()));
+ parser::omp::GetUpperName(targetContext->directive, version));
}
if (sourceContext &&
(!targetContext ||
@@ -3532,9 +3529,7 @@ 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, version)
- .str()));
+ parser::omp::GetUpperName(sourceContext->directive, version));
}
}
@@ -3559,12 +3554,13 @@ void OmpAttributeVisitor::AddOmpRequiresToScope(Scope &scope,
if (memOrder) {
if (details.has_ompAtomicDefaultMemOrder() &&
*details.ompAtomicDefaultMemOrder() != *memOrder) {
+ unsigned version{context_.langOptions().OpenMPVersion};
context_.Say(programUnit.sourceRange(),
"Conflicting '%s' REQUIRES clauses found in compilation "
"unit"_err_en_US,
- parser::ToUpperCaseLetters(llvm::omp::getOpenMPClauseName(
- llvm::omp::Clause::OMPC_atomic_default_mem_order)
- .str()));
+ parser::omp::GetUpperName(
+ llvm::omp::Clause::OMPC_atomic_default_mem_order,
+ version));
}
details.set_ompAtomicDefaultMemOrder(*memOrder);
}
@@ -3584,9 +3580,7 @@ void OmpAttributeVisitor::IssueNonConformanceWarning(llvm::omp::Directive D,
if (version < EmitFromVersion) {
return;
}
- warnStrOS << "OpenMP directive "
- << parser::ToUpperCaseLetters(
- llvm::omp::getOpenMPDirectiveName(D, version).str())
+ warnStrOS << "OpenMP directive " << parser::omp::GetUpperName(D, version)
<< " has been deprecated";
auto setAlternativeStr = [&warnStrOS](llvm::StringRef alt) {
>From da5f60cf979211f07cec8f572f4f3be1e37dcb58 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Thu, 5 Mar 2026 12:52:01 -0600
Subject: [PATCH 2/2] format
---
flang/lib/Semantics/check-omp-structure.cpp | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 8275b0d4913dd..69818bee2febe 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -5247,10 +5247,11 @@ void OmpStructureChecker::CheckDefinableObjects(
for (auto &[symbol, source] : symbols) {
if (auto msg{WhyNotDefinable(source, context_.FindScope(source),
DefinabilityFlags{}, *symbol)}) {
- context_.Say(source,
- "Variable '%s' on the %s clause is not definable"_err_en_US,
- symbol->name(), parser::omp::GetUpperName(clause, version))
- .Attach(std::move(msg->set_severity(parser::Severity::Because)));
+ context_
+ .Say(source,
+ "Variable '%s' on the %s clause is not definable"_err_en_US,
+ symbol->name(), parser::omp::GetUpperName(clause, version))
+ .Attach(std::move(msg->set_severity(parser::Severity::Because)));
}
}
}
More information about the flang-commits
mailing list