[flang-commits] [flang] [flang][OpenMP] Utilities to get uppercase directive/clause names (PR #184853)
via flang-commits
flang-commits at lists.llvm.org
Thu Mar 5 10:49:27 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-parser
Author: Krzysztof Parzyszek (kparzysz)
<details>
<summary>Changes</summary>
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.
---
Patch is 33.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/184853.diff
6 Files Affected:
- (modified) flang/include/flang/Parser/openmp-utils.h (+3)
- (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+5-3)
- (modified) flang/lib/Parser/openmp-utils.cpp (+12)
- (modified) flang/lib/Semantics/check-omp-loop.cpp (+2-3)
- (modified) flang/lib/Semantics/check-omp-structure.cpp (+76-76)
- (modified) flang/lib/Semantics/resolve-directives.cpp (+8-14)
``````````diff
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)}) {
...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/184853
More information about the flang-commits
mailing list