//===-- Clauses.h -- OpenMP clause handling -------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef FORTRAN_LOWER_OPENMP_CLAUSES_H #define FORTRAN_LOWER_OPENMP_CLAUSES_H #include "ClauseT.h" #include "flang/Evaluate/expression.h" #include "flang/Parser/parse-tree.h" #include "flang/Semantics/expression.h" #include "flang/Semantics/semantics.h" #include "flang/Semantics/symbol.h" #include "llvm/ADT/STLExtras.h" #include #include #include namespace Fortran::lower::omp { using namespace Fortran; using SomeType = evaluate::SomeType; using SomeExpr = semantics::SomeExpr; using MaybeExpr = semantics::MaybeExpr; using SymIdent = semantics::Symbol *; using SymReference = SomeExpr; template using List = tomp::ListT; } // namespace Fortran::lower::omp namespace tomp { template <> struct ObjectT { using IdType = Fortran::lower::omp::SymIdent; using ExprType = Fortran::lower::omp::SymReference; const IdType &id() const { return symbol; } const std::optional &ref() const { return designator; } IdType symbol; std::optional designator; }; } // namespace tomp namespace Fortran::lower::omp { using Object = tomp::ObjectT; using ObjectList = tomp::ObjectListT; Object makeObject(const parser::OmpObject &object, semantics::SemanticsContext &semaCtx); Object makeObject(const parser::Name &name, semantics::SemanticsContext &semaCtx); Object makeObject(const parser::Designator &dsg, semantics::SemanticsContext &semaCtx); Object makeObject(const parser::StructureComponent &comp, semantics::SemanticsContext &semaCtx); inline auto makeObjectFn(semantics::SemanticsContext &semaCtx) { return [&](auto &&s) { return makeObject(s, semaCtx); }; } template SomeExpr makeExpr(T &&pftExpr, semantics::SemanticsContext &semaCtx) { auto maybeExpr = evaluate::ExpressionAnalyzer(semaCtx).Analyze(pftExpr); assert(maybeExpr); return std::move(*maybeExpr); } inline auto makeExprFn(semantics::SemanticsContext &semaCtx) { return [&](auto &&s) { return makeExpr(s, semaCtx); }; } template < typename ContainerTy, typename FunctionTy, typename ElemTy = typename llvm::remove_cvref_t::value_type, typename ResultTy = std::invoke_result_t> List makeList(ContainerTy &&container, FunctionTy &&func) { List v; llvm::transform(container, std::back_inserter(v), func); return v; } inline ObjectList makeList(const parser::OmpObjectList &objects, semantics::SemanticsContext &semaCtx) { return makeList(objects.v, makeObjectFn(semaCtx)); } template > std::optional maybeApply(FuncTy &&func, const std::optional &inp) { if (!inp) return std::nullopt; return std::move(func(*inp)); } std::optional getBaseObject(const Object &object, Fortran::semantics::SemanticsContext &semaCtx); namespace clause { #ifdef EMPTY_CLASS #undef EMPTY_CLASS #endif #define EMPTY_CLASS(cls) \ using cls = tomp::clause::cls##T #ifdef WRAPPER_CLASS #undef WRAPPER_CLASS #endif #define WRAPPER_CLASS(cls, content) \ [[maybe_unused]] extern int xyzzy_semicolon_absorber #define GEN_FLANG_CLAUSE_PARSER_CLASSES #include "llvm/Frontend/OpenMP/OMP.inc" #undef EMPTY_CLASS #undef WRAPPER_CLASS using DefinedOperator = tomp::clause::DefinedOperatorT; using ProcedureDesignator = tomp::clause::ProcedureDesignatorT; using ReductionOperator = tomp::clause::ReductionOperatorT; // "Requires" clauses are handled early on, and the aggregated information // is stored in the Symbol details of modules, programs, and subprograms. // These clauses are still handled here to cover all alternatives in the // main clause variant. using Aligned = tomp::clause::AlignedT; using Allocate = tomp::clause::AllocateT; using Allocator = tomp::clause::AllocatorT; using AtomicDefaultMemOrder = tomp::clause::AtomicDefaultMemOrderT; using Collapse = tomp::clause::CollapseT; using Copyin = tomp::clause::CopyinT; using Copyprivate = tomp::clause::CopyprivateT; using Defaultmap = tomp::clause::DefaultmapT; using Default = tomp::clause::DefaultT; using Depend = tomp::clause::DependT; using Device = tomp::clause::DeviceT; using DeviceType = tomp::clause::DeviceTypeT; using DistSchedule = tomp::clause::DistScheduleT; using Enter = tomp::clause::EnterT; using Filter = tomp::clause::FilterT; using Final = tomp::clause::FinalT; using Firstprivate = tomp::clause::FirstprivateT; using From = tomp::clause::FromT; using Grainsize = tomp::clause::GrainsizeT; using HasDeviceAddr = tomp::clause::HasDeviceAddrT; using Hint = tomp::clause::HintT; using If = tomp::clause::IfT; using InReduction = tomp::clause::InReductionT; using IsDevicePtr = tomp::clause::IsDevicePtrT; using Lastprivate = tomp::clause::LastprivateT; using Linear = tomp::clause::LinearT; using Link = tomp::clause::LinkT; using Map = tomp::clause::MapT; using Nocontext = tomp::clause::NocontextT; using Nontemporal = tomp::clause::NontemporalT; using Novariants = tomp::clause::NovariantsT; using NumTasks = tomp::clause::NumTasksT; using NumTeams = tomp::clause::NumTeamsT; using NumThreads = tomp::clause::NumThreadsT; using OmpxDynCgroupMem = tomp::clause::OmpxDynCgroupMemT; using Ordered = tomp::clause::OrderedT; using Order = tomp::clause::OrderT; using Partial = tomp::clause::PartialT; using Priority = tomp::clause::PriorityT; using Private = tomp::clause::PrivateT; using ProcBind = tomp::clause::ProcBindT; using Reduction = tomp::clause::ReductionT; using Safelen = tomp::clause::SafelenT; using Schedule = tomp::clause::ScheduleT; using Shared = tomp::clause::SharedT; using Simdlen = tomp::clause::SimdlenT; using Sizes = tomp::clause::SizesT; using TaskReduction = tomp::clause::TaskReductionT; using ThreadLimit = tomp::clause::ThreadLimitT; using To = tomp::clause::ToT; using Uniform = tomp::clause::UniformT; using UseDeviceAddr = tomp::clause::UseDeviceAddrT; using UseDevicePtr = tomp::clause::UseDevicePtrT; } // namespace clause struct Clause : public tomp::ClauseT { parser::CharBlock source; }; template Clause makeClause(llvm::omp::Clause id, Specific &&specific, parser::CharBlock source = {}) { return Clause{{id, specific}, source}; } Clause makeClause(const Fortran::parser::OmpClause &cls, semantics::SemanticsContext &semaCtx); List makeList(const parser::OmpClauseList &clauses, semantics::SemanticsContext &semaCtx); } // namespace Fortran::lower::omp #endif // FORTRAN_LOWER_OPENMP_CLAUSES_H