https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/219822
Also make llvm::omp::Version converting constructor/operstor explicit. --- <sub>Stack created with <a href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub> >From f84f14b56875eb5164d6cd569caf4ce898f6b149 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek <[email protected]> Date: Fri, 28 Aug 2026 15:46:48 -0500 Subject: [PATCH] [flang][OpenMP] Switch OpenMP version from unsigned to llvm::omp::Version Also make llvm::omp::Version converting constructor/operstor explicit. --- flang/include/flang/Parser/openmp-utils.h | 4 +- .../flang/Semantics/openmp-modifiers.h | 20 +- flang/include/flang/Semantics/openmp-utils.h | 38 ++-- flang/include/flang/Semantics/symbol.h | 4 +- flang/include/flang/Support/LangOptions.h | 5 + flang/lib/Frontend/CompilerInvocation.cpp | 11 +- flang/lib/Frontend/FrontendActions.cpp | 3 +- flang/lib/Lower/OpenMP/Atomic.cpp | 10 +- flang/lib/Lower/OpenMP/ClauseProcessor.cpp | 6 +- flang/lib/Lower/OpenMP/ClauseProcessor.h | 2 +- .../lib/Lower/OpenMP/DataSharingProcessor.cpp | 6 +- flang/lib/Lower/OpenMP/DataSharingProcessor.h | 6 +- flang/lib/Lower/OpenMP/Decomposer.cpp | 6 +- flang/lib/Lower/OpenMP/OpenMP.cpp | 6 +- flang/lib/Lower/PFTBuilder.cpp | 2 +- flang/lib/Parser/openmp-parsers.cpp | 10 +- flang/lib/Parser/openmp-utils.cpp | 4 +- flang/lib/Parser/unparse.cpp | 4 +- flang/lib/Semantics/check-omp-atomic.cpp | 2 +- flang/lib/Semantics/check-omp-loop.cpp | 12 +- flang/lib/Semantics/check-omp-structure.cpp | 179 +++++++++--------- flang/lib/Semantics/check-omp-variant.cpp | 10 +- flang/lib/Semantics/mod-file.cpp | 4 +- flang/lib/Semantics/openmp-utils.cpp | 35 ++-- flang/lib/Semantics/resolve-directives.cpp | 14 +- flang/unittests/Semantics/OpenMPUtils.cpp | 9 +- .../include/llvm/Frontend/OpenMP/OMPVersion.h | 8 +- 27 files changed, 220 insertions(+), 200 deletions(-) diff --git a/flang/include/flang/Parser/openmp-utils.h b/flang/include/flang/Parser/openmp-utils.h index 9f47689906035..cd19ed1d72f0d 100644 --- a/flang/include/flang/Parser/openmp-utils.h +++ b/flang/include/flang/Parser/openmp-utils.h @@ -142,8 +142,8 @@ 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); +std::string GetUpperName(llvm::omp::Clause id, llvm::omp::Version version); +std::string GetUpperName(llvm::omp::Directive id, llvm::omp::Version version); const OpenMPDeclarativeConstruct *GetOmp(const DeclarationConstruct &x); const OpenMPConstruct *GetOmp(const ExecutionPartConstruct &x); diff --git a/flang/include/flang/Semantics/openmp-modifiers.h b/flang/include/flang/Semantics/openmp-modifiers.h index a199e55639ea8..ef92cd397dd89 100644 --- a/flang/include/flang/Semantics/openmp-modifiers.h +++ b/flang/include/flang/Semantics/openmp-modifiers.h @@ -295,7 +295,7 @@ bool verifyVersions(const std::optional<std::list<UnionTy>> &modifiers, if (!modifiers) { return true; } - unsigned version{semaCtx.langOptions().OpenMPVersion}; + llvm::omp::Version version{semaCtx.langOptions().getOpenMP()}; bool result{true}; for (auto &m : *modifiers) { const llvm::omp::descriptor::Modifier &desc{OmpGetDescriptor(m)}; @@ -304,8 +304,8 @@ bool verifyVersions(const std::optional<std::list<UnionTy>> &modifiers, } // Find the next higher version that allows this modifier on this clause. const auto &versions{desc.getVersions()}; - unsigned since{~0u}, until{0u}; - for (unsigned v : versions) { + llvm::omp::Version since(~0u), until(0u); + for (llvm::omp::Version v : versions) { if (desc.getClauses(v).test(id)) { if (v < version) { until = std::max(until, v); @@ -314,20 +314,20 @@ bool verifyVersions(const std::optional<std::list<UnionTy>> &modifiers, } } } - if (since == ~0u && until == 0u) { + if (since == ~0 && until == 0) { // 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.getName().str(), parser::ToUpperCaseLetters(llvm::omp::getOpenMPClauseName(id))); - } else if (since != ~0u && version < since) { + } else if (since != ~0 && version < since) { semaCtx.Say(m.source, "'%s' modifier is not supported in %s on %s clause, %s"_warn_en_US, desc.getName().str(), omp::ThisVersion(version), parser::ToUpperCaseLetters(llvm::omp::getOpenMPClauseName(id)), omp::TryVersion(since)); result = false; - } else if (until != 0u && version > until) { + } else if (until != 0 && version > until) { semaCtx.Say(m.source, "'%s' modifier is no longer supported in %s on %s clause"_warn_en_US, desc.getName().str(), omp::ThisVersion(version), @@ -346,7 +346,7 @@ template <typename SpecificTy, typename UnionTy> bool verifyIfRequired(const SpecificTy *, const std::optional<std::list<UnionTy>> &modifiers, parser::CharBlock clauseSource, SemanticsContext &semaCtx) { - unsigned version{semaCtx.langOptions().OpenMPVersion}; + llvm::omp::Version version{semaCtx.langOptions().getOpenMP()}; 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. @@ -400,7 +400,7 @@ bool verifyIfUnique(const SpecificTy *, // `specific` is the location of the modifier of type SpecificTy. assert(specific != end && "`specific` must be a valid location"); - unsigned version{semaCtx.langOptions().OpenMPVersion}; + llvm::omp::Version version{semaCtx.langOptions().getOpenMP()}; const llvm::omp::descriptor::Modifier &desc{OmpGetDescriptor<SpecificTy>()}; // Ultimate implies Unique. if (!desc.getProperties(version).test(llvm::omp::Property::Unique) && @@ -449,7 +449,7 @@ bool verifyUltimate(const std::optional<std::list<UnionTy>> &modifiers, if (!modifiers || modifiers->size() <= 1) { return true; } - unsigned version{semaCtx.langOptions().OpenMPVersion}; + llvm::omp::Version version{semaCtx.langOptions().getOpenMP()}; bool result{true}; auto first{modifiers->cbegin()}; auto last{std::prev(modifiers->cend())}; @@ -498,7 +498,7 @@ bool verifyExclusive(const std::optional<std::list<UnionTy>> &modifiers, if (!modifiers || modifiers->size() <= 1) { return true; } - unsigned version{semaCtx.langOptions().OpenMPVersion}; + llvm::omp::Version version{semaCtx.langOptions().getOpenMP()}; const UnionTy &front{modifiers->front()}; const llvm::omp::descriptor::Modifier &frontDesc{OmpGetDescriptor(front)}; diff --git a/flang/include/flang/Semantics/openmp-utils.h b/flang/include/flang/Semantics/openmp-utils.h index de3d532c7f79a..eab005c2a08ac 100644 --- a/flang/include/flang/Semantics/openmp-utils.h +++ b/flang/include/flang/Semantics/openmp-utils.h @@ -25,6 +25,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Frontend/OpenMP/OMPContext.h" +#include "llvm/Frontend/OpenMP/OMPVersion.h" #include <memory> #include <optional> @@ -69,8 +70,8 @@ struct SourcedActionStmt SourcedActionStmt GetActionStmt(const parser::ExecutionPartConstruct *x); SourcedActionStmt GetActionStmt(const parser::Block &block); -std::string ThisVersion(unsigned version); -std::string TryVersion(unsigned version); +std::string ThisVersion(llvm::omp::Version version); +std::string TryVersion(llvm::omp::Version version); const Symbol *GetObjectSymbol( const parser::OmpObject &object, bool ultimate = false); @@ -275,7 +276,7 @@ enum struct ListItemKind : uint32_t { }; std::optional<ListItemKind> GetArgumentListItemKind( - llvm::omp::Clause clause, unsigned version); + llvm::omp::Clause clause, llvm::omp::Version version); bool IsLoopTransforming(llvm::omp::Directive dir); bool HasDataEnvironment(llvm::omp::Directive dir); @@ -297,7 +298,7 @@ struct OmpErrorArgs { /// MESSAGE clause values. OmpErrorArgs GetErrorDirectiveArgs(const parser::OmpErrorDirective &errDir); -inline bool IsDoConcurrentLegal(unsigned version) { +inline bool IsDoConcurrentLegal(llvm::omp::Version version) { // DO CONCURRENT is allowed (as an alternative to a Canonical Loop Nest) // in OpenMP 6.0+. return version >= 60; @@ -358,33 +359,33 @@ template <typename T> struct WithReason { WithReason<int64_t> GetArgumentValueWithReason( const parser::OmpDirectiveSpecification &spec, llvm::omp::Clause clauseId, - unsigned version, SemanticsContext *semaCtx = nullptr); + llvm::omp::Version version, SemanticsContext *semaCtx = nullptr); WithReason<int64_t> GetNumArgumentsWithReason( const parser::OmpDirectiveSpecification &spec, llvm::omp::Clause clauseId, - unsigned version, SemanticsContext *semaCtx = nullptr); + llvm::omp::Version version, SemanticsContext *semaCtx = nullptr); WithReason<int64_t> GetHeightWithReason( - const parser::OmpDirectiveSpecification &spec, unsigned version, + const parser::OmpDirectiveSpecification &spec, llvm::omp::Version version, SemanticsContext *semaCtx = nullptr); /// Return the depth of the affected nest(s): /// {affected-depth, must-be-perfect-nest}. std::pair<WithReason<int64_t>, bool> GetAffectedNestDepthWithReason( - const parser::OmpDirectiveSpecification &spec, unsigned version, + const parser::OmpDirectiveSpecification &spec, llvm::omp::Version version, SemanticsContext *semaCtx = nullptr); /// Return the depth of the generated nest(s): /// {generated-depth, is-perfect-nest} std::pair<WithReason<int64_t>, bool> GetGeneratedNestDepthWithReason( - const parser::OmpDirectiveSpecification &spec, unsigned version, + const parser::OmpDirectiveSpecification &spec, llvm::omp::Version version, SemanticsContext *semaCtx = nullptr); /// Return the range of the affected nests in the sequence: /// {first, count}. /// If the range is "the whole sequence", the return value will be {1, -1}. WithReason<std::pair<int64_t, int64_t>> GetAffectedLoopRangeWithReason( - const parser::OmpDirectiveSpecification &spec, unsigned version, + const parser::OmpDirectiveSpecification &spec, llvm::omp::Version version, SemanticsContext *semaCtx = nullptr); /// Return the depth in which all loops must be rectangular. WithReason<int64_t> GetRectangularNestDepthWithReason( - const parser::OmpDirectiveSpecification &spec, unsigned version, + const parser::OmpDirectiveSpecification &spec, llvm::omp::Version version, SemanticsContext *semaCtx = nullptr); /// Calculate the minimum length of a sequence that contains the specified @@ -401,7 +402,7 @@ std::optional<int64_t> GetMinimumSequenceCount( /// Returns std::nullopt if `x` or code nested in `x` was malformed in a /// way that prevented the function from returning an accurate result. std::optional<std::vector<const parser::DoConstruct *>> CollectAffectedDoLoops( - const parser::OpenMPLoopConstruct &x, unsigned version, + const parser::OpenMPLoopConstruct &x, llvm::omp::Version version, SemanticsContext *semaCtx = nullptr); /// Returns whether the loop nest associated with `x` is a doacross loop nest, @@ -411,12 +412,13 @@ std::optional<std::vector<const parser::DoConstruct *>> CollectAffectedDoLoops( bool IsDoacrossAffected(const parser::OpenMPLoopConstruct &x); struct LoopSequence { - LoopSequence(const parser::ExecutionPartConstruct &root, unsigned version, - bool allowAllLoops = false, SemanticsContext *semaCtx = nullptr); + LoopSequence(const parser::ExecutionPartConstruct &root, + llvm::omp::Version version, bool allowAllLoops = false, + SemanticsContext *semaCtx = nullptr); template <typename R, typename = std::enable_if_t<is_range_v<R>>> - LoopSequence(const R &range, unsigned version, bool allowAllLoops = false, - SemanticsContext *semaCtx = nullptr) + LoopSequence(const R &range, llvm::omp::Version version, + bool allowAllLoops = false, SemanticsContext *semaCtx = nullptr) : version_(version), allowAllLoops_(allowAllLoops), semaCtx_(semaCtx) { entry_ = std::make_unique<Construct>(range, nullptr); createChildrenFromRange(entry_->location); @@ -455,7 +457,7 @@ struct LoopSequence { private: using Construct = ExecutionPartIterator::Construct; - LoopSequence(std::unique_ptr<Construct> entry, unsigned version, + LoopSequence(std::unique_ptr<Construct> entry, llvm::omp::Version version, bool allowAllLoops, SemanticsContext *semaCtx = nullptr); template <typename R, typename = std::enable_if_t<is_range_v<R>>> @@ -504,7 +506,7 @@ struct LoopSequence { WithReason<int64_t> height_; // The core structure of the class: - unsigned version_; // Needed for GetXyzWithReason + llvm::omp::Version version_; // Needed for GetXyzWithReason bool allowAllLoops_; std::unique_ptr<Construct> entry_; std::vector<LoopSequence> children_; diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h index a51b4542e4f36..e62b52f1f0bd4 100644 --- a/flang/include/flang/Semantics/symbol.h +++ b/flang/include/flang/Semantics/symbol.h @@ -99,10 +99,10 @@ class WithOmpDeclarative { friend llvm::raw_ostream &operator<<( llvm::raw_ostream &, const WithOmpDeclarative &); - void set_version(unsigned version) { version_ = version; } + void set_version(llvm::omp::Version version) { version_ = version; } private: - unsigned version_; + llvm::omp::Version version_; // The set of clauses from a REQUIRES directive. Only applicable // to program unit symbols (i.e. scopes of the REQUIRES directive). // The set of requirements for any program unit include requirements diff --git a/flang/include/flang/Support/LangOptions.h b/flang/include/flang/Support/LangOptions.h index 42b488c3d18a3..054bafb78354a 100644 --- a/flang/include/flang/Support/LangOptions.h +++ b/flang/include/flang/Support/LangOptions.h @@ -18,6 +18,7 @@ #include <string> #include <vector> +#include "llvm/Frontend/OpenMP/OMPVersion.h" #include "llvm/TargetParser/Triple.h" namespace Fortran::common { @@ -87,6 +88,10 @@ class LangOptions : public LangOptionsBase { /// List of triples passed in using -fopenmp-targets. std::vector<llvm::Triple> OMPTargetTriples; + llvm::omp::Version getOpenMP() const { + return llvm::omp::Version(OpenMPVersion); + } + LangOptions(); }; diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 933446771dddc..b92ad8e2982b4 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -1305,8 +1305,10 @@ static bool parseOpenMPArgs(CompilerInvocation &res, llvm::opt::ArgList &args, res.getFrontendOpts().features.Enable( Fortran::common::LanguageFeature::OpenMP); if (auto *arg = args.getLastArg(clang::options::OPT_fopenmp_version_EQ)) { - llvm::ArrayRef<llvm::omp::Version> ompVersions = - llvm::omp::getOpenMPVersions(); + llvm::SmallVector<unsigned> ompVersions; + for (llvm::omp::Version v : llvm::omp::getOpenMPVersions()) { + ompVersions.push_back(static_cast<unsigned>(v)); + } unsigned oldVersions[] = {11, 20, 25, 30}; unsigned version = 0; @@ -1955,8 +1957,9 @@ void CompilerInvocation::setDefaultPredefinitions() { } if (frontendOptions.features.IsEnabled( Fortran::common::LanguageFeature::OpenMP)) { - Fortran::common::setOpenMPMacro(getLangOpts().OpenMPVersion, - fortranOptions.predefinitions); + Fortran::common::setOpenMPMacro( + static_cast<unsigned>(getLangOpts().getOpenMP()), + fortranOptions.predefinitions); } if (frontendOptions.features.IsEnabled( diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index 8a2d1a6c2e2a2..2f5930890aaf9 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -275,8 +275,9 @@ bool CodeGenAction::beginSourceFileAction() { mlir::omp::setOffloadModuleInterfaceAttributes( lb.getModule(), makeOffloadModuleOpts(ci.getInvocation().getLangOpts())); + llvm::omp::Version version = ci.getInvocation().getLangOpts().getOpenMP(); mlir::omp::setOpenMPVersionAttribute( - lb.getModule(), ci.getInvocation().getLangOpts().OpenMPVersion); + lb.getModule(), static_cast<unsigned>(version)); if (!ci.getInvocation().getLoweringOpts().getIntegerWrapAround()) mlir::omp::setOpenMPIntegerWrapAround(lb.getModule(), false); } diff --git a/flang/lib/Lower/OpenMP/Atomic.cpp b/flang/lib/Lower/OpenMP/Atomic.cpp index 37c856795defe..79f4681c67275 100644 --- a/flang/lib/Lower/OpenMP/Atomic.cpp +++ b/flang/lib/Lower/OpenMP/Atomic.cpp @@ -226,7 +226,7 @@ getMemoryOrderFromRequires(const semantics::Scope &scope) { static std::optional<mlir::omp::ClauseMemoryOrderKind> getDefaultAtomicMemOrder(semantics::SemanticsContext &semaCtx) { - unsigned version = semaCtx.langOptions().OpenMPVersion; + llvm::omp::Version version = semaCtx.langOptions().getOpenMP(); if (version > 50) return mlir::omp::ClauseMemoryOrderKind::Relaxed; return std::nullopt; @@ -250,7 +250,7 @@ getAtomicMemoryOrder(semantics::SemanticsContext &semaCtx, static std::optional<mlir::omp::ClauseMemoryOrderKind> makeValidForAction(std::optional<mlir::omp::ClauseMemoryOrderKind> memOrder, - int action0, int action1, unsigned version) { + int action0, int action1, llvm::omp::Version version) { // When the atomic default memory order specified on a REQUIRES directive is // disallowed on a given ATOMIC operation, and it's not ACQ_REL, the order // reverts to RELAXED. ACQ_REL decays to either ACQUIRE or RELEASE, depending @@ -355,7 +355,7 @@ genAtomicRead(lower::AbstractConverter &converter, if (*memOrder == mlir::omp::ClauseMemoryOrderKind::Release) { // Reset it back to the default. memOrder = getDefaultAtomicMemOrder(semaCtx); - } else if (semaCtx.langOptions().OpenMPVersion <= 50 && + } else if (semaCtx.langOptions().getOpenMP() <= 50 && *memOrder == mlir::omp::ClauseMemoryOrderKind::Acq_rel) { // In OpenMP 5.0, acq_rel is not allowed on read; decay to acquire. // In OpenMP 5.1+, acq_rel is permitted on read. @@ -418,7 +418,7 @@ genAtomicWrite(lower::AbstractConverter &converter, if (*memOrder == mlir::omp::ClauseMemoryOrderKind::Acquire) { // Reset it back to the default. memOrder = getDefaultAtomicMemOrder(semaCtx); - } else if (semaCtx.langOptions().OpenMPVersion <= 50 && + } else if (semaCtx.langOptions().getOpenMP() <= 50 && *memOrder == mlir::omp::ClauseMemoryOrderKind::Acq_rel) { // In OpenMP 5.0, acq_rel is not allowed on write; decay to release. // In OpenMP 5.1+, acq_rel is permitted on write. @@ -574,7 +574,7 @@ void Fortran::lower::omp::lowerAtomic( auto [memOrder, canOverride] = getAtomicMemoryOrder( semaCtx, clauses, semaCtx.FindScope(construct.source)); - unsigned version = semaCtx.langOptions().OpenMPVersion; + llvm::omp::Version version = semaCtx.langOptions().getOpenMP(); int action0 = analysis.op0.what & analysis.Action; int action1 = analysis.op1.what & analysis.Action; memOrder = makeValidForAction(memOrder, action0, action1, version); diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp index b2f511c2c9cd1..044dd65e16fa0 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp @@ -1831,7 +1831,7 @@ bool ClauseProcessor::processLinear(mlir::omp::LinearClauseOps &result, std::optional<mlir::omp::LinearModifier> linearMod; if (explicitLinearMod) linearMod = *explicitLinearMod; - else if (semaCtx.langOptions().OpenMPVersion >= 52) + else if (semaCtx.langOptions().getOpenMP() >= 52) linearMod = isDeclareSimd ? getDeclareSimdDefaultMod(*sym) : mlir::omp::LinearModifier::val; @@ -1979,10 +1979,10 @@ bool ClauseProcessor::processMap( // default value Map::MapType type; if (directive == llvm::omp::Directive::OMPD_target_enter_data && - semaCtx.langOptions().OpenMPVersion >= 52) + semaCtx.langOptions().getOpenMP() >= 52) type = mapType.value_or(Map::MapType::To); else if (directive == llvm::omp::Directive::OMPD_target_exit_data && - semaCtx.langOptions().OpenMPVersion >= 52) + semaCtx.langOptions().getOpenMP() >= 52) type = mapType.value_or(Map::MapType::From); else type = mapType.value_or(Map::MapType::Tofrom); diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h index 10d52bcdf89de..177a5ff33f231 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.h +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h @@ -236,7 +236,7 @@ void ClauseProcessor::processTODO(mlir::Location currentLocation, auto checkUnhandledClause = [&](llvm::omp::Clause id, const auto *x) { if (!x) return; - unsigned version = semaCtx.langOptions().OpenMPVersion; + llvm::omp::Version version = semaCtx.langOptions().getOpenMP(); bool isSimdDirective = llvm::omp::getOpenMPDirectiveName(directive, version) .upper() .find("SIMD") != llvm::StringRef::npos; diff --git a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp index 1d39c1a8d4b77..a4d09375dfbfc 100644 --- a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp +++ b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp @@ -287,7 +287,7 @@ void DataSharingProcessor::collectSymbolsForPrivatization() { // versions semantics only warns and ignores it, so fall back to a // regular lastprivate here to keep lowering consistent and avoid the // conditional path for entities it cannot handle (e.g. characters). - if (semaCtx.langOptions().OpenMPVersion >= 50) { + if (semaCtx.langOptions().getOpenMP() >= 50) { collectOmpObjectListSymbol(objects, conditionalLastPrivatizedSymbols); } else { collectOmpObjectListSymbol(objects, explicitlyPrivatizedSymbols); @@ -456,14 +456,14 @@ static parser::CharBlock getSource(const semantics::SemanticsContext &semaCtx, } bool DataSharingProcessor::isOpenMPPrivatizingConstruct( - const parser::OpenMPConstruct &omp, unsigned version) { + const parser::OpenMPConstruct &omp, llvm::omp::Version version) { return llvm::omp::isPrivatizingConstruct( parser::omp::GetOmpDirectiveName(omp).v, version); } bool DataSharingProcessor::isOpenMPPrivatizingEvaluation( const pft::Evaluation &eval) const { - unsigned version = semaCtx.langOptions().OpenMPVersion; + llvm::omp::Version version = semaCtx.langOptions().getOpenMP(); return eval.visit([=](auto &&s) { using BareS = llvm::remove_cvref_t<decltype(s)>; if constexpr (std::is_same_v<BareS, parser::OpenMPConstruct>) { diff --git a/flang/lib/Lower/OpenMP/DataSharingProcessor.h b/flang/lib/Lower/OpenMP/DataSharingProcessor.h index 557584c21123f..c11c427d88c18 100644 --- a/flang/lib/Lower/OpenMP/DataSharingProcessor.h +++ b/flang/lib/Lower/OpenMP/DataSharingProcessor.h @@ -38,7 +38,7 @@ class DataSharingProcessor { /// order to tell which OMP scope defined vs. references a certain Symbol. struct OMPConstructSymbolVisitor { OMPConstructSymbolVisitor(semantics::SemanticsContext &ctx) - : version(ctx.langOptions().OpenMPVersion) {} + : version(ctx.langOptions().getOpenMP()) {} template <typename T> bool Pre(const T &) { return true; @@ -88,7 +88,7 @@ class DataSharingProcessor { llvm::SmallVector<ConstructPtr> constructs; llvm::DenseMap<semantics::Symbol *, ConstructPtr> symDefMap; - unsigned version; + llvm::omp::Version version; }; mlir::OpBuilder::InsertPoint lastPrivIP; @@ -153,7 +153,7 @@ class DataSharingProcessor { void insertDeallocs(); static bool isOpenMPPrivatizingConstruct(const parser::OpenMPConstruct &omp, - unsigned version); + llvm::omp::Version version); bool isOpenMPPrivatizingEvaluation(const pft::Evaluation &eval) const; public: diff --git a/flang/lib/Lower/OpenMP/Decomposer.cpp b/flang/lib/Lower/OpenMP/Decomposer.cpp index 1368d6bac0d88..8ebd9eb738069 100644 --- a/flang/lib/Lower/OpenMP/Decomposer.cpp +++ b/flang/lib/Lower/OpenMP/Decomposer.cpp @@ -42,9 +42,9 @@ struct ConstructDecomposition { llvm::omp::Directive compound, const List<Clause> &clauses) : semaCtx(semaCtx), mod(modOp), eval(ev) { - tomp::ConstructDecompositionT decompose( - mlir::omp::getOpenMPVersionAttribute(modOp), *this, compound, - llvm::ArrayRef(clauses)); + llvm::omp::Version version(mlir::omp::getOpenMPVersionAttribute(modOp)); + tomp::ConstructDecompositionT decompose(version, *this, compound, + llvm::ArrayRef(clauses)); output = std::move(decompose.output); } diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index 3b121a4673c23..04598e6b07541 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -2531,7 +2531,7 @@ genSimdImplicitLinear(lower::AbstractConverter &converter, Fortran::semantics::IsAllocatableOrPointer(loopVar->GetUltimate()))) { mlir::Type ty = converter.genType(*loopVar); typeAttrs.push_back(mlir::TypeAttr::get(ty)); - if (semaCtx.langOptions().OpenMPVersion >= 52) + if (semaCtx.langOptions().getOpenMP() >= 52) linearModAttrs.push_back(mlir::omp::LinearModifierAttr::get( &converter.getMLIRContext(), mlir::omp::LinearModifier::val)); else @@ -7522,7 +7522,7 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, const common::LangOptions &options = semaCtx.langOptions(); if (!options.OpenMPSimd) { std::string name = - parser::omp::GetUpperName(clause.id, options.OpenMPVersion); + parser::omp::GetUpperName(clause.id, options.getOpenMP()); TODO(clauseLocation, name + " clause is not implemented yet"); } } @@ -7732,7 +7732,7 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, // generating the omp.loop_nest op. break; default: { - unsigned version = semaCtx.langOptions().OpenMPVersion; + llvm::omp::Version version = semaCtx.langOptions().getOpenMP(); TODO(currentLocation, "Applying a loop-associated on the loop generated by the " + llvm::omp::getOpenMPDirectiveName(nestedDirective, version) + diff --git a/flang/lib/Lower/PFTBuilder.cpp b/flang/lib/Lower/PFTBuilder.cpp index 351ace166c8c0..91f1fedcd6961 100644 --- a/flang/lib/Lower/PFTBuilder.cpp +++ b/flang/lib/Lower/PFTBuilder.cpp @@ -2629,7 +2629,7 @@ static bool isOmpLoopBody(const Fortran::lower::pft::Evaluation &eval, if (!loop) return false; - unsigned version = semaCtx.langOptions().OpenMPVersion; + llvm::omp::Version version = semaCtx.langOptions().getOpenMP(); auto [depth, _] = semantics::omp::GetAffectedNestDepthWithReason(loop->BeginDir(), version); int64_t n = depth.value.value_or(1); diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 2a9f96618f696..5c9ccf2fed3f1 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -266,7 +266,7 @@ void OmpDirectiveNameParser::initTokens(std::vector<NameWithId> table[]) const { for (size_t i{0}, e{llvm::omp::Directive_enumSize}; i != e; ++i) { llvm::StringSet spellings; auto id{static_cast<llvm::omp::Directive>(i)}; - for (unsigned version : llvm::omp::getOpenMPVersions()) { + for (llvm::omp::Version version : llvm::omp::getOpenMPVersions()) { spellings.insert(llvm::omp::getOpenMPDirectiveName(id, version)); } for (auto &[name, _] : spellings) { @@ -969,7 +969,7 @@ struct OmpMapTypeParser { using resultType = OmpMapType::Value; std::optional<resultType> Parse(ParseState &state) const { - unsigned version{state.userState()->langOptions().OpenMPVersion}; + llvm::omp::Version version{state.userState()->langOptions().getOpenMP()}; if (version < 60) { auto parser{// "ALLOC" >> pure(OmpMapType::Value::Alloc) || @@ -999,7 +999,7 @@ struct OmpMapTypeModifierParser { using resultType = OmpMapTypeModifier::Value; std::optional<resultType> Parse(ParseState &state) const { - unsigned version{state.userState()->langOptions().OpenMPVersion}; + llvm::omp::Version version{state.userState()->langOptions().getOpenMP()}; if (version < 60) { auto parser{// "ALWAYS" >> pure(OmpMapTypeModifier::Value::Always) || @@ -1133,7 +1133,7 @@ template <typename MotionClause> struct OmpMotionClauseModifierParser { using resultType = typename MotionClause::Modifier; std::optional<resultType> Parse(ParseState &state) const { - unsigned version{state.userState()->langOptions().OpenMPVersion}; + llvm::omp::Version version{state.userState()->langOptions().getOpenMP()}; if (version <= 51) { auto motion{sourced(construct<resultType>(Parser<OmpMotionModifier>{}))}; if (auto &&result{attempt(motion).Parse(state)}) { @@ -1178,7 +1178,7 @@ struct OmpLinearClauseModifierParser { using resultType = OmpLinearClause::Modifier; std::optional<resultType> Parse(ParseState &state) const { - unsigned version{state.userState()->langOptions().OpenMPVersion}; + llvm::omp::Version version{state.userState()->langOptions().getOpenMP()}; if (version < 52) { auto parser{sourced( // construct<resultType>(Parser<OmpLinearModifier>{}) || diff --git a/flang/lib/Parser/openmp-utils.cpp b/flang/lib/Parser/openmp-utils.cpp index 4ea10f8a2e156..94fb8bfddd185 100644 --- a/flang/lib/Parser/openmp-utils.cpp +++ b/flang/lib/Parser/openmp-utils.cpp @@ -117,12 +117,12 @@ const OmpDirectiveSpecification &GetOmpDirectiveSpecification( x.u); } -std::string GetUpperName(llvm::omp::Clause id, unsigned version) { +std::string GetUpperName(llvm::omp::Clause id, llvm::omp::Version version) { llvm::StringRef name{llvm::omp::getOpenMPClauseName(id, version)}; return parser::ToUpperCaseLetters(name); } -std::string GetUpperName(llvm::omp::Directive id, unsigned version) { +std::string GetUpperName(llvm::omp::Directive id, llvm::omp::Version version) { llvm::StringRef name{llvm::omp::getOpenMPDirectiveName(id, version)}; return parser::ToUpperCaseLetters(name); } diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 32542d8bc6d5c..a177e90cd6f64 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2172,7 +2172,7 @@ class UnparseVisitor { return false; } void Unparse(const llvm::omp::Directive &x) { - unsigned ompVersion{langOpts_.OpenMPVersion}; + llvm::omp::Version ompVersion{langOpts_.getOpenMP()}; Word(llvm::omp::getOpenMPDirectiveName(x, ompVersion).str()); } void Unparse(const OmpAbsentClause &x) { Walk("", x.v, ","); } @@ -2317,7 +2317,7 @@ class UnparseVisitor { Put(")"); } void Unparse(const OmpDirectiveNameModifier &x) { - unsigned ompVersion{langOpts_.OpenMPVersion}; + llvm::omp::Version ompVersion{langOpts_.getOpenMP()}; Word(llvm::omp::getOpenMPDirectiveName(x.v, ompVersion)); } void Unparse(const OmpDirectiveSpecification &x) { diff --git a/flang/lib/Semantics/check-omp-atomic.cpp b/flang/lib/Semantics/check-omp-atomic.cpp index 7db4bdefa65b0..afc4638ccc692 100644 --- a/flang/lib/Semantics/check-omp-atomic.cpp +++ b/flang/lib/Semantics/check-omp-atomic.cpp @@ -1571,7 +1571,7 @@ static void checkIncompatibleMemoryOrderClause(SemanticsContext &context, llvm::omp::Clause kind{x.GetKind()}; const parser::OmpDirectiveSpecification &dirSpec{x.BeginDir()}; - unsigned version{context.langOptions().OpenMPVersion}; + llvm::omp::Version version{context.langOptions().getOpenMP()}; if (version < 50) return; diff --git a/flang/lib/Semantics/check-omp-loop.cpp b/flang/lib/Semantics/check-omp-loop.cpp index d1c354a9147b0..0cf497d543121 100644 --- a/flang/lib/Semantics/check-omp-loop.cpp +++ b/flang/lib/Semantics/check-omp-loop.cpp @@ -235,7 +235,7 @@ void OmpStructureChecker::CheckSIMDNest(const parser::OpenMPConstruct &c) { void OmpStructureChecker::CheckRectangularNest( const parser::OmpDirectiveSpecification &spec, const LoopSequence &nest) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; auto depth{GetRectangularNestDepthWithReason(spec, version)}; if (!depth || *depth.value == 0) { return; @@ -266,7 +266,7 @@ void OmpStructureChecker::CheckNestedConstruct( const parser::OpenMPLoopConstruct &x) { const parser::OmpDirectiveSpecification &beginSpec{x.BeginDir()}; llvm::omp::Directive dir{beginSpec.DirId()}; - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; parser::CharBlock beginSource{beginSpec.DirName().source}; // End-directive is not allowed in such cases: @@ -489,7 +489,7 @@ const parser::Name OmpStructureChecker::GetLoopIndex( void OmpStructureChecker::CheckIterationVariables( const parser::OpenMPLoopConstruct &x) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; auto doLoops{CollectAffectedDoLoops(x, version, &context_)}; if (!doLoops) { return; @@ -760,7 +760,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Ordered &x) { } void OmpStructureChecker::Enter(const parser::OmpClause::Linear &x) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; llvm::omp::Directive dir{GetContext().directive}; parser::CharBlock clauseSource{GetContext().clauseSource}; const parser::OmpLinearModifier *linearMod{nullptr}; @@ -878,7 +878,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Sizes &c) { } void OmpStructureChecker::Enter(const parser::OmpClause::Permutation &c) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; llvm::omp::Clause clause = llvm::omp::Clause::OMPC_permutation; if (c.v.size() < 2) context_.Say(GetContext().clauseSource, @@ -924,7 +924,7 @@ void OmpStructureChecker::Enter(const parser::DoConstruct &x) { void OmpStructureChecker::Enter(const parser::OmpLoopModifier &x) { DirectiveContext &dirCtx = GetContext(); llvm::omp::Directive dir{dirCtx.directive}; - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; auto &m{std::get<llvm::omp::LoopModifier>(x.t)}; if (!llvm::omp::isAllowedLoopModifier(dir, m)) { llvm::StringRef name = llvm::omp::getLoopModifierName(m); diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index a25f4c39dcd80..41691ff7113cd 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -164,7 +164,7 @@ void OmpStructureChecker::Enter(const parser::SubroutineStmt &x) { } void OmpStructureChecker::CheckTempDescriptorMappings() { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; for (const auto &[symbol, source] : tempDescriptorEnterMaps_) { if (tempDescriptorExitMaps_.find(symbol) == tempDescriptorExitMaps_.end()) { if (version >= 61) { @@ -442,7 +442,7 @@ bool OmpStructureChecker::IsAllowedClause(llvm::omp::Clause clauseId) { return true; } return llvm::omp::isAllowedClauseForDirective( - GetContext().directive, clauseId, context_.langOptions().OpenMPVersion); + GetContext().directive, clauseId, context_.langOptions().getOpenMP()); } bool OmpStructureChecker::CheckAllowedClause(llvm::omp::Clause clauseId, @@ -457,11 +457,11 @@ bool OmpStructureChecker::CheckAllowedClause(llvm::omp::Clause clauseId, return true; } - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; if (!llvm::omp::isAllowedClauseForDirective(dirId, clauseId, version)) { - unsigned allowedInVersion{[&] { - for (unsigned v : llvm::omp::getOpenMPVersions()) { + llvm::omp::Version allowedInVersion{[&] { + for (llvm::omp::Version v : llvm::omp::getOpenMPVersions()) { if (v <= version) { continue; } @@ -469,12 +469,12 @@ bool OmpStructureChecker::CheckAllowedClause(llvm::omp::Clause clauseId, return v; } } - return 0u; + return llvm::omp::Version(); }()}; // 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) { + if (allowedInVersion) { context_.Say(clauseSource, "%s clause is not allowed on %s directive in %s, %s"_err_en_US, GetUpperName(clauseId, version), GetUpperName(dirId, version), @@ -588,7 +588,7 @@ void OmpStructureChecker::CheckLabelContext(const parser::CharBlock source, return getSource(*lhs).Contains(getSource(*rhs)); }; - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; if (tgtOmp && !isSameOrIncludes(tgtOmp, srcOmp)) { parser::OmpDirectiveName name{GetOmpDirectiveName(*tgtOmp)}; context_ @@ -732,7 +732,7 @@ bool OmpStructureChecker::HasRequires(llvm::omp::Clause req) { } void OmpStructureChecker::CheckArgumentObjectKind(const parser::OmpClause &x) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; llvm::omp::Directive dirId{GetContext().directive}; llvm::omp::Clause clauseId{x.Id()}; @@ -901,12 +901,12 @@ void OmpStructureChecker::CheckDirectiveSpelling( ref = ref.drop_front(3); } - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; // For every "future" version v, check if the check if the corresponding // spelling of id was introduced later than the current version. If so, // and if that spelling matches the source spelling, issue a warning. - for (unsigned v : llvm::omp::getOpenMPVersions()) { + for (llvm::omp::Version v : llvm::omp::getOpenMPVersions()) { if (v <= version) { continue; } @@ -917,13 +917,14 @@ void OmpStructureChecker::CheckDirectiveSpelling( assert(kind == id && "Directive kind mismatch"); } - if (static_cast<int>(version) >= versions.Min) { + if (version >= versions.Min) { continue; } if (ref == removeSpaces(name)) { context_.Say(spelling, "Directive spelling '%s' is introduced in a later OpenMP version, %s"_warn_en_US, - parser::ToUpperCaseLetters(ref), TryVersion(versions.Min)); + parser::ToUpperCaseLetters(ref), + TryVersion(llvm::omp::Version(versions.Min))); break; } } @@ -932,7 +933,7 @@ void OmpStructureChecker::CheckDirectiveSpelling( void OmpStructureChecker::CheckDirectiveDeprecation( const parser::OpenMPConstruct &x) { parser::OmpDirectiveName dirName{GetOmpDirectiveName(x)}; - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; // We only want to emit the warning when the version being used has the // directive deprecated if (version >= 52) { @@ -963,10 +964,10 @@ void OmpStructureChecker::CheckDirectiveInPureProcedure( if (!FindPureProcedureContaining(scope)) { return; } - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; // A directive's "pure" property is version-specific: pureSince is the // OpenMP version at which the directive gained that property. - unsigned pureSince{llvm::omp::getDirectivePureSince(id)}; + llvm::omp::Version pureSince{llvm::omp::getDirectivePureSince(id)}; if (version >= pureSince) { return; } @@ -1009,7 +1010,7 @@ OmpStructureChecker::FindMutuallyExclusiveClauses( void OmpStructureChecker::CheckClauses(parser::OmpDirectiveName dirName, llvm::iterator_range<ClauseIterator> beginClauses, llvm::iterator_range<ClauseIterator> endClauses) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; llvm::omp::Directive dirId{dirName.v}; std::vector<const parser::OmpClause *> allClauses; @@ -1512,7 +1513,7 @@ void OmpStructureChecker::CheckTargetNest(const parser::OpenMPConstruct &c) { }, c.u); if (!eligibleTarget) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; context_.Warn(common::UsageWarning::OpenMPUsage, source, "If %s directive is nested inside TARGET region, the behaviour is unspecified"_port_en_US, parser::omp::GetUpperName(ineligibleTargetDir, version)); @@ -1523,7 +1524,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}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; // Missing mandatory end block: this is checked in semantics because that // makes it easier to control the error messages. @@ -1641,7 +1642,7 @@ void OmpStructureChecker::Enter(const parser::OmpBlockConstruct &x) { void OmpStructureChecker::CheckSingleConstruct( const parser::OmpBlockConstruct &x) { const parser::OmpDirectiveSpecification &beginSpec{x.BeginDir()}; - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; SymbolSourceMap copyPrivateSyms; parser::CharBlock nowaitSource1, nowaitSource2; @@ -2040,7 +2041,7 @@ void OmpStructureChecker::Leave(const parser::OmpThreadprivateDirective &x) { void OmpStructureChecker::Enter(const parser::OmpDeclareSimdDirective &x) { const parser::OmpDirectiveName &dirName{x.v.DirName()}; - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; const Scope &containingScope = context_.FindScope(dirName.source); const Scope &progUnitScope = GetProgramUnitContaining(containingScope); @@ -2178,7 +2179,7 @@ void OmpStructureChecker::CheckInitOnDepobj( void OmpStructureChecker::Enter(const parser::OpenMPDepobjConstruct &x) { const auto &dirName{std::get<parser::OmpDirectiveName>(x.v.t)}; - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; const parser::OmpArgumentList &arguments{x.v.Arguments()}; const parser::OmpClauseList &clauses{x.v.Clauses()}; @@ -2233,7 +2234,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPDepobjConstruct &x) { } void OmpStructureChecker::Enter(const parser::OmpRequiresDirective &x) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; for (const parser::OmpClause &clause : x.v.Clauses().v) { llvm::omp::Clause id{clause.Id()}; @@ -2263,11 +2264,12 @@ void OmpStructureChecker::Enter(const parser::OmpRequiresDirective &x) { } }, clause.u)}; - if (version < 60 && hasArgument) { + llvm::omp::Version v60(60); + if (version < v60 && hasArgument) { context_.Say(clause.source, "An argument to %s is an %s feature, %s"_warn_en_US, - parser::omp::GetUpperName(clause.Id(), version), ThisVersion(60), - TryVersion(60)); + parser::omp::GetUpperName(clause.Id(), version), ThisVersion(v60), + TryVersion(v60)); } } } @@ -2345,7 +2347,7 @@ void OmpStructureChecker::CheckIndividualAllocateDirective( auto maybePredefined{maybeHasPredefinedAllocator(allocator)}; - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; std::string condStr{version == 50 ? "a named common block, has SAVE attribute or is declared in the " "scope of a module" @@ -2466,7 +2468,7 @@ void OmpStructureChecker::Enter(const parser::OmpAllocateDirective &x) { bool isExecutable{partStack_.back() == PartKind::ExecutionPart}; - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; if (isExecutable && allocateDirectiveLevel_ == 1 && version >= 52) { context_.Warn(common::UsageWarning::OpenMPUsage, dirName.source, "The executable form of the OpenMP ALLOCATE directive has been deprecated, please use ALLOCATORS instead"_warn_en_US); @@ -2706,7 +2708,7 @@ void OmpStructureChecker::Leave(const parser::OmpDeclareTargetDirective &x) { context_.Say(x.source, "The INDIRECT clause cannot be used without the ENTER clause with the DECLARE TARGET directive."_err_en_US); } - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; if (toClause && version >= 52) { context_.Warn(common::UsageWarning::OpenMPUsage, toClause->source, "The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead."_warn_en_US); @@ -3123,7 +3125,7 @@ struct TaskgraphVisitor { } } - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; bool allowsNogroup{llvm::omp::isAllowedClauseForDirective( leafs[0], llvm::omp::Clause::OMPC_nogroup, version)}; @@ -3262,8 +3264,8 @@ void OmpStructureChecker::CheckTaskgraph(const parser::OmpBlockConstruct &x) { void OmpStructureChecker::CheckTaskDependenceType( const parser::OmpTaskDependenceType::Value &x) { // Common checks for task-dependence-type (DEPEND and UPDATE clauses). - unsigned version{context_.langOptions().OpenMPVersion}; - unsigned since{0}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; + llvm::omp::Version since; switch (x) { case parser::OmpTaskDependenceType::Value::In: @@ -3272,10 +3274,10 @@ void OmpStructureChecker::CheckTaskDependenceType( break; case parser::OmpTaskDependenceType::Value::Mutexinoutset: case parser::OmpTaskDependenceType::Value::Depobj: - since = 50; + since = llvm::omp::Version(50); break; case parser::OmpTaskDependenceType::Value::Inoutset: - since = 52; + since = llvm::omp::Version(52); break; } @@ -3342,7 +3344,7 @@ void OmpStructureChecker::Leave(const parser::OpenMPFlushConstruct &x) { } } - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; if (version >= 52) { auto &flags{std::get<parser::OmpDirectiveSpecification::Flags>(x.v.t)}; if (flags.test(parser::OmpDirectiveSpecification::Flag::DeprecatedSyntax)) { @@ -3486,7 +3488,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}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; if (dir != llvm::omp::Directive::OMPD_cancel && dir != llvm::omp::Directive::OMPD_cancellation_point) { @@ -3532,7 +3534,7 @@ 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}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; std::optional<llvm::omp::Directive> cancelee; std::string cancelName{parser::omp::GetUpperName(cancelDir, version)}; @@ -3562,7 +3564,7 @@ std::optional<llvm::omp::Directive> OmpStructureChecker::GetCancelType( void OmpStructureChecker::CheckCancellationNest( const parser::CharBlock &source, llvm::omp::Directive type) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; std::string typeName{parser::omp::GetUpperName(type, version)}; if (CurrentDirectiveIsNested()) { @@ -3676,7 +3678,7 @@ void OmpStructureChecker::Enter(const parser::OmpClauseList &) { // 3. Checks on clauses which are not in 'struct OmpClause' from parse-tree.h. void OmpStructureChecker::Leave(const parser::OmpClauseList &x) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; // 2.7.1 Loop Construct Restriction if (llvm::omp::allDoSet.test(GetContext().directive)) { @@ -3914,9 +3916,10 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Destroy &x) { } llvm::omp::Directive dir{GetContext().directive}; - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; if (dir == llvm::omp::Directive::OMPD_depobj) { - unsigned argSince{52}, noargDeprecatedIn{52}; + llvm::omp::Version argSince(52); + llvm::omp::Version noargDeprecatedIn(52); if (x.v) { if (version < argSince) { context_.Say(GetContext().clauseSource, @@ -4009,7 +4012,7 @@ 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}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; auto visitOperator{[&](const parser::DefinedOperator &dOpr) { if (const auto *intrinsicOp{ @@ -4076,7 +4079,7 @@ bool OmpStructureChecker::CheckReductionOperator( /// Check restrictions on objects that are common to all reduction clauses. void OmpStructureChecker::CheckReductionObjects( const parser::OmpObjectList &objects, llvm::omp::Clause clauseId) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; SymbolSourceMap symbols; GetSymbolsInObjectList(objects, symbols); @@ -4326,7 +4329,7 @@ void OmpStructureChecker::CheckReductionObjectTypes( void OmpStructureChecker::CheckReductionModifier( const parser::OmpReductionModifier &modifier) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; using ReductionModifier = parser::OmpReductionModifier; if (modifier.v == ReductionModifier::Value::Default) { @@ -4396,7 +4399,7 @@ void OmpStructureChecker::CheckReductionArraySection( void OmpStructureChecker::CheckSharedBindingInOuterContext( const parser::OmpObjectList &redObjectList) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; // TODO: Verify the assumption here that the immediately enclosing region is // the parallel region to which the worksharing construct having reduction // binds to. @@ -4455,7 +4458,7 @@ void OmpStructureChecker::CheckTypeParamInquiry(const parser::CharBlock &source, if (IsTypeParamInquiry(*symbol)) { context_.Say(source, "A type parameter inquiry cannot appear on the %s directive"_err_en_US, - GetUpperName(dirId, context_.langOptions().OpenMPVersion)); + GetUpperName(dirId, context_.langOptions().getOpenMP())); } } } @@ -4466,7 +4469,7 @@ void OmpStructureChecker::CheckTypeParamInquiry(const parser::CharBlock &source, if (IsTypeParamInquiry(*symbol)) { context_.Say(source, "A type parameter inquiry cannot appear on the %s clause"_err_en_US, - GetUpperName(clauseId, context_.langOptions().OpenMPVersion)); + GetUpperName(clauseId, context_.langOptions().getOpenMP())); } } } @@ -4581,7 +4584,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Aligned &x) { } void OmpStructureChecker::Enter(const parser::OmpClause::Defaultmap &x) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; using ImplicitBehavior = parser::OmpDefaultmapClause::ImplicitBehavior; auto behavior{std::get<ImplicitBehavior>(x.v.t)}; if (version <= 45) { @@ -4590,7 +4593,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Defaultmap &x) { "%s is not allowed in %s, %s"_warn_en_US, parser::ToUpperCaseLetters( parser::OmpDefaultmapClause::EnumToString(behavior)), - ThisVersion(version), TryVersion(50)); + ThisVersion(version), TryVersion(llvm::omp::Version(50))); } } if (!OmpVerifyModifiers(x.v, llvm::omp::OMPC_defaultmap, @@ -4604,12 +4607,12 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Defaultmap &x) { if (maybeCategory) { using VariableCategory = parser::OmpVariableCategory; VariableCategory::Value category{maybeCategory->v}; - unsigned tryVersion{0}; + llvm::omp::Version tryVersion; if (version <= 45 && category != VariableCategory::Value::Scalar) { - tryVersion = 50; + tryVersion = llvm::omp::Version(50); } if (version < 52 && category == VariableCategory::Value::All) { - tryVersion = 52; + tryVersion = llvm::omp::Version(52); } if (tryVersion) { context_.Say(GetContext().clauseSource, @@ -4621,7 +4624,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Defaultmap &x) { } void OmpStructureChecker::Enter(const parser::OmpClause::If &x) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; llvm::omp::Directive dir{GetContext().directive}; auto isConstituent{[](llvm::omp::Directive dir, llvm::omp::Directive part) { @@ -4696,21 +4699,21 @@ void OmpStructureChecker::Enter(const parser::OmpClause::If &x) { static auto minVersion{[&](llvm::omp::Directive d) { if (valid45.test(d)) { - return 45; + return llvm::omp::Version(45); } if (valid50.test(d)) { - return 50; + return llvm::omp::Version(50); } if (valid52.test(d)) { - return 52; + return llvm::omp::Version(52); } if (valid60.test(d)) { - return 60; + return llvm::omp::Version(60); } - return 0; + return llvm::omp::Version{}; }}; - static auto suggest{[&](unsigned v) -> std::string { - if (v != 0) { + static auto suggest{[&](llvm::omp::Version v) -> std::string { + if (v) { return ", " + TryVersion(v); } else { return ""; @@ -4761,7 +4764,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::If &x) { } void OmpStructureChecker::Enter(const parser::OmpClause::Detach &x) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; CheckTypeParamInquiry( GetContext().clauseSource, x.v.v, llvm::omp::Clause::OMPC_detach); // OpenMP 5.2: 12.5.2 Detach clause restrictions @@ -4808,7 +4811,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Map &x) { } auto &modifiers{OmpGetModifiers(x.v)}; - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; if (auto commas{std::get<bool>(x.v.t)}; !commas && version >= 52) { context_.Say(GetContext().clauseSource, "The specification of modifiers without comma separators for the " @@ -4829,7 +4832,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Map &x) { mapType = type->v; static auto isValidForVersion{ - [](parser::OmpMapType::Value t, unsigned version) { + [](parser::OmpMapType::Value t, llvm::omp::Version version) { switch (t) { case parser::OmpMapType::Value::Delete: return version < 60; @@ -5025,7 +5028,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Schedule &x) { void OmpStructureChecker::Enter(const parser::OmpClause::Device &x) { const parser::OmpDeviceClause &deviceClause{x.v}; const auto &device{std::get<parser::ScalarIntExpr>(deviceClause.t)}; - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; // The predefined identifiers omp_initial_device (-1) and omp_invalid_device // (-2) were introduced in OpenMP 5.2. Under earlier versions the device // expression must be a non-negative integer. @@ -5061,7 +5064,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Device &x) { void OmpStructureChecker::Enter(const parser::OmpClause::Depend &x) { llvm::omp::Directive dir{GetContext().directive}; - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; auto *doaDep{std::get_if<parser::OmpDoacross>(&x.v.u)}; auto *taskDep{std::get_if<parser::OmpDependClause::TaskDep>(&x.v.u)}; @@ -5245,7 +5248,7 @@ void OmpStructureChecker::CheckDoacross( void OmpStructureChecker::CheckCopyingPolymorphicAllocatable( SymbolSourceMap &symbols, const llvm::omp::Clause clause) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; if (context_.ShouldWarn(common::UsageWarning::Portability)) { for (auto &[symbol, source] : symbols) { if (IsPolymorphicAllocatable(*symbol)) { @@ -5386,7 +5389,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Copyin &x) { void OmpStructureChecker::CheckStructureComponent( const parser::OmpObject &object, llvm::omp::Clause clauseId) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; if (auto *desg{GetDesignatorFromObj(object)}) { if (auto *symbol{GetLastName(*desg).symbol}) { if (!IsTypeParamInquiry(*symbol) && @@ -5413,7 +5416,7 @@ void OmpStructureChecker::CheckStructureComponent( void OmpStructureChecker::Enter( const parser::OmpClause::UpdateDependObjects &x) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; auto *taskType = std::get_if<parser::OmpTaskDependenceType>(&x.v.u); if (taskType) { @@ -5518,7 +5521,7 @@ static constexpr UsesAllocatorsMemSpaceName usesAllocatorsMemSpaceNames[]{ }; static bool IsUsesAllocatorsMemSpaceName( - const parser::Name &name, unsigned version) { + const parser::Name &name, llvm::omp::Version version) { return llvm::any_of(usesAllocatorsMemSpaceNames, [&](const auto &candidate) { return version >= candidate.since && name.ToString() == candidate.name; }); @@ -5560,7 +5563,7 @@ static bool IsIntrinsicOmpAlloctrait( // of a predefined spelling therefore qualifies, while a rename to some other // name does not, even when it denotes the intrinsic entity. static bool IsPredefinedHandle(const parser::Name &name, - llvm::ArrayRef<std::string_view> names, unsigned version) { + llvm::ArrayRef<std::string_view> names, llvm::omp::Version version) { if (version >= 60) { return llvm::is_contained(names, name.ToString()); } @@ -5573,7 +5576,7 @@ static bool IsPredefinedHandle(const parser::Name &name, } static bool ClauseHasTargetEffect(llvm::omp::Directive directive, - llvm::omp::Clause clause, unsigned version) { + llvm::omp::Clause clause, llvm::omp::Version version) { llvm::ArrayRef<llvm::omp::Directive> leafs{ llvm::omp::getLeafConstructsOrSelf(directive)}; if (!llvm::is_contained(leafs, llvm::omp::Directive::OMPD_target)) { @@ -5606,7 +5609,7 @@ static bool ClauseHasTargetEffect(llvm::omp::Directive directive, void OmpStructureChecker::CheckUsesAllocatorsSpec( const parser::OmpUsesAllocatorsClause::AllocatorSpec &spec) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; bool isLegacySyntax{std::get<bool>(spec.t)}; // The traits of the deprecated syntax are stored as a traits-array modifier, @@ -5753,7 +5756,7 @@ void OmpStructureChecker::CheckUsesAllocatorsTraits( return; } const Symbol &ultimate{symbol->GetUltimate()}; - if (context_.langOptions().OpenMPVersion < 60 && + if (context_.langOptions().getOpenMP() < 60 && &ultimate.owner() != &GetScopingUnit(context_.FindScope(GetContext().directiveSource))) { context_.Say(traitsSource, @@ -5785,7 +5788,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::UsesAllocators &x) { return; } - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; const std::list<parser::OmpUsesAllocatorsClause::AllocatorSpec> &specs{x.v.v}; // Classify by the syntax each specification was written in, which the parse @@ -5901,7 +5904,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::From &x) { } auto &modifiers{OmpGetModifiers(x.v)}; - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; if (auto *iter{OmpGetUniqueModifier<parser::OmpIterator>(modifiers)}) { CheckIteratorModifier(*iter); @@ -5924,7 +5927,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::To &x) { } auto &modifiers{OmpGetModifiers(x.v)}; - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; // The "to" clause is only allowed on "declare target" (pre-5.1), and // "target update". In the former case it can take an extended list item, @@ -5953,7 +5956,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::To &x) { } void OmpStructureChecker::Enter(const parser::OmpClause::OmpxBare &x) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; // 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". @@ -5965,13 +5968,13 @@ void OmpStructureChecker::Enter(const parser::OmpClause::OmpxBare &x) { } llvm::StringRef OmpStructureChecker::getClauseName(llvm::omp::Clause clause) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; return llvm::omp::getOpenMPClauseName(clause, version); } llvm::StringRef OmpStructureChecker::getDirectiveName( llvm::omp::Directive directive) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; return llvm::omp::getOpenMPDirectiveName(directive, version); } @@ -5998,7 +6001,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}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; // Sometimes substring operations are incorrectly parsed as array accesses. // Detect this by looking for array accesses on character variables which are // not arrays. @@ -6100,7 +6103,7 @@ void OmpStructureChecker::CheckLastPartRefForArraySection( void OmpStructureChecker::CheckIntentInPointer( SymbolSourceMap &symbols, llvm::omp::Clause clauseId) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; for (auto &[symbol, source] : symbols) { if (IsPointer(*symbol) && IsIntentIn(*symbol)) { context_.Say(source, @@ -6112,7 +6115,7 @@ void OmpStructureChecker::CheckIntentInPointer( void OmpStructureChecker::CheckProcedurePointer( SymbolSourceMap &symbols, llvm::omp::Clause clause) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; for (const auto &[symbol, source] : symbols) { if (IsProcedurePointer(*symbol)) { context_.Say(source, @@ -6162,7 +6165,7 @@ void OmpStructureChecker::GetSymbolsInObjectList( void OmpStructureChecker::CheckDefinableObjects( SymbolSourceMap &symbols, const llvm::omp::Clause clause) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; for (auto &[symbol, source] : symbols) { if (!IsVariableListItem(*symbol)) { continue; @@ -6181,7 +6184,7 @@ void OmpStructureChecker::CheckDefinableObjects( void OmpStructureChecker::CheckPrivateSymbolsInOuterCxt( SymbolSourceMap &currSymbols, DirectivesClauseTriple &dirClauseTriple, const llvm::omp::Clause currClause) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; SymbolSourceMap enclosingSymbols; auto range{dirClauseTriple.equal_range(GetContext().directive)}; for (auto dirIter{range.first}; dirIter != range.second; ++dirIter) { @@ -6307,8 +6310,8 @@ void OmpStructureChecker::CheckWorkshareBlockStmts( void OmpStructureChecker::CheckWorkdistributeBlockStmts( const parser::Block &block, parser::CharBlock source) { - unsigned version{context_.langOptions().OpenMPVersion}; - unsigned since{60}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; + llvm::omp::Version since(60); if (version < since) context_.Say(source, "WORKDISTRIBUTE construct is not allowed in %s, %s"_err_en_US, @@ -6385,7 +6388,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::DynamicAllocators &x) { void OmpStructureChecker::Enter(const parser::OmpClause::ReverseOffload &x) { CheckAllowedRequiresClause(llvm::omp::Clause::OMPC_reverse_offload); if (IsAllowedClause(llvm::omp::Clause::OMPC_reverse_offload)) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; context_.Say(GetContext().clauseSource, "%s clause is not supported and will be ignored"_warn_en_US, GetUpperName(llvm::omp::Clause::OMPC_reverse_offload, version)); @@ -6682,7 +6685,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPInteropConstruct &x) { } void OmpStructureChecker::CheckAllowedRequiresClause(llvm::omp::Clause clause) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; if (clause != llvm::omp::Clause::OMPC_atomic_default_mem_order) { // Check that it does not appear after a device construct diff --git a/flang/lib/Semantics/check-omp-variant.cpp b/flang/lib/Semantics/check-omp-variant.cpp index 0f8daf84d25ec..5573afc3ffb84 100644 --- a/flang/lib/Semantics/check-omp-variant.cpp +++ b/flang/lib/Semantics/check-omp-variant.cpp @@ -170,7 +170,7 @@ void OmpStructureChecker::CheckDefaultNoneInAssociatedLoop( } SymbolSourceMap explicitDSA; - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; for (const parser::OmpClause &clause : spec.Clauses().v) { if (llvm::omp::isDataSharingAttributeClause(clause.Id(), version)) { if (const parser::OmpObjectList *objects{ @@ -655,7 +655,7 @@ void OmpStructureChecker::CheckTraitDeviceNum( void OmpStructureChecker::CheckTraitRequires( const parser::OmpTraitSetSelector &traitSet, const parser::OmpTraitSelector &trait) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; auto &traitName{std::get<parser::OmpTraitSelectorName>(trait.t)}; auto &properties{GetTraitPropertyList(trait)}; @@ -680,7 +680,7 @@ void OmpStructureChecker::CheckTraitRequires( void OmpStructureChecker::CheckTraitSimd( const parser::OmpTraitSetSelector &traitSet, const parser::OmpTraitSelector &trait) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; auto &traitName{std::get<parser::OmpTraitSelectorName>(trait.t)}; auto &properties{GetTraitPropertyList(trait)}; @@ -719,7 +719,7 @@ void OmpStructureChecker::Enter(const parser::OmpDirectiveSpecification &x) { if (const parser::OpenMPConstruct *meta{GetCurrentConstruct()}) { if (parser::Unwrap<parser::OmpDelimitedMetadirectiveDirective>(meta->u)) { checkDefaultNoneInAssociatedLoop = false; - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; switch (llvm::omp::getDirectiveAssociation(dirId)) { case llvm::omp::Association::Block: case llvm::omp::Association::LoopNest: @@ -786,7 +786,7 @@ void OmpStructureChecker::Enter(const parser::ExecutionPartConstruct &x) { std::vector<MetadirectiveLoopVariant> variants; variants.swap(metadirectiveLoopVariants_); - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; LoopSequence sequence(x, version, /*allowAllLoops=*/true, &context_); const parser::DoConstruct &rootLoop{*parser::Unwrap<parser::DoConstruct>(x)}; const auto &[haveSemantic, havePerfect]{sequence.depth()}; diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp index e0fabd989bb45..b6c6a36575562 100644 --- a/flang/lib/Semantics/mod-file.cpp +++ b/flang/lib/Semantics/mod-file.cpp @@ -382,7 +382,7 @@ static const WithOmpDeclarative *GetOmpDeclarative(const Symbol &symbol) { static void PutOpenMPRequirements( llvm::raw_ostream &os, const Symbol &symbol, SemanticsContext &semaCtx) { - unsigned version{semaCtx.langOptions().OpenMPVersion}; + llvm::omp::Version version{semaCtx.langOptions().getOpenMP()}; if (const auto *decls{GetOmpDeclarative(symbol)}) { if (const llvm::omp::ClauseSet &reqs{decls->ompRequires()}; reqs.count()) { @@ -397,7 +397,7 @@ static void PutOpenMPRequirements( static void PutOpenMPDeclarativeDirectives(llvm::raw_ostream &os, const SymbolVector &symbols, SemanticsContext &semaCtx) { - unsigned version{semaCtx.langOptions().OpenMPVersion}; + llvm::omp::Version version{semaCtx.langOptions().getOpenMP()}; for (const Symbol &symbol : symbols) { if (const auto *decls{GetOmpDeclarative(symbol)}) { diff --git a/flang/lib/Semantics/openmp-utils.cpp b/flang/lib/Semantics/openmp-utils.cpp index dc3d5a302e841..a19bde31643d8 100644 --- a/flang/lib/Semantics/openmp-utils.cpp +++ b/flang/lib/Semantics/openmp-utils.cpp @@ -116,14 +116,15 @@ SourcedActionStmt GetActionStmt(const parser::Block &block) { return SourcedActionStmt{}; } -std::string ThisVersion(unsigned version) { - std::string tv{ - std::to_string(version / 10) + "." + std::to_string(version % 10)}; +std::string ThisVersion(llvm::omp::Version version) { + auto v{static_cast<unsigned>(version)}; + std::string tv{std::to_string(v / 10) + "." + std::to_string(v % 10)}; return "OpenMP v" + tv; } -std::string TryVersion(unsigned version) { - return "try -fopenmp-version=" + std::to_string(version); +std::string TryVersion(llvm::omp::Version version) { + return "try -fopenmp-version=" + + std::to_string(static_cast<unsigned>(version)); } static const Symbol *GetFunctionReferenceSymbol( @@ -686,7 +687,7 @@ MaybeExpr MakeEvaluateExpr(const parser::OmpStylizedInstance &inp) { /// For clauses that take argument lists, return the type of the argument /// list item. For other clauses return std::nullopt. std::optional<ListItemKind> GetArgumentListItemKind( - llvm::omp::Clause clause, unsigned version) { + llvm::omp::Clause clause, llvm::omp::Version version) { switch (clause) { case llvm::omp::Clause::OMPC_absent: if (version >= 51) { @@ -1039,7 +1040,7 @@ static SymbolVector SelectUsedSymbols( WithReason<int64_t> GetArgumentValueWithReason( const parser::OmpDirectiveSpecification &spec, llvm::omp::Clause clauseId, - unsigned version, SemanticsContext *semaCtx) { + llvm::omp::Version version, SemanticsContext *semaCtx) { if (auto *clause{parser::omp::FindClause(spec, clauseId)}) { if (auto *expr{parser::Unwrap<parser::Expr>(clause->u)}) { if (auto value{GetIntValueFromExpr(*expr, semaCtx)}) { @@ -1071,7 +1072,7 @@ static WithReason<int64_t> GetNumArgumentsWithReasonForType( WithReason<int64_t> GetNumArgumentsWithReason( const parser::OmpDirectiveSpecification &spec, llvm::omp::Clause clauseId, - unsigned version, SemanticsContext *semaCtx) { + llvm::omp::Version version, SemanticsContext *semaCtx) { if (auto *clause{parser::omp::FindClause(spec, clauseId)}) { std::string name{GetUpperName(clauseId, version)}; // Try the types used for list items. @@ -1092,7 +1093,7 @@ WithReason<int64_t> GetNumArgumentsWithReason( } WithReason<int64_t> GetHeightWithReason( - const parser::OmpDirectiveSpecification &spec, unsigned version, + const parser::OmpDirectiveSpecification &spec, llvm::omp::Version version, SemanticsContext *semaCtx) { bool isFullUnroll{IsFullUnroll(spec)}; @@ -1294,7 +1295,7 @@ WithReason<T> operator+(T a, const WithReason<T> &b) { /// Return the depth of the affected nest(s): /// {affected-depth, must-be-perfect-nest}. std::pair<WithReason<int64_t>, bool> GetAffectedNestDepthWithReason( - const parser::OmpDirectiveSpecification &spec, unsigned version, + const parser::OmpDirectiveSpecification &spec, llvm::omp::Version version, SemanticsContext *semaCtx) { llvm::omp::Directive dir{spec.DirId()}; bool allowsCollapse{llvm::omp::isAllowedClauseForDirective( @@ -1411,7 +1412,7 @@ std::pair<WithReason<int64_t>, bool> GetAffectedNestDepthWithReason( /// Return the depth of the generated nest(s) /// {generated-depth, is-perfect-nest} std::pair<WithReason<int64_t>, bool> GetGeneratedNestDepthWithReason( - const parser::OmpDirectiveSpecification &spec, unsigned version, + const parser::OmpDirectiveSpecification &spec, llvm::omp::Version version, SemanticsContext *semaCtx) { llvm::omp::Directive dir{spec.DirId()}; if (!IsLoopTransforming(dir)) { @@ -1451,7 +1452,7 @@ std::pair<WithReason<int64_t>, bool> GetGeneratedNestDepthWithReason( /// Return the range of the affected nests in the sequence: /// {first, count} WithReason<std::pair<int64_t, int64_t>> GetAffectedLoopRangeWithReason( - const parser::OmpDirectiveSpecification &spec, unsigned version, + const parser::OmpDirectiveSpecification &spec, llvm::omp::Version version, SemanticsContext *semaCtx) { llvm::omp::Directive dir{spec.DirId()}; @@ -1490,7 +1491,7 @@ WithReason<std::pair<int64_t, int64_t>> GetAffectedLoopRangeWithReason( } WithReason<int64_t> GetRectangularNestDepthWithReason( - const parser::OmpDirectiveSpecification &spec, unsigned version, + const parser::OmpDirectiveSpecification &spec, llvm::omp::Version version, SemanticsContext *semaCtx) { auto [depth, _]{GetAffectedNestDepthWithReason(spec, version, semaCtx)}; if (!depth) { @@ -1637,7 +1638,7 @@ bool IsDoacrossAffected(const parser::OpenMPLoopConstruct &x) { /// For the top-level DO COLLAPSE(5) construct, the k loop is the only /// directly affected loop. std::optional<std::vector<const parser::DoConstruct *>> CollectAffectedDoLoops( - const parser::OpenMPLoopConstruct &x, unsigned version, + const parser::OpenMPLoopConstruct &x, llvm::omp::Version version, SemanticsContext *semaCtx) { std::vector<const parser::DoConstruct *> result; const parser::OmpDirectiveSpecification &spec{x.BeginDir()}; @@ -1770,7 +1771,7 @@ static_assert(HasSourceT<parser::ExecutionPartConstruct>::value); #endif // EXPENSIVE_CHECKS LoopSequence::LoopSequence(const parser::ExecutionPartConstruct &root, - unsigned version, bool allowAllLoops, SemanticsContext *semaCtx) + llvm::omp::Version version, bool allowAllLoops, SemanticsContext *semaCtx) : version_(version), allowAllLoops_(allowAllLoops), semaCtx_(semaCtx) { entry_ = createConstructEntry(root); assert(entry_ && "Expecting loop like code"); @@ -1779,8 +1780,8 @@ LoopSequence::LoopSequence(const parser::ExecutionPartConstruct &root, precalculate(); } -LoopSequence::LoopSequence(std::unique_ptr<Construct> entry, unsigned version, - bool allowAllLoops, SemanticsContext *semaCtx) +LoopSequence::LoopSequence(std::unique_ptr<Construct> entry, + llvm::omp::Version version, bool allowAllLoops, SemanticsContext *semaCtx) : version_(version), allowAllLoops_(allowAllLoops), entry_(std::move(entry)), semaCtx_(semaCtx) { createChildrenFromRange(entry_->location); diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index 532f1f821b8f2..f7e4abe99e2ba 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -914,7 +914,7 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> { } void Post(const parser::OmpMapClause &x) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; std::optional<Symbol::Flag> ompFlag; auto &mods{OmpGetModifiers(x)}; @@ -2135,7 +2135,7 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPLoopConstruct &x) { void OmpAttributeVisitor::ResolveSeqLoopIndexInParallelOrTaskConstruct( const parser::Name &iv) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; // Find the parallel, teams or task generating construct enclosing the // sequential loop. auto targetIt{dirContext_.rbegin()}; @@ -2226,7 +2226,7 @@ bool OmpAttributeVisitor::Pre(const parser::DoConstruct &x) { void OmpAttributeVisitor::PrivatizeAssociatedLoopIndex( const parser::OpenMPLoopConstruct &x) { const parser::OmpDirectiveSpecification &spec{x.BeginDir()}; - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; auto [depth, _]{ omp::GetAffectedNestDepthWithReason(spec, version, &context_)}; @@ -2282,7 +2282,7 @@ bool OmpAttributeVisitor::Pre(const parser::OmpGroupprivateDirective &x) { device = parser::UnwrapRef<common::OmpDeviceType>(*devClause); } - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; llvm::omp::ClauseSet clauses{llvm::omp::Clause::OMPC_device_type}; for (const parser::OmpArgument &arg : x.v.Arguments().v) { if (const parser::OmpObject *object{parser::omp::GetArgumentObject(arg)}) { @@ -2336,7 +2336,7 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPCriticalConstruct &x) { bool OmpAttributeVisitor::Pre(const parser::OmpDeclareTargetDirective &x) { PushContext(x.source, llvm::omp::Directive::OMPD_declare_target); - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; std::map<const Symbol *, WithOmpDeclarative> details; std::optional<common::OmpDeviceType> device; @@ -3044,7 +3044,7 @@ static bool SymbolOrEquivalentIsInNamelist(const Symbol &symbol) { void OmpAttributeVisitor::ResolveOmpDesignator( const parser::Designator &designator, Symbol::Flag ompFlag) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; llvm::omp::Directive directive{GetContext().directive}; const auto *name{parser::GetDesignatorNameIfDataRef(designator)}; @@ -3430,7 +3430,7 @@ void OmpAttributeVisitor::CheckObjectIsPrivatizable( void OmpAttributeVisitor::AddOmpRequiresToScope(Scope &scope, const llvm::omp::ClauseSet &reqs, const std::optional<common::OmpMemoryOrderType> &memOrder) { - unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Version version{context_.langOptions().getOpenMP()}; const Scope &programUnit{omp::GetProgramUnit(scope)}; if (auto *symbol{const_cast<Symbol *>(programUnit.symbol())}) { diff --git a/flang/unittests/Semantics/OpenMPUtils.cpp b/flang/unittests/Semantics/OpenMPUtils.cpp index 7b003d8fa4af8..aee4b452ec87f 100644 --- a/flang/unittests/Semantics/OpenMPUtils.cpp +++ b/flang/unittests/Semantics/OpenMPUtils.cpp @@ -201,7 +201,8 @@ TEST_F(OpenMPUtilsTest, AffectedNestDepthNoClauses) { auto &body = std::get<parser::ExecutionPart>(mainProgram.t).v; auto &omp = parser::UnwrapRef<parser::OpenMPLoopConstruct>(body.front()); auto [depth, mustBePerfect] = - semantics::omp::GetAffectedNestDepthWithReason(omp.BeginDir(), 60); + semantics::omp::GetAffectedNestDepthWithReason( + omp.BeginDir(), llvm::omp::Version(60)); EXPECT_TRUE(depth.value.has_value()); if (depth) { EXPECT_EQ(*depth.value, 1); @@ -245,7 +246,8 @@ TEST_F(OpenMPUtilsTest, AffectedNestDepthCollapse) { auto &body = std::get<parser::ExecutionPart>(mainProgram.t).v; auto &omp = parser::UnwrapRef<parser::OpenMPLoopConstruct>(body.front()); auto [depth, mustBePerfect] = - semantics::omp::GetAffectedNestDepthWithReason(omp.BeginDir(), 60); + semantics::omp::GetAffectedNestDepthWithReason( + omp.BeginDir(), llvm::omp::Version(60)); EXPECT_TRUE(depth.value.has_value()); if (depth) { EXPECT_EQ(*depth.value, 2); @@ -293,7 +295,8 @@ TEST_F(OpenMPUtilsTest, AffectedNestDepthCollapseOrdered) { auto &body = std::get<parser::ExecutionPart>(mainProgram.t).v; auto &omp = parser::UnwrapRef<parser::OpenMPLoopConstruct>(body.front()); auto [depth, mustBePerfect] = - semantics::omp::GetAffectedNestDepthWithReason(omp.BeginDir(), 60); + semantics::omp::GetAffectedNestDepthWithReason( + omp.BeginDir(), llvm::omp::Version(60)); EXPECT_TRUE(depth.value.has_value()); if (depth) { EXPECT_EQ(*depth.value, 3); diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPVersion.h b/llvm/include/llvm/Frontend/OpenMP/OMPVersion.h index 508c14b3df4ab..6b8b533ea7ede 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMPVersion.h +++ b/llvm/include/llvm/Frontend/OpenMP/OMPVersion.h @@ -19,8 +19,8 @@ namespace llvm { namespace omp { struct Version { using value_type = unsigned; - constexpr Version(value_type Ver = 0) : V(Ver) {} - constexpr operator value_type() const { return V; } + constexpr explicit Version(value_type Ver = 0) : V(Ver) {} + constexpr explicit operator value_type() const { return V; } constexpr explicit operator bool() const { return V != 0; } friend constexpr bool operator<(Version A, Version B); @@ -40,12 +40,14 @@ inline constexpr bool operator>(Version A, Version B) { return !(A <= B); } inline constexpr bool operator>=(Version A, Version B) { return !(A < B); } inline constexpr bool operator==(Version A, int B) { return A == Version(B); } -inline constexpr bool operator==(Version A, unsigned B) { return A == Version(B); } inline constexpr bool operator!=(Version A, int B) { return A != Version(B); } inline constexpr bool operator<(Version A, int B) { return A < Version(B); } inline constexpr bool operator<=(Version A, int B) { return A <= Version(B); } inline constexpr bool operator>(Version A, int B) { return A > Version(B); } inline constexpr bool operator>=(Version A, int B) { return A >= Version(B); } +//inline constexpr bool operator<(int A, Version B) { return Version(A) < B; } +//inline constexpr bool operator<=(int A, Version B) { return Version(A) <= B; } +//inline constexpr bool operator>=(int A, Version B) { return Version(A) >= B; } } // namespace omp template <> struct DenseMapInfo<omp::Version> { _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
