1ea2cfcc1SKrzysztof Parzyszek //===-- Clauses.cpp -- OpenMP clause handling -----------------------------===// 2ea2cfcc1SKrzysztof Parzyszek // 3ea2cfcc1SKrzysztof Parzyszek // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4ea2cfcc1SKrzysztof Parzyszek // See https://llvm.org/LICENSE.txt for license information. 5ea2cfcc1SKrzysztof Parzyszek // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6ea2cfcc1SKrzysztof Parzyszek // 7ea2cfcc1SKrzysztof Parzyszek //===----------------------------------------------------------------------===// 8ea2cfcc1SKrzysztof Parzyszek 9ea2cfcc1SKrzysztof Parzyszek #include "Clauses.h" 10ea2cfcc1SKrzysztof Parzyszek 11ea2cfcc1SKrzysztof Parzyszek #include "flang/Common/idioms.h" 12ea2cfcc1SKrzysztof Parzyszek #include "flang/Evaluate/expression.h" 1392604d7cSMats Petersson #include "flang/Optimizer/Builder/Todo.h" 14ea2cfcc1SKrzysztof Parzyszek #include "flang/Parser/parse-tree.h" 15ea2cfcc1SKrzysztof Parzyszek #include "flang/Semantics/expression.h" 164fc1141eSKrzysztof Parzyszek #include "flang/Semantics/openmp-modifiers.h" 17ea2cfcc1SKrzysztof Parzyszek #include "flang/Semantics/symbol.h" 18ea2cfcc1SKrzysztof Parzyszek 19ea2cfcc1SKrzysztof Parzyszek #include "llvm/Frontend/OpenMP/OMPConstants.h" 20ea2cfcc1SKrzysztof Parzyszek 21ea2cfcc1SKrzysztof Parzyszek #include <list> 22ea2cfcc1SKrzysztof Parzyszek #include <optional> 23ea2cfcc1SKrzysztof Parzyszek #include <tuple> 24ea2cfcc1SKrzysztof Parzyszek #include <utility> 25ea2cfcc1SKrzysztof Parzyszek #include <variant> 26ea2cfcc1SKrzysztof Parzyszek 27f9e55796SKrzysztof Parzyszek namespace Fortran::lower::omp { 28ea2cfcc1SKrzysztof Parzyszek using SymbolWithDesignator = std::tuple<semantics::Symbol *, MaybeExpr>; 29ea2cfcc1SKrzysztof Parzyszek 30ea2cfcc1SKrzysztof Parzyszek struct SymbolAndDesignatorExtractor { 31ea2cfcc1SKrzysztof Parzyszek template <typename T> 32ea2cfcc1SKrzysztof Parzyszek static T &&AsRvalueRef(T &&t) { 33ea2cfcc1SKrzysztof Parzyszek return std::move(t); 34ea2cfcc1SKrzysztof Parzyszek } 35ea2cfcc1SKrzysztof Parzyszek template <typename T> 36ea2cfcc1SKrzysztof Parzyszek static T AsRvalueRef(const T &t) { 37ea2cfcc1SKrzysztof Parzyszek return t; 38ea2cfcc1SKrzysztof Parzyszek } 39ea2cfcc1SKrzysztof Parzyszek 40ea2cfcc1SKrzysztof Parzyszek static semantics::Symbol *symbol_addr(const evaluate::SymbolRef &ref) { 41ea2cfcc1SKrzysztof Parzyszek // Symbols cannot be created after semantic checks, so all symbol 42ea2cfcc1SKrzysztof Parzyszek // pointers that are non-null must point to one of those pre-existing 43ea2cfcc1SKrzysztof Parzyszek // objects. Throughout the code, symbols are often pointed to by 44ea2cfcc1SKrzysztof Parzyszek // non-const pointers, so there is no harm in casting the constness 45ea2cfcc1SKrzysztof Parzyszek // away. 46ea2cfcc1SKrzysztof Parzyszek return const_cast<semantics::Symbol *>(&ref.get()); 47ea2cfcc1SKrzysztof Parzyszek } 48ea2cfcc1SKrzysztof Parzyszek 49ea2cfcc1SKrzysztof Parzyszek template <typename T> 50ea2cfcc1SKrzysztof Parzyszek static SymbolWithDesignator visit(T &&) { 51ea2cfcc1SKrzysztof Parzyszek // Use this to see missing overloads: 52ea2cfcc1SKrzysztof Parzyszek // llvm::errs() << "NULL: " << __PRETTY_FUNCTION__ << '\n'; 53ea2cfcc1SKrzysztof Parzyszek return SymbolWithDesignator{}; 54ea2cfcc1SKrzysztof Parzyszek } 55ea2cfcc1SKrzysztof Parzyszek 56ea2cfcc1SKrzysztof Parzyszek template <typename T> 57ea2cfcc1SKrzysztof Parzyszek static SymbolWithDesignator visit(const evaluate::Designator<T> &e) { 58ea2cfcc1SKrzysztof Parzyszek return std::make_tuple(symbol_addr(*e.GetLastSymbol()), 59ea2cfcc1SKrzysztof Parzyszek evaluate::AsGenericExpr(AsRvalueRef(e))); 60ea2cfcc1SKrzysztof Parzyszek } 61ea2cfcc1SKrzysztof Parzyszek 62ea2cfcc1SKrzysztof Parzyszek static SymbolWithDesignator visit(const evaluate::ProcedureDesignator &e) { 63ea2cfcc1SKrzysztof Parzyszek return std::make_tuple(symbol_addr(*e.GetSymbol()), std::nullopt); 64ea2cfcc1SKrzysztof Parzyszek } 65ea2cfcc1SKrzysztof Parzyszek 66ea2cfcc1SKrzysztof Parzyszek template <typename T> 67ea2cfcc1SKrzysztof Parzyszek static SymbolWithDesignator visit(const evaluate::Expr<T> &e) { 6877d8cfb3SAlexander Shaposhnikov return Fortran::common::visit([](auto &&s) { return visit(s); }, e.u); 69ea2cfcc1SKrzysztof Parzyszek } 70ea2cfcc1SKrzysztof Parzyszek 71ea2cfcc1SKrzysztof Parzyszek static void verify(const SymbolWithDesignator &sd) { 72ea2cfcc1SKrzysztof Parzyszek const semantics::Symbol *symbol = std::get<0>(sd); 73ea2cfcc1SKrzysztof Parzyszek assert(symbol && "Expecting symbol"); 74ea2cfcc1SKrzysztof Parzyszek auto &maybeDsg = std::get<1>(sd); 75ea2cfcc1SKrzysztof Parzyszek if (!maybeDsg) 76ea2cfcc1SKrzysztof Parzyszek return; // Symbol with no designator -> OK 77ea2cfcc1SKrzysztof Parzyszek std::optional<evaluate::DataRef> maybeRef = 78ea2cfcc1SKrzysztof Parzyszek evaluate::ExtractDataRef(*maybeDsg); 79ea2cfcc1SKrzysztof Parzyszek if (maybeRef) { 80ea2cfcc1SKrzysztof Parzyszek if (&maybeRef->GetLastSymbol() == symbol) 81ea2cfcc1SKrzysztof Parzyszek return; // Symbol with a designator for it -> OK 82ea2cfcc1SKrzysztof Parzyszek llvm_unreachable("Expecting designator for given symbol"); 83ea2cfcc1SKrzysztof Parzyszek } else { 84ea2cfcc1SKrzysztof Parzyszek // This could still be a Substring or ComplexPart, but at least Substring 85ea2cfcc1SKrzysztof Parzyszek // is not allowed in OpenMP. 865a77bdc3SKrzysztof Parzyszek #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 87ea2cfcc1SKrzysztof Parzyszek maybeDsg->dump(); 885a77bdc3SKrzysztof Parzyszek #endif 89ea2cfcc1SKrzysztof Parzyszek llvm_unreachable("Expecting DataRef designator"); 90ea2cfcc1SKrzysztof Parzyszek } 91ea2cfcc1SKrzysztof Parzyszek } 92ea2cfcc1SKrzysztof Parzyszek }; 93ea2cfcc1SKrzysztof Parzyszek 94ea2cfcc1SKrzysztof Parzyszek SymbolWithDesignator getSymbolAndDesignator(const MaybeExpr &expr) { 95ea2cfcc1SKrzysztof Parzyszek if (!expr) 96ea2cfcc1SKrzysztof Parzyszek return SymbolWithDesignator{}; 9777d8cfb3SAlexander Shaposhnikov return Fortran::common::visit( 98ea2cfcc1SKrzysztof Parzyszek [](auto &&s) { return SymbolAndDesignatorExtractor::visit(s); }, expr->u); 99ea2cfcc1SKrzysztof Parzyszek } 100ea2cfcc1SKrzysztof Parzyszek 101ea2cfcc1SKrzysztof Parzyszek Object makeObject(const parser::Name &name, 102ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 103ea2cfcc1SKrzysztof Parzyszek assert(name.symbol && "Expecting Symbol"); 104ea2cfcc1SKrzysztof Parzyszek return Object{name.symbol, std::nullopt}; 105ea2cfcc1SKrzysztof Parzyszek } 106ea2cfcc1SKrzysztof Parzyszek 107ea2cfcc1SKrzysztof Parzyszek Object makeObject(const parser::Designator &dsg, 108ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 109ea2cfcc1SKrzysztof Parzyszek evaluate::ExpressionAnalyzer ea{semaCtx}; 110ea2cfcc1SKrzysztof Parzyszek SymbolWithDesignator sd = getSymbolAndDesignator(ea.Analyze(dsg)); 111ea2cfcc1SKrzysztof Parzyszek SymbolAndDesignatorExtractor::verify(sd); 112ea2cfcc1SKrzysztof Parzyszek return Object{std::get<0>(sd), std::move(std::get<1>(sd))}; 113ea2cfcc1SKrzysztof Parzyszek } 114ea2cfcc1SKrzysztof Parzyszek 115ea2cfcc1SKrzysztof Parzyszek Object makeObject(const parser::StructureComponent &comp, 116ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 117ea2cfcc1SKrzysztof Parzyszek evaluate::ExpressionAnalyzer ea{semaCtx}; 118ea2cfcc1SKrzysztof Parzyszek SymbolWithDesignator sd = getSymbolAndDesignator(ea.Analyze(comp)); 119ea2cfcc1SKrzysztof Parzyszek SymbolAndDesignatorExtractor::verify(sd); 120ea2cfcc1SKrzysztof Parzyszek return Object{std::get<0>(sd), std::move(std::get<1>(sd))}; 121ea2cfcc1SKrzysztof Parzyszek } 122ea2cfcc1SKrzysztof Parzyszek 123ea2cfcc1SKrzysztof Parzyszek Object makeObject(const parser::OmpObject &object, 124ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 125ea2cfcc1SKrzysztof Parzyszek // If object is a common block, expression analyzer won't be able to 126ea2cfcc1SKrzysztof Parzyszek // do anything. 127ea2cfcc1SKrzysztof Parzyszek if (const auto *name = std::get_if<parser::Name>(&object.u)) { 128ea2cfcc1SKrzysztof Parzyszek assert(name->symbol && "Expecting Symbol"); 129ea2cfcc1SKrzysztof Parzyszek return Object{name->symbol, std::nullopt}; 130ea2cfcc1SKrzysztof Parzyszek } 131ea2cfcc1SKrzysztof Parzyszek // OmpObject is std::variant<Designator, /*common block*/ Name>; 132ea2cfcc1SKrzysztof Parzyszek return makeObject(std::get<parser::Designator>(object.u), semaCtx); 133ea2cfcc1SKrzysztof Parzyszek } 134ea2cfcc1SKrzysztof Parzyszek 1357a66e420SKrzysztof Parzyszek std::optional<Object> getBaseObject(const Object &object, 1367a66e420SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 137ea2cfcc1SKrzysztof Parzyszek // If it's just the symbol, then there is no base. 138e910f61fSagozillon if (!object.ref()) 139ea2cfcc1SKrzysztof Parzyszek return std::nullopt; 140ea2cfcc1SKrzysztof Parzyszek 141ea2cfcc1SKrzysztof Parzyszek auto maybeRef = evaluate::ExtractDataRef(*object.ref()); 142ea2cfcc1SKrzysztof Parzyszek if (!maybeRef) 143ea2cfcc1SKrzysztof Parzyszek return std::nullopt; 144ea2cfcc1SKrzysztof Parzyszek 145ea2cfcc1SKrzysztof Parzyszek evaluate::DataRef ref = *maybeRef; 146ea2cfcc1SKrzysztof Parzyszek 147ea2cfcc1SKrzysztof Parzyszek if (std::get_if<evaluate::SymbolRef>(&ref.u)) { 148ea2cfcc1SKrzysztof Parzyszek return std::nullopt; 149ea2cfcc1SKrzysztof Parzyszek } else if (auto *comp = std::get_if<evaluate::Component>(&ref.u)) { 150ea2cfcc1SKrzysztof Parzyszek const evaluate::DataRef &base = comp->base(); 151ea2cfcc1SKrzysztof Parzyszek return Object{ 152ea2cfcc1SKrzysztof Parzyszek SymbolAndDesignatorExtractor::symbol_addr(base.GetLastSymbol()), 153ea2cfcc1SKrzysztof Parzyszek evaluate::AsGenericExpr( 154ea2cfcc1SKrzysztof Parzyszek SymbolAndDesignatorExtractor::AsRvalueRef(base))}; 155ea2cfcc1SKrzysztof Parzyszek } else if (auto *arr = std::get_if<evaluate::ArrayRef>(&ref.u)) { 156ea2cfcc1SKrzysztof Parzyszek const evaluate::NamedEntity &base = arr->base(); 157ea2cfcc1SKrzysztof Parzyszek evaluate::ExpressionAnalyzer ea{semaCtx}; 158ea2cfcc1SKrzysztof Parzyszek if (auto *comp = base.UnwrapComponent()) { 159ea2cfcc1SKrzysztof Parzyszek return Object{SymbolAndDesignatorExtractor::symbol_addr(comp->symbol()), 160ea2cfcc1SKrzysztof Parzyszek ea.Designate(evaluate::DataRef{ 161ea2cfcc1SKrzysztof Parzyszek SymbolAndDesignatorExtractor::AsRvalueRef(*comp)})}; 162ea2cfcc1SKrzysztof Parzyszek } else if (base.UnwrapSymbolRef()) { 163ea2cfcc1SKrzysztof Parzyszek return std::nullopt; 164ea2cfcc1SKrzysztof Parzyszek } 165ea2cfcc1SKrzysztof Parzyszek } else { 166ea2cfcc1SKrzysztof Parzyszek assert(std::holds_alternative<evaluate::CoarrayRef>(ref.u) && 167ea2cfcc1SKrzysztof Parzyszek "Unexpected variant alternative"); 168ea2cfcc1SKrzysztof Parzyszek llvm_unreachable("Coarray reference not supported at the moment"); 169ea2cfcc1SKrzysztof Parzyszek } 170ea2cfcc1SKrzysztof Parzyszek return std::nullopt; 171ea2cfcc1SKrzysztof Parzyszek } 172ea2cfcc1SKrzysztof Parzyszek 173148a5579SKrzysztof Parzyszek // Helper macros 174148a5579SKrzysztof Parzyszek #define MAKE_EMPTY_CLASS(cls, from_cls) \ 175148a5579SKrzysztof Parzyszek cls make(const parser::OmpClause::from_cls &, \ 176148a5579SKrzysztof Parzyszek semantics::SemanticsContext &) { \ 177148a5579SKrzysztof Parzyszek static_assert(cls::EmptyTrait::value); \ 178ea2cfcc1SKrzysztof Parzyszek return cls{}; \ 179ea2cfcc1SKrzysztof Parzyszek } \ 180ea2cfcc1SKrzysztof Parzyszek [[maybe_unused]] extern int xyzzy_semicolon_absorber 181ea2cfcc1SKrzysztof Parzyszek 182148a5579SKrzysztof Parzyszek #define MAKE_INCOMPLETE_CLASS(cls, from_cls) \ 183148a5579SKrzysztof Parzyszek cls make(const parser::OmpClause::from_cls &, \ 184148a5579SKrzysztof Parzyszek semantics::SemanticsContext &) { \ 185148a5579SKrzysztof Parzyszek static_assert(cls::IncompleteTrait::value); \ 186148a5579SKrzysztof Parzyszek return cls{}; \ 187148a5579SKrzysztof Parzyszek } \ 188ea2cfcc1SKrzysztof Parzyszek [[maybe_unused]] extern int xyzzy_semicolon_absorber 189148a5579SKrzysztof Parzyszek 190148a5579SKrzysztof Parzyszek #define MS(x, y) CLAUSET_SCOPED_ENUM_MEMBER_CONVERT(x, y) 191148a5579SKrzysztof Parzyszek #define MU(x, y) CLAUSET_UNSCOPED_ENUM_MEMBER_CONVERT(x, y) 192148a5579SKrzysztof Parzyszek 193148a5579SKrzysztof Parzyszek namespace clause { 194148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(AcqRel, AcqRel); 195148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(Acquire, Acquire); 196148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(Capture, Capture); 197148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(Compare, Compare); 198148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(DynamicAllocators, DynamicAllocators); 199148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(Full, Full); 200148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(Inbranch, Inbranch); 201148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(Mergeable, Mergeable); 202148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(Nogroup, Nogroup); 20389c556cfSKrzysztof Parzyszek MAKE_EMPTY_CLASS(NoOpenmp, NoOpenmp); 20489c556cfSKrzysztof Parzyszek MAKE_EMPTY_CLASS(NoOpenmpRoutines, NoOpenmpRoutines); 20589c556cfSKrzysztof Parzyszek MAKE_EMPTY_CLASS(NoParallelism, NoParallelism); 206148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(Notinbranch, Notinbranch); 207148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(Nowait, Nowait); 208148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(OmpxAttribute, OmpxAttribute); 209148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(OmpxBare, OmpxBare); 210148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(Read, Read); 211148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(Relaxed, Relaxed); 212148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(Release, Release); 213148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(ReverseOffload, ReverseOffload); 214148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(SeqCst, SeqCst); 215148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(Simd, Simd); 216148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(Threads, Threads); 217148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(UnifiedAddress, UnifiedAddress); 218148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(UnifiedSharedMemory, UnifiedSharedMemory); 219148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(Unknown, Unknown); 220148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(Untied, Untied); 221148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(Weak, Weak); 222148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(Write, Write); 223148a5579SKrzysztof Parzyszek 224148a5579SKrzysztof Parzyszek // Artificial clauses 225148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(CancellationConstructType, CancellationConstructType); 226148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(Depobj, Depobj); 227148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(Flush, Flush); 228148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(MemoryOrder, MemoryOrder); 229148a5579SKrzysztof Parzyszek MAKE_EMPTY_CLASS(Threadprivate, Threadprivate); 230148a5579SKrzysztof Parzyszek 231148a5579SKrzysztof Parzyszek MAKE_INCOMPLETE_CLASS(AdjustArgs, AdjustArgs); 232148a5579SKrzysztof Parzyszek MAKE_INCOMPLETE_CLASS(AppendArgs, AppendArgs); 233ea2cfcc1SKrzysztof Parzyszek 234973fa983SKrzysztof Parzyszek List<IteratorSpecifier> 235973fa983SKrzysztof Parzyszek makeIteratorSpecifiers(const parser::OmpIteratorSpecifier &inp, 236973fa983SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 237973fa983SKrzysztof Parzyszek List<IteratorSpecifier> specifiers; 238973fa983SKrzysztof Parzyszek 239973fa983SKrzysztof Parzyszek auto &[begin, end, step] = std::get<parser::SubscriptTriplet>(inp.t).t; 240973fa983SKrzysztof Parzyszek assert(begin && end && "Expecting begin/end values"); 241973fa983SKrzysztof Parzyszek evaluate::ExpressionAnalyzer ea{semaCtx}; 242973fa983SKrzysztof Parzyszek 243973fa983SKrzysztof Parzyszek MaybeExpr rbegin{ea.Analyze(*begin)}, rend{ea.Analyze(*end)}; 244973fa983SKrzysztof Parzyszek MaybeExpr rstep; 245973fa983SKrzysztof Parzyszek if (step) 246973fa983SKrzysztof Parzyszek rstep = ea.Analyze(*step); 247973fa983SKrzysztof Parzyszek 248973fa983SKrzysztof Parzyszek assert(rbegin && rend && "Unable to get range bounds"); 249973fa983SKrzysztof Parzyszek Range range{{*rbegin, *rend, rstep}}; 250973fa983SKrzysztof Parzyszek 251973fa983SKrzysztof Parzyszek auto &tds = std::get<parser::TypeDeclarationStmt>(inp.t); 252973fa983SKrzysztof Parzyszek auto &entities = std::get<std::list<parser::EntityDecl>>(tds.t); 253973fa983SKrzysztof Parzyszek for (const parser::EntityDecl &ed : entities) { 254973fa983SKrzysztof Parzyszek auto &name = std::get<parser::ObjectName>(ed.t); 255973fa983SKrzysztof Parzyszek assert(name.symbol && "Expecting symbol for iterator variable"); 256973fa983SKrzysztof Parzyszek auto *stype = name.symbol->GetType(); 257973fa983SKrzysztof Parzyszek assert(stype && "Expecting symbol type"); 258973fa983SKrzysztof Parzyszek IteratorSpecifier spec{{evaluate::DynamicType::From(*stype), 259973fa983SKrzysztof Parzyszek makeObject(name, semaCtx), range}}; 260973fa983SKrzysztof Parzyszek specifiers.emplace_back(std::move(spec)); 261973fa983SKrzysztof Parzyszek } 262973fa983SKrzysztof Parzyszek 263973fa983SKrzysztof Parzyszek return specifiers; 264973fa983SKrzysztof Parzyszek } 265973fa983SKrzysztof Parzyszek 266cfd67c21SKrzysztof Parzyszek Iterator makeIterator(const parser::OmpIterator &inp, 267973fa983SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 268973fa983SKrzysztof Parzyszek Iterator iterator; 269973fa983SKrzysztof Parzyszek for (auto &&spec : inp.v) 270973fa983SKrzysztof Parzyszek llvm::append_range(iterator, makeIteratorSpecifiers(spec, semaCtx)); 271973fa983SKrzysztof Parzyszek return iterator; 272973fa983SKrzysztof Parzyszek } 273973fa983SKrzysztof Parzyszek 274ea2cfcc1SKrzysztof Parzyszek DefinedOperator makeDefinedOperator(const parser::DefinedOperator &inp, 275ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 276148a5579SKrzysztof Parzyszek CLAUSET_ENUM_CONVERT( // 277148a5579SKrzysztof Parzyszek convert, parser::DefinedOperator::IntrinsicOperator, 278148a5579SKrzysztof Parzyszek DefinedOperator::IntrinsicOperator, 279148a5579SKrzysztof Parzyszek // clang-format off 280148a5579SKrzysztof Parzyszek MS(Add, Add) 281148a5579SKrzysztof Parzyszek MS(AND, AND) 282148a5579SKrzysztof Parzyszek MS(Concat, Concat) 283148a5579SKrzysztof Parzyszek MS(Divide, Divide) 284148a5579SKrzysztof Parzyszek MS(EQ, EQ) 285148a5579SKrzysztof Parzyszek MS(EQV, EQV) 286148a5579SKrzysztof Parzyszek MS(GE, GE) 287148a5579SKrzysztof Parzyszek MS(GT, GT) 288148a5579SKrzysztof Parzyszek MS(NOT, NOT) 289148a5579SKrzysztof Parzyszek MS(LE, LE) 290148a5579SKrzysztof Parzyszek MS(LT, LT) 291148a5579SKrzysztof Parzyszek MS(Multiply, Multiply) 292148a5579SKrzysztof Parzyszek MS(NE, NE) 293148a5579SKrzysztof Parzyszek MS(NEQV, NEQV) 294148a5579SKrzysztof Parzyszek MS(OR, OR) 295148a5579SKrzysztof Parzyszek MS(Power, Power) 296148a5579SKrzysztof Parzyszek MS(Subtract, Subtract) 297148a5579SKrzysztof Parzyszek // clang-format on 298148a5579SKrzysztof Parzyszek ); 299148a5579SKrzysztof Parzyszek 30077d8cfb3SAlexander Shaposhnikov return Fortran::common::visit( 301ea2cfcc1SKrzysztof Parzyszek common::visitors{ 302ea2cfcc1SKrzysztof Parzyszek [&](const parser::DefinedOpName &s) { 303ea2cfcc1SKrzysztof Parzyszek return DefinedOperator{ 304ea2cfcc1SKrzysztof Parzyszek DefinedOperator::DefinedOpName{makeObject(s.v, semaCtx)}}; 305ea2cfcc1SKrzysztof Parzyszek }, 306ea2cfcc1SKrzysztof Parzyszek [&](const parser::DefinedOperator::IntrinsicOperator &s) { 307148a5579SKrzysztof Parzyszek return DefinedOperator{convert(s)}; 308ea2cfcc1SKrzysztof Parzyszek }, 309ea2cfcc1SKrzysztof Parzyszek }, 310ea2cfcc1SKrzysztof Parzyszek inp.u); 311ea2cfcc1SKrzysztof Parzyszek } 312ea2cfcc1SKrzysztof Parzyszek 313ea2cfcc1SKrzysztof Parzyszek ProcedureDesignator 314ea2cfcc1SKrzysztof Parzyszek makeProcedureDesignator(const parser::ProcedureDesignator &inp, 315ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 31677d8cfb3SAlexander Shaposhnikov return ProcedureDesignator{Fortran::common::visit( 317ea2cfcc1SKrzysztof Parzyszek common::visitors{ 318ea2cfcc1SKrzysztof Parzyszek [&](const parser::Name &t) { return makeObject(t, semaCtx); }, 319ea2cfcc1SKrzysztof Parzyszek [&](const parser::ProcComponentRef &t) { 320ea2cfcc1SKrzysztof Parzyszek return makeObject(t.v.thing, semaCtx); 321ea2cfcc1SKrzysztof Parzyszek }, 322ea2cfcc1SKrzysztof Parzyszek }, 323ea2cfcc1SKrzysztof Parzyszek inp.u)}; 324ea2cfcc1SKrzysztof Parzyszek } 325ea2cfcc1SKrzysztof Parzyszek 326cfd67c21SKrzysztof Parzyszek ReductionOperator 327cfd67c21SKrzysztof Parzyszek makeReductionOperator(const parser::OmpReductionIdentifier &inp, 328ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 32977d8cfb3SAlexander Shaposhnikov return Fortran::common::visit( 330ea2cfcc1SKrzysztof Parzyszek common::visitors{ 331ea2cfcc1SKrzysztof Parzyszek [&](const parser::DefinedOperator &s) { 332ea2cfcc1SKrzysztof Parzyszek return ReductionOperator{makeDefinedOperator(s, semaCtx)}; 333ea2cfcc1SKrzysztof Parzyszek }, 334ea2cfcc1SKrzysztof Parzyszek [&](const parser::ProcedureDesignator &s) { 335ea2cfcc1SKrzysztof Parzyszek return ReductionOperator{makeProcedureDesignator(s, semaCtx)}; 336ea2cfcc1SKrzysztof Parzyszek }, 337ea2cfcc1SKrzysztof Parzyszek }, 338ea2cfcc1SKrzysztof Parzyszek inp.u); 339ea2cfcc1SKrzysztof Parzyszek } 340ea2cfcc1SKrzysztof Parzyszek 341f87737f3SKrzysztof Parzyszek clause::DependenceType makeDepType(const parser::OmpDependenceType &inp) { 342c478aab6SKrzysztof Parzyszek switch (inp.v) { 343cfd67c21SKrzysztof Parzyszek case parser::OmpDependenceType::Value::Sink: 344f87737f3SKrzysztof Parzyszek return clause::DependenceType::Sink; 345cfd67c21SKrzysztof Parzyszek case parser::OmpDependenceType::Value::Source: 346f87737f3SKrzysztof Parzyszek return clause::DependenceType::Source; 347c478aab6SKrzysztof Parzyszek } 348c478aab6SKrzysztof Parzyszek llvm_unreachable("Unexpected dependence type"); 349c478aab6SKrzysztof Parzyszek } 350c478aab6SKrzysztof Parzyszek 351f87737f3SKrzysztof Parzyszek clause::DependenceType makeDepType(const parser::OmpTaskDependenceType &inp) { 352f87737f3SKrzysztof Parzyszek switch (inp.v) { 353cfd67c21SKrzysztof Parzyszek case parser::OmpTaskDependenceType::Value::Depobj: 354f87737f3SKrzysztof Parzyszek return clause::DependenceType::Depobj; 355cfd67c21SKrzysztof Parzyszek case parser::OmpTaskDependenceType::Value::In: 356f87737f3SKrzysztof Parzyszek return clause::DependenceType::In; 357cfd67c21SKrzysztof Parzyszek case parser::OmpTaskDependenceType::Value::Inout: 358f87737f3SKrzysztof Parzyszek return clause::DependenceType::Inout; 359cfd67c21SKrzysztof Parzyszek case parser::OmpTaskDependenceType::Value::Inoutset: 360f87737f3SKrzysztof Parzyszek return clause::DependenceType::Inoutset; 361cfd67c21SKrzysztof Parzyszek case parser::OmpTaskDependenceType::Value::Mutexinoutset: 362f87737f3SKrzysztof Parzyszek return clause::DependenceType::Mutexinoutset; 363cfd67c21SKrzysztof Parzyszek case parser::OmpTaskDependenceType::Value::Out: 364f87737f3SKrzysztof Parzyszek return clause::DependenceType::Out; 365f87737f3SKrzysztof Parzyszek } 366f87737f3SKrzysztof Parzyszek llvm_unreachable("Unexpected task dependence type"); 367f87737f3SKrzysztof Parzyszek } 368f87737f3SKrzysztof Parzyszek 369bde79c0eSKrzysztof Parzyszek clause::Prescriptiveness 370bde79c0eSKrzysztof Parzyszek makePrescriptiveness(parser::OmpPrescriptiveness::Value v) { 371bde79c0eSKrzysztof Parzyszek switch (v) { 372bde79c0eSKrzysztof Parzyszek case parser::OmpPrescriptiveness::Value::Strict: 373bde79c0eSKrzysztof Parzyszek return clause::Prescriptiveness::Strict; 374bde79c0eSKrzysztof Parzyszek } 375bde79c0eSKrzysztof Parzyszek llvm_unreachable("Unexpected prescriptiveness"); 376bde79c0eSKrzysztof Parzyszek } 377bde79c0eSKrzysztof Parzyszek 378148a5579SKrzysztof Parzyszek // -------------------------------------------------------------------- 379148a5579SKrzysztof Parzyszek // Actual clauses. Each T (where tomp::T exists in ClauseT) has its "make". 380148a5579SKrzysztof Parzyszek 3816d688601SJulian Brown Absent make(const parser::OmpClause::Absent &inp, 3826d688601SJulian Brown semantics::SemanticsContext &semaCtx) { 3836d688601SJulian Brown llvm_unreachable("Unimplemented: absent"); 3846d688601SJulian Brown } 3856d688601SJulian Brown 386148a5579SKrzysztof Parzyszek // AcqRel: empty 387148a5579SKrzysztof Parzyszek // Acquire: empty 388e8e80d07SKrzysztof Parzyszek // AdjustArgs: incomplete 389148a5579SKrzysztof Parzyszek 390148a5579SKrzysztof Parzyszek Affinity make(const parser::OmpClause::Affinity &inp, 391148a5579SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 392ea3534b3SKrzysztof Parzyszek // inp.v -> parser::OmpAffinityClause 39305096590SKrzysztof Parzyszek auto &mods = semantics::OmpGetModifiers(inp.v); 39405096590SKrzysztof Parzyszek auto *m0 = semantics::OmpGetUniqueModifier<parser::OmpIterator>(mods); 395ea3534b3SKrzysztof Parzyszek auto &t1 = std::get<parser::OmpObjectList>(inp.v.t); 396ea3534b3SKrzysztof Parzyszek 397ea3534b3SKrzysztof Parzyszek auto &&maybeIter = 39805096590SKrzysztof Parzyszek m0 ? makeIterator(*m0, semaCtx) : std::optional<Iterator>{}; 399ea3534b3SKrzysztof Parzyszek 400ea3534b3SKrzysztof Parzyszek return Affinity{{/*Iterator=*/std::move(maybeIter), 401ea3534b3SKrzysztof Parzyszek /*LocatorList=*/makeObjects(t1, semaCtx)}}; 402148a5579SKrzysztof Parzyszek } 403148a5579SKrzysztof Parzyszek 404148a5579SKrzysztof Parzyszek Align make(const parser::OmpClause::Align &inp, 405148a5579SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 406148a5579SKrzysztof Parzyszek // inp -> empty 407148a5579SKrzysztof Parzyszek llvm_unreachable("Empty: align"); 408148a5579SKrzysztof Parzyszek } 409148a5579SKrzysztof Parzyszek 410ea2cfcc1SKrzysztof Parzyszek Aligned make(const parser::OmpClause::Aligned &inp, 411ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 412ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpAlignedClause 41305096590SKrzysztof Parzyszek auto &mods = semantics::OmpGetModifiers(inp.v); 414ea2cfcc1SKrzysztof Parzyszek auto &t0 = std::get<parser::OmpObjectList>(inp.v.t); 41505096590SKrzysztof Parzyszek auto *m1 = semantics::OmpGetUniqueModifier<parser::OmpAlignment>(mods); 416ea2cfcc1SKrzysztof Parzyszek 417ea2cfcc1SKrzysztof Parzyszek return Aligned{{ 41805096590SKrzysztof Parzyszek /*Alignment=*/maybeApplyToV(makeExprFn(semaCtx), m1), 4194d177435SKrzysztof Parzyszek /*List=*/makeObjects(t0, semaCtx), 420ea2cfcc1SKrzysztof Parzyszek }}; 421ea2cfcc1SKrzysztof Parzyszek } 422ea2cfcc1SKrzysztof Parzyszek 423ea2cfcc1SKrzysztof Parzyszek Allocate make(const parser::OmpClause::Allocate &inp, 424ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 425ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpAllocateClause 426cdbd2287SKrzysztof Parzyszek auto &mods = semantics::OmpGetModifiers(inp.v); 427cdbd2287SKrzysztof Parzyszek auto *m0 = semantics::OmpGetUniqueModifier<parser::OmpAlignModifier>(mods); 428cdbd2287SKrzysztof Parzyszek auto *m1 = 429cdbd2287SKrzysztof Parzyszek semantics::OmpGetUniqueModifier<parser::OmpAllocatorComplexModifier>( 430cdbd2287SKrzysztof Parzyszek mods); 431cdbd2287SKrzysztof Parzyszek auto *m2 = 432cdbd2287SKrzysztof Parzyszek semantics::OmpGetUniqueModifier<parser::OmpAllocatorSimpleModifier>(mods); 433ea2cfcc1SKrzysztof Parzyszek auto &t1 = std::get<parser::OmpObjectList>(inp.v.t); 434ea2cfcc1SKrzysztof Parzyszek 435cdbd2287SKrzysztof Parzyszek auto makeAllocator = [&](auto *mod) -> std::optional<Allocator> { 436cdbd2287SKrzysztof Parzyszek if (mod) 437cdbd2287SKrzysztof Parzyszek return Allocator{makeExpr(mod->v, semaCtx)}; 438cdbd2287SKrzysztof Parzyszek return std::nullopt; 439cdbd2287SKrzysztof Parzyszek }; 440cdbd2287SKrzysztof Parzyszek 441cdbd2287SKrzysztof Parzyszek auto makeAlign = [&](const parser::ScalarIntExpr &expr) { 442cdbd2287SKrzysztof Parzyszek return Align{makeExpr(expr, semaCtx)}; 443cdbd2287SKrzysztof Parzyszek }; 444cdbd2287SKrzysztof Parzyszek 445cdbd2287SKrzysztof Parzyszek auto maybeAllocator = m1 ? makeAllocator(m1) : makeAllocator(m2); 446cdbd2287SKrzysztof Parzyszek return Allocate{{/*AllocatorComplexModifier=*/std::move(maybeAllocator), 447cdbd2287SKrzysztof Parzyszek /*AlignModifier=*/maybeApplyToV(makeAlign, m0), 4484d177435SKrzysztof Parzyszek /*List=*/makeObjects(t1, semaCtx)}}; 449148a5579SKrzysztof Parzyszek } 450ea2cfcc1SKrzysztof Parzyszek 451ea2cfcc1SKrzysztof Parzyszek Allocator make(const parser::OmpClause::Allocator &inp, 452ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 453ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::ScalarIntExpr 454148a5579SKrzysztof Parzyszek return Allocator{/*Allocator=*/makeExpr(inp.v, semaCtx)}; 455148a5579SKrzysztof Parzyszek } 456148a5579SKrzysztof Parzyszek 457148a5579SKrzysztof Parzyszek // AppendArgs: incomplete 458148a5579SKrzysztof Parzyszek 459148a5579SKrzysztof Parzyszek At make(const parser::OmpClause::At &inp, 460148a5579SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 461148a5579SKrzysztof Parzyszek // inp -> empty 462148a5579SKrzysztof Parzyszek llvm_unreachable("Empty: at"); 463ea2cfcc1SKrzysztof Parzyszek } 464ea2cfcc1SKrzysztof Parzyszek 465ea2cfcc1SKrzysztof Parzyszek // Never called, but needed for using "make" as a Clause visitor. 466ea2cfcc1SKrzysztof Parzyszek // See comment about "requires" clauses in Clauses.h. 467ea2cfcc1SKrzysztof Parzyszek AtomicDefaultMemOrder make(const parser::OmpClause::AtomicDefaultMemOrder &inp, 468ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 469ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpAtomicDefaultMemOrderClause 470148a5579SKrzysztof Parzyszek CLAUSET_ENUM_CONVERT( // 471148a5579SKrzysztof Parzyszek convert, common::OmpAtomicDefaultMemOrderType, 472148a5579SKrzysztof Parzyszek AtomicDefaultMemOrder::MemoryOrder, 473148a5579SKrzysztof Parzyszek // clang-format off 474148a5579SKrzysztof Parzyszek MS(AcqRel, AcqRel) 475148a5579SKrzysztof Parzyszek MS(Relaxed, Relaxed) 476148a5579SKrzysztof Parzyszek MS(SeqCst, SeqCst) 477148a5579SKrzysztof Parzyszek // clang-format on 478148a5579SKrzysztof Parzyszek ); 479148a5579SKrzysztof Parzyszek 480148a5579SKrzysztof Parzyszek return AtomicDefaultMemOrder{/*MemoryOrder=*/convert(inp.v.v)}; 481ea2cfcc1SKrzysztof Parzyszek } 482ea2cfcc1SKrzysztof Parzyszek 483148a5579SKrzysztof Parzyszek Bind make(const parser::OmpClause::Bind &inp, 484148a5579SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 485b4c0ef18SKareem Ergawy // inp.v -> parser::OmpBindClause 486b4c0ef18SKareem Ergawy using wrapped = parser::OmpBindClause; 487b4c0ef18SKareem Ergawy 488b4c0ef18SKareem Ergawy CLAUSET_ENUM_CONVERT( // 489608f4ae1SKrzysztof Parzyszek convert, wrapped::Binding, Bind::Binding, 490b4c0ef18SKareem Ergawy // clang-format off 491b4c0ef18SKareem Ergawy MS(Teams, Teams) 492b4c0ef18SKareem Ergawy MS(Parallel, Parallel) 493b4c0ef18SKareem Ergawy MS(Thread, Thread) 494b4c0ef18SKareem Ergawy // clang-format on 495b4c0ef18SKareem Ergawy ); 496b4c0ef18SKareem Ergawy 497b4c0ef18SKareem Ergawy return Bind{/*Binding=*/convert(inp.v.v)}; 498148a5579SKrzysztof Parzyszek } 499148a5579SKrzysztof Parzyszek 500148a5579SKrzysztof Parzyszek // CancellationConstructType: empty 501148a5579SKrzysztof Parzyszek // Capture: empty 502148a5579SKrzysztof Parzyszek 503ea2cfcc1SKrzysztof Parzyszek Collapse make(const parser::OmpClause::Collapse &inp, 504ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 505ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::ScalarIntConstantExpr 506148a5579SKrzysztof Parzyszek return Collapse{/*N=*/makeExpr(inp.v, semaCtx)}; 507ea2cfcc1SKrzysztof Parzyszek } 508ea2cfcc1SKrzysztof Parzyszek 509148a5579SKrzysztof Parzyszek // Compare: empty 5106d688601SJulian Brown 5116d688601SJulian Brown Contains make(const parser::OmpClause::Contains &inp, 5126d688601SJulian Brown semantics::SemanticsContext &semaCtx) { 5136d688601SJulian Brown llvm_unreachable("Unimplemented: contains"); 5146d688601SJulian Brown } 515148a5579SKrzysztof Parzyszek 516ea2cfcc1SKrzysztof Parzyszek Copyin make(const parser::OmpClause::Copyin &inp, 517ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 518ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpObjectList 5194d177435SKrzysztof Parzyszek return Copyin{/*List=*/makeObjects(inp.v, semaCtx)}; 520ea2cfcc1SKrzysztof Parzyszek } 521ea2cfcc1SKrzysztof Parzyszek 522ea2cfcc1SKrzysztof Parzyszek Copyprivate make(const parser::OmpClause::Copyprivate &inp, 523ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 524ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpObjectList 5254d177435SKrzysztof Parzyszek return Copyprivate{/*List=*/makeObjects(inp.v, semaCtx)}; 526148a5579SKrzysztof Parzyszek } 527148a5579SKrzysztof Parzyszek 528*15ab7be2SKrzysztof Parzyszek // The Default clause is overloaded in OpenMP 5.0 and 5.1: it can be either 529*15ab7be2SKrzysztof Parzyszek // a data-sharing clause, or a METADIRECTIVE clause. In the latter case, it 530*15ab7be2SKrzysztof Parzyszek // has been superseded by the OTHERWISE clause. 531*15ab7be2SKrzysztof Parzyszek // Disambiguate this in this representation: for the DSA case, create Default, 532*15ab7be2SKrzysztof Parzyszek // and in the other case create Otherwise. 533*15ab7be2SKrzysztof Parzyszek Default makeDefault(const parser::OmpClause::Default &inp, 534148a5579SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 535148a5579SKrzysztof Parzyszek // inp.v -> parser::OmpDefaultClause 536148a5579SKrzysztof Parzyszek using wrapped = parser::OmpDefaultClause; 537148a5579SKrzysztof Parzyszek 538148a5579SKrzysztof Parzyszek CLAUSET_ENUM_CONVERT( // 539608f4ae1SKrzysztof Parzyszek convert, wrapped::DataSharingAttribute, Default::DataSharingAttribute, 540148a5579SKrzysztof Parzyszek // clang-format off 541148a5579SKrzysztof Parzyszek MS(Firstprivate, Firstprivate) 542148a5579SKrzysztof Parzyszek MS(None, None) 543148a5579SKrzysztof Parzyszek MS(Private, Private) 544148a5579SKrzysztof Parzyszek MS(Shared, Shared) 545148a5579SKrzysztof Parzyszek // clang-format on 546148a5579SKrzysztof Parzyszek ); 547148a5579SKrzysztof Parzyszek 548*15ab7be2SKrzysztof Parzyszek auto dsa = std::get<wrapped::DataSharingAttribute>(inp.v.u); 549*15ab7be2SKrzysztof Parzyszek return Default{/*DataSharingAttribute=*/convert(dsa)}; 550*15ab7be2SKrzysztof Parzyszek } 551*15ab7be2SKrzysztof Parzyszek 552*15ab7be2SKrzysztof Parzyszek Otherwise makeOtherwise(const parser::OmpClause::Default &inp, 553*15ab7be2SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 554*15ab7be2SKrzysztof Parzyszek return Otherwise{}; 555ea2cfcc1SKrzysztof Parzyszek } 556ea2cfcc1SKrzysztof Parzyszek 557ea2cfcc1SKrzysztof Parzyszek Defaultmap make(const parser::OmpClause::Defaultmap &inp, 558ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 559ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpDefaultmapClause 560ea2cfcc1SKrzysztof Parzyszek using wrapped = parser::OmpDefaultmapClause; 561ea2cfcc1SKrzysztof Parzyszek 562148a5579SKrzysztof Parzyszek CLAUSET_ENUM_CONVERT( // 563148a5579SKrzysztof Parzyszek convert1, wrapped::ImplicitBehavior, Defaultmap::ImplicitBehavior, 564148a5579SKrzysztof Parzyszek // clang-format off 565148a5579SKrzysztof Parzyszek MS(Alloc, Alloc) 566148a5579SKrzysztof Parzyszek MS(To, To) 567148a5579SKrzysztof Parzyszek MS(From, From) 568148a5579SKrzysztof Parzyszek MS(Tofrom, Tofrom) 569148a5579SKrzysztof Parzyszek MS(Firstprivate, Firstprivate) 570148a5579SKrzysztof Parzyszek MS(None, None) 571148a5579SKrzysztof Parzyszek MS(Default, Default) 572148a5579SKrzysztof Parzyszek // MS(, Present) missing-in-parser 573148a5579SKrzysztof Parzyszek // clang-format on 574148a5579SKrzysztof Parzyszek ); 575148a5579SKrzysztof Parzyszek 576148a5579SKrzysztof Parzyszek CLAUSET_ENUM_CONVERT( // 5774fc1141eSKrzysztof Parzyszek convert2, parser::OmpVariableCategory::Value, 5784fc1141eSKrzysztof Parzyszek Defaultmap::VariableCategory, 579148a5579SKrzysztof Parzyszek // clang-format off 580148a5579SKrzysztof Parzyszek MS(Aggregate, Aggregate) 5814c4a4134SKrzysztof Parzyszek MS(All, All) 582148a5579SKrzysztof Parzyszek MS(Allocatable, Allocatable) 5834c4a4134SKrzysztof Parzyszek MS(Pointer, Pointer) 5844c4a4134SKrzysztof Parzyszek MS(Scalar, Scalar) 585148a5579SKrzysztof Parzyszek // clang-format on 586148a5579SKrzysztof Parzyszek ); 587148a5579SKrzysztof Parzyszek 58852755ac2SKrzysztof Parzyszek auto &mods = semantics::OmpGetModifiers(inp.v); 589ea2cfcc1SKrzysztof Parzyszek auto &t0 = std::get<wrapped::ImplicitBehavior>(inp.v.t); 5904fc1141eSKrzysztof Parzyszek auto *t1 = semantics::OmpGetUniqueModifier<parser::OmpVariableCategory>(mods); 5914c4a4134SKrzysztof Parzyszek 5924fc1141eSKrzysztof Parzyszek auto category = t1 ? convert2(t1->v) : Defaultmap::VariableCategory::All; 593148a5579SKrzysztof Parzyszek return Defaultmap{{/*ImplicitBehavior=*/convert1(t0), 5944c4a4134SKrzysztof Parzyszek /*VariableCategory=*/category}}; 595ea2cfcc1SKrzysztof Parzyszek } 596ea2cfcc1SKrzysztof Parzyszek 597b08b252aSKrzysztof Parzyszek Doacross makeDoacross(const parser::OmpDoacross &doa, 598ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 599f87737f3SKrzysztof Parzyszek // Iteration is the equivalent of parser::OmpIteration 600148a5579SKrzysztof Parzyszek using Iteration = Doacross::Vector::value_type; // LoopIterationT 601ea2cfcc1SKrzysztof Parzyszek 602b08b252aSKrzysztof Parzyszek auto visitSource = [&](const parser::OmpDoacross::Source &) { 603f87737f3SKrzysztof Parzyszek return Doacross{{/*DependenceType=*/Doacross::DependenceType::Source, 604148a5579SKrzysztof Parzyszek /*Vector=*/{}}}; 605f87737f3SKrzysztof Parzyszek }; 606148a5579SKrzysztof Parzyszek 607b08b252aSKrzysztof Parzyszek auto visitSink = [&](const parser::OmpDoacross::Sink &s) { 608f87737f3SKrzysztof Parzyszek using IterOffset = parser::OmpIterationOffset; 609f87737f3SKrzysztof Parzyszek auto convert2 = [&](const parser::OmpIteration &v) { 610f87737f3SKrzysztof Parzyszek auto &t0 = std::get<parser::Name>(v.t); 611f87737f3SKrzysztof Parzyszek auto &t1 = std::get<std::optional<IterOffset>>(v.t); 612f87737f3SKrzysztof Parzyszek 613f87737f3SKrzysztof Parzyszek auto convert3 = [&](const IterOffset &u) { 614ea2cfcc1SKrzysztof Parzyszek auto &s0 = std::get<parser::DefinedOperator>(u.t); 615ea2cfcc1SKrzysztof Parzyszek auto &s1 = std::get<parser::ScalarIntConstantExpr>(u.t); 616148a5579SKrzysztof Parzyszek return Iteration::Distance{ 617148a5579SKrzysztof Parzyszek {makeDefinedOperator(s0, semaCtx), makeExpr(s1, semaCtx)}}; 618ea2cfcc1SKrzysztof Parzyszek }; 619f87737f3SKrzysztof Parzyszek return Iteration{{makeObject(t0, semaCtx), maybeApply(convert3, t1)}}; 620ea2cfcc1SKrzysztof Parzyszek }; 621148a5579SKrzysztof Parzyszek return Doacross{{/*DependenceType=*/Doacross::DependenceType::Sink, 622f87737f3SKrzysztof Parzyszek /*Vector=*/makeList(s.v.v, convert2)}}; 623f87737f3SKrzysztof Parzyszek }; 624f87737f3SKrzysztof Parzyszek 625b08b252aSKrzysztof Parzyszek return common::visit(common::visitors{visitSink, visitSource}, doa.u); 626b08b252aSKrzysztof Parzyszek } 627b08b252aSKrzysztof Parzyszek 628b08b252aSKrzysztof Parzyszek Depend make(const parser::OmpClause::Depend &inp, 629b08b252aSKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 630b08b252aSKrzysztof Parzyszek // inp.v -> parser::OmpDependClause 631b08b252aSKrzysztof Parzyszek using wrapped = parser::OmpDependClause; 632b08b252aSKrzysztof Parzyszek using Variant = decltype(Depend::u); 633b08b252aSKrzysztof Parzyszek 634f87737f3SKrzysztof Parzyszek auto visitTaskDep = [&](const wrapped::TaskDep &s) -> Variant { 635bde79c0eSKrzysztof Parzyszek auto &mods = semantics::OmpGetModifiers(s); 636bde79c0eSKrzysztof Parzyszek auto *m0 = semantics::OmpGetUniqueModifier<parser::OmpIterator>(mods); 637bde79c0eSKrzysztof Parzyszek auto *m1 = 638bde79c0eSKrzysztof Parzyszek semantics::OmpGetUniqueModifier<parser::OmpTaskDependenceType>(mods); 639bde79c0eSKrzysztof Parzyszek auto &t1 = std::get<parser::OmpObjectList>(s.t); 640bde79c0eSKrzysztof Parzyszek assert(m1 && "expecting task dependence type"); 641d48c849eSKrzysztof Parzyszek 642f87737f3SKrzysztof Parzyszek auto &&maybeIter = 643bde79c0eSKrzysztof Parzyszek m0 ? makeIterator(*m0, semaCtx) : std::optional<Iterator>{}; 644bde79c0eSKrzysztof Parzyszek return Depend::TaskDep{{/*DependenceType=*/makeDepType(*m1), 645d48c849eSKrzysztof Parzyszek /*Iterator=*/std::move(maybeIter), 646bde79c0eSKrzysztof Parzyszek /*LocatorList=*/makeObjects(t1, semaCtx)}}; 647f87737f3SKrzysztof Parzyszek }; 648f87737f3SKrzysztof Parzyszek 649b08b252aSKrzysztof Parzyszek return Depend{common::visit( // 650f87737f3SKrzysztof Parzyszek common::visitors{ 651f87737f3SKrzysztof Parzyszek // Doacross 652f87737f3SKrzysztof Parzyszek [&](const parser::OmpDoacross &s) -> Variant { 653b08b252aSKrzysztof Parzyszek return makeDoacross(s, semaCtx); 654ea2cfcc1SKrzysztof Parzyszek }, 655f87737f3SKrzysztof Parzyszek // Depend::TaskDep 656f87737f3SKrzysztof Parzyszek visitTaskDep, 657ea2cfcc1SKrzysztof Parzyszek }, 658148a5579SKrzysztof Parzyszek inp.v.u)}; 659148a5579SKrzysztof Parzyszek } 660148a5579SKrzysztof Parzyszek 661148a5579SKrzysztof Parzyszek // Depobj: empty 662148a5579SKrzysztof Parzyszek 663148a5579SKrzysztof Parzyszek Destroy make(const parser::OmpClause::Destroy &inp, 664148a5579SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 665c478aab6SKrzysztof Parzyszek // inp.v -> std::optional<OmpDestroyClause> 666c478aab6SKrzysztof Parzyszek auto &&maybeObject = maybeApply( 667c478aab6SKrzysztof Parzyszek [&](const parser::OmpDestroyClause &c) { 668c478aab6SKrzysztof Parzyszek return makeObject(c.v, semaCtx); 669c478aab6SKrzysztof Parzyszek }, 670c478aab6SKrzysztof Parzyszek inp.v); 671c478aab6SKrzysztof Parzyszek 672c478aab6SKrzysztof Parzyszek return Destroy{/*DestroyVar=*/std::move(maybeObject)}; 673148a5579SKrzysztof Parzyszek } 674148a5579SKrzysztof Parzyszek 675148a5579SKrzysztof Parzyszek Detach make(const parser::OmpClause::Detach &inp, 676148a5579SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 6770653698dSNimishMishra // inp.v -> parser::OmpDetachClause 6780653698dSNimishMishra return Detach{makeObject(inp.v.v, semaCtx)}; 679ea2cfcc1SKrzysztof Parzyszek } 680ea2cfcc1SKrzysztof Parzyszek 681ea2cfcc1SKrzysztof Parzyszek Device make(const parser::OmpClause::Device &inp, 682ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 683ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpDeviceClause 684148a5579SKrzysztof Parzyszek CLAUSET_ENUM_CONVERT( // 68505096590SKrzysztof Parzyszek convert, parser::OmpDeviceModifier::Value, Device::DeviceModifier, 686148a5579SKrzysztof Parzyszek // clang-format off 687148a5579SKrzysztof Parzyszek MS(Ancestor, Ancestor) 688148a5579SKrzysztof Parzyszek MS(Device_Num, DeviceNum) 689148a5579SKrzysztof Parzyszek // clang-format on 690148a5579SKrzysztof Parzyszek ); 69105096590SKrzysztof Parzyszek 69205096590SKrzysztof Parzyszek auto &mods = semantics::OmpGetModifiers(inp.v); 69305096590SKrzysztof Parzyszek auto *m0 = semantics::OmpGetUniqueModifier<parser::OmpDeviceModifier>(mods); 694ea2cfcc1SKrzysztof Parzyszek auto &t1 = std::get<parser::ScalarIntExpr>(inp.v.t); 69505096590SKrzysztof Parzyszek return Device{{/*DeviceModifier=*/maybeApplyToV(convert, m0), 696148a5579SKrzysztof Parzyszek /*DeviceDescription=*/makeExpr(t1, semaCtx)}}; 697ea2cfcc1SKrzysztof Parzyszek } 698ea2cfcc1SKrzysztof Parzyszek 699ea2cfcc1SKrzysztof Parzyszek DeviceType make(const parser::OmpClause::DeviceType &inp, 700ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 701ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpDeviceTypeClause 702148a5579SKrzysztof Parzyszek using wrapped = parser::OmpDeviceTypeClause; 703148a5579SKrzysztof Parzyszek 704148a5579SKrzysztof Parzyszek CLAUSET_ENUM_CONVERT( // 705608f4ae1SKrzysztof Parzyszek convert, wrapped::DeviceTypeDescription, 706608f4ae1SKrzysztof Parzyszek DeviceType::DeviceTypeDescription, 707148a5579SKrzysztof Parzyszek // clang-format off 708148a5579SKrzysztof Parzyszek MS(Any, Any) 709148a5579SKrzysztof Parzyszek MS(Host, Host) 710148a5579SKrzysztof Parzyszek MS(Nohost, Nohost) 711148a5579SKrzysztof Parzyszek // clang-format om 712148a5579SKrzysztof Parzyszek ); 713148a5579SKrzysztof Parzyszek return DeviceType{/*DeviceTypeDescription=*/convert(inp.v.v)}; 714ea2cfcc1SKrzysztof Parzyszek } 715ea2cfcc1SKrzysztof Parzyszek 716ea2cfcc1SKrzysztof Parzyszek DistSchedule make(const parser::OmpClause::DistSchedule &inp, 717ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 718ea2cfcc1SKrzysztof Parzyszek // inp.v -> std::optional<parser::ScalarIntExpr> 719148a5579SKrzysztof Parzyszek return DistSchedule{{/*Kind=*/DistSchedule::Kind::Static, 720148a5579SKrzysztof Parzyszek /*ChunkSize=*/maybeApply(makeExprFn(semaCtx), inp.v)}}; 721ea2cfcc1SKrzysztof Parzyszek } 722ea2cfcc1SKrzysztof Parzyszek 723148a5579SKrzysztof Parzyszek Doacross make(const parser::OmpClause::Doacross &inp, 724148a5579SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 725b08b252aSKrzysztof Parzyszek // inp.v -> OmpDoacrossClause 726b08b252aSKrzysztof Parzyszek return makeDoacross(inp.v.v, semaCtx); 727148a5579SKrzysztof Parzyszek } 728148a5579SKrzysztof Parzyszek 729148a5579SKrzysztof Parzyszek // DynamicAllocators: empty 730148a5579SKrzysztof Parzyszek 731ea2cfcc1SKrzysztof Parzyszek Enter make(const parser::OmpClause::Enter &inp, 732ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 733ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpObjectList 7344d177435SKrzysztof Parzyszek return Enter{makeObjects(/*List=*/inp.v, semaCtx)}; 735148a5579SKrzysztof Parzyszek } 736148a5579SKrzysztof Parzyszek 737148a5579SKrzysztof Parzyszek Exclusive make(const parser::OmpClause::Exclusive &inp, 738148a5579SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 739148a5579SKrzysztof Parzyszek // inp -> empty 740148a5579SKrzysztof Parzyszek llvm_unreachable("Empty: exclusive"); 741148a5579SKrzysztof Parzyszek } 742148a5579SKrzysztof Parzyszek 743148a5579SKrzysztof Parzyszek Fail make(const parser::OmpClause::Fail &inp, 744148a5579SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 745148a5579SKrzysztof Parzyszek // inp -> empty 746148a5579SKrzysztof Parzyszek llvm_unreachable("Empty: fail"); 747ea2cfcc1SKrzysztof Parzyszek } 748ea2cfcc1SKrzysztof Parzyszek 749ea2cfcc1SKrzysztof Parzyszek Filter make(const parser::OmpClause::Filter &inp, 750ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 751ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::ScalarIntExpr 752148a5579SKrzysztof Parzyszek return Filter{/*ThreadNum=*/makeExpr(inp.v, semaCtx)}; 753ea2cfcc1SKrzysztof Parzyszek } 754ea2cfcc1SKrzysztof Parzyszek 755ea2cfcc1SKrzysztof Parzyszek Final make(const parser::OmpClause::Final &inp, 756ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 757ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::ScalarLogicalExpr 758148a5579SKrzysztof Parzyszek return Final{/*Finalize=*/makeExpr(inp.v, semaCtx)}; 759ea2cfcc1SKrzysztof Parzyszek } 760ea2cfcc1SKrzysztof Parzyszek 761ea2cfcc1SKrzysztof Parzyszek Firstprivate make(const parser::OmpClause::Firstprivate &inp, 762ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 763ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpObjectList 7644d177435SKrzysztof Parzyszek return Firstprivate{/*List=*/makeObjects(inp.v, semaCtx)}; 765ea2cfcc1SKrzysztof Parzyszek } 766ea2cfcc1SKrzysztof Parzyszek 767148a5579SKrzysztof Parzyszek // Flush: empty 768148a5579SKrzysztof Parzyszek 769ea2cfcc1SKrzysztof Parzyszek From make(const parser::OmpClause::From &inp, 770ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 7711c6ec29bSKrzysztof Parzyszek // inp.v -> parser::OmpFromClause 7721c6ec29bSKrzysztof Parzyszek CLAUSET_ENUM_CONVERT( // 77352755ac2SKrzysztof Parzyszek convert, parser::OmpExpectation::Value, From::Expectation, 7741c6ec29bSKrzysztof Parzyszek // clang-format off 7751c6ec29bSKrzysztof Parzyszek MS(Present, Present) 7761c6ec29bSKrzysztof Parzyszek // clang-format on 7771c6ec29bSKrzysztof Parzyszek ); 7781c6ec29bSKrzysztof Parzyszek 77952755ac2SKrzysztof Parzyszek auto &mods = semantics::OmpGetModifiers(inp.v); 78052755ac2SKrzysztof Parzyszek auto *t0 = semantics::OmpGetUniqueModifier<parser::OmpExpectation>(mods); 78152755ac2SKrzysztof Parzyszek auto *t1 = semantics::OmpGetUniqueModifier<parser::OmpMapper>(mods); 78252755ac2SKrzysztof Parzyszek auto *t2 = semantics::OmpGetUniqueModifier<parser::OmpIterator>(mods); 78352755ac2SKrzysztof Parzyszek auto &t3 = std::get<parser::OmpObjectList>(inp.v.t); 7841c6ec29bSKrzysztof Parzyszek 78552755ac2SKrzysztof Parzyszek auto mappers = [&]() -> std::optional<List<Mapper>> { 78652755ac2SKrzysztof Parzyszek if (t1) 78752755ac2SKrzysztof Parzyszek return List<Mapper>{Mapper{makeObject(t1->v, semaCtx)}}; 7881c6ec29bSKrzysztof Parzyszek return std::nullopt; 7891c6ec29bSKrzysztof Parzyszek }(); 7901c6ec29bSKrzysztof Parzyszek 7911c6ec29bSKrzysztof Parzyszek auto iterator = [&]() -> std::optional<Iterator> { 79252755ac2SKrzysztof Parzyszek if (t2) 79352755ac2SKrzysztof Parzyszek return makeIterator(*t2, semaCtx); 7941c6ec29bSKrzysztof Parzyszek return std::nullopt; 7951c6ec29bSKrzysztof Parzyszek }(); 7961c6ec29bSKrzysztof Parzyszek 79752755ac2SKrzysztof Parzyszek return From{{/*Expectation=*/maybeApplyToV(convert, t0), 79852755ac2SKrzysztof Parzyszek /*Mappers=*/std::move(mappers), 7991c6ec29bSKrzysztof Parzyszek /*Iterator=*/std::move(iterator), 80052755ac2SKrzysztof Parzyszek /*LocatorList=*/makeObjects(t3, semaCtx)}}; 801ea2cfcc1SKrzysztof Parzyszek } 802ea2cfcc1SKrzysztof Parzyszek 803148a5579SKrzysztof Parzyszek // Full: empty 804148a5579SKrzysztof Parzyszek 805ea2cfcc1SKrzysztof Parzyszek Grainsize make(const parser::OmpClause::Grainsize &inp, 806ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 8075621929fSKiran Chandramohan // inp.v -> parser::OmpGrainsizeClause 808bde79c0eSKrzysztof Parzyszek auto &mods = semantics::OmpGetModifiers(inp.v); 809bde79c0eSKrzysztof Parzyszek auto *m0 = semantics::OmpGetUniqueModifier<parser::OmpPrescriptiveness>(mods); 8105621929fSKiran Chandramohan auto &t1 = std::get<parser::ScalarIntExpr>(inp.v.t); 811bde79c0eSKrzysztof Parzyszek return Grainsize{ 812bde79c0eSKrzysztof Parzyszek {/*Prescriptiveness=*/maybeApplyToV(makePrescriptiveness, m0), 8135621929fSKiran Chandramohan /*Grainsize=*/makeExpr(t1, semaCtx)}}; 814ea2cfcc1SKrzysztof Parzyszek } 815ea2cfcc1SKrzysztof Parzyszek 816ea2cfcc1SKrzysztof Parzyszek HasDeviceAddr make(const parser::OmpClause::HasDeviceAddr &inp, 817ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 818ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpObjectList 8194d177435SKrzysztof Parzyszek return HasDeviceAddr{/*List=*/makeObjects(inp.v, semaCtx)}; 820ea2cfcc1SKrzysztof Parzyszek } 821ea2cfcc1SKrzysztof Parzyszek 822ea2cfcc1SKrzysztof Parzyszek Hint make(const parser::OmpClause::Hint &inp, 823ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 824ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::ConstantExpr 825148a5579SKrzysztof Parzyszek return Hint{/*HintExpr=*/makeExpr(inp.v, semaCtx)}; 826ea2cfcc1SKrzysztof Parzyszek } 827ea2cfcc1SKrzysztof Parzyszek 8286d688601SJulian Brown Holds make(const parser::OmpClause::Holds &inp, 8296d688601SJulian Brown semantics::SemanticsContext &semaCtx) { 8306d688601SJulian Brown llvm_unreachable("Unimplemented: holds"); 8316d688601SJulian Brown } 832148a5579SKrzysztof Parzyszek 833ea2cfcc1SKrzysztof Parzyszek If make(const parser::OmpClause::If &inp, 834ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 835ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpIfClause 83633faa828SKrzysztof Parzyszek auto &mods = semantics::OmpGetModifiers(inp.v); 83733faa828SKrzysztof Parzyszek auto *m0 = 83833faa828SKrzysztof Parzyszek semantics::OmpGetUniqueModifier<parser::OmpDirectiveNameModifier>(mods); 839ea2cfcc1SKrzysztof Parzyszek auto &t1 = std::get<parser::ScalarLogicalExpr>(inp.v.t); 84033faa828SKrzysztof Parzyszek return If{ 84133faa828SKrzysztof Parzyszek {/*DirectiveNameModifier=*/maybeApplyToV([](auto &&s) { return s; }, m0), 842148a5579SKrzysztof Parzyszek /*IfExpression=*/makeExpr(t1, semaCtx)}}; 843ea2cfcc1SKrzysztof Parzyszek } 844ea2cfcc1SKrzysztof Parzyszek 845148a5579SKrzysztof Parzyszek // Inbranch: empty 846148a5579SKrzysztof Parzyszek 847148a5579SKrzysztof Parzyszek Inclusive make(const parser::OmpClause::Inclusive &inp, 848148a5579SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 849148a5579SKrzysztof Parzyszek // inp -> empty 850148a5579SKrzysztof Parzyszek llvm_unreachable("Empty: inclusive"); 851148a5579SKrzysztof Parzyszek } 852148a5579SKrzysztof Parzyszek 853148a5579SKrzysztof Parzyszek Indirect make(const parser::OmpClause::Indirect &inp, 854148a5579SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 855148a5579SKrzysztof Parzyszek // inp -> empty 856148a5579SKrzysztof Parzyszek llvm_unreachable("Empty: indirect"); 857148a5579SKrzysztof Parzyszek } 858148a5579SKrzysztof Parzyszek 859148a5579SKrzysztof Parzyszek Init make(const parser::OmpClause::Init &inp, 860148a5579SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 861148a5579SKrzysztof Parzyszek // inp -> empty 862148a5579SKrzysztof Parzyszek llvm_unreachable("Empty: init"); 863148a5579SKrzysztof Parzyszek } 864148a5579SKrzysztof Parzyszek 865148a5579SKrzysztof Parzyszek // Initializer: missing-in-parser 866148a5579SKrzysztof Parzyszek 867ea2cfcc1SKrzysztof Parzyszek InReduction make(const parser::OmpClause::InReduction &inp, 868ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 869ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpInReductionClause 87058f9c4fcSKrzysztof Parzyszek auto &mods = semantics::OmpGetModifiers(inp.v); 87158f9c4fcSKrzysztof Parzyszek auto *m0 = 87258f9c4fcSKrzysztof Parzyszek semantics::OmpGetUniqueModifier<parser::OmpReductionIdentifier>(mods); 873ea2cfcc1SKrzysztof Parzyszek auto &t1 = std::get<parser::OmpObjectList>(inp.v.t); 87458f9c4fcSKrzysztof Parzyszek assert(m0 && "OmpReductionIdentifier is required"); 87558f9c4fcSKrzysztof Parzyszek 876ea2cfcc1SKrzysztof Parzyszek return InReduction{ 87758f9c4fcSKrzysztof Parzyszek {/*ReductionIdentifiers=*/{makeReductionOperator(*m0, semaCtx)}, 8784d177435SKrzysztof Parzyszek /*List=*/makeObjects(t1, semaCtx)}}; 879ea2cfcc1SKrzysztof Parzyszek } 880ea2cfcc1SKrzysztof Parzyszek 881ea2cfcc1SKrzysztof Parzyszek IsDevicePtr make(const parser::OmpClause::IsDevicePtr &inp, 882ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 883ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpObjectList 8844d177435SKrzysztof Parzyszek return IsDevicePtr{/*List=*/makeObjects(inp.v, semaCtx)}; 885ea2cfcc1SKrzysztof Parzyszek } 886ea2cfcc1SKrzysztof Parzyszek 887ea2cfcc1SKrzysztof Parzyszek Lastprivate make(const parser::OmpClause::Lastprivate &inp, 888ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 889f9824439SKrzysztof Parzyszek // inp.v -> parser::OmpLastprivateClause 890f9824439SKrzysztof Parzyszek CLAUSET_ENUM_CONVERT( // 89133faa828SKrzysztof Parzyszek convert, parser::OmpLastprivateModifier::Value, 892f9824439SKrzysztof Parzyszek Lastprivate::LastprivateModifier, 893f9824439SKrzysztof Parzyszek // clang-format off 894f9824439SKrzysztof Parzyszek MS(Conditional, Conditional) 895f9824439SKrzysztof Parzyszek // clang-format on 896f9824439SKrzysztof Parzyszek ); 897f9824439SKrzysztof Parzyszek 89833faa828SKrzysztof Parzyszek auto &mods = semantics::OmpGetModifiers(inp.v); 89933faa828SKrzysztof Parzyszek auto *m0 = 90033faa828SKrzysztof Parzyszek semantics::OmpGetUniqueModifier<parser::OmpLastprivateModifier>(mods); 901f9824439SKrzysztof Parzyszek auto &t1 = std::get<parser::OmpObjectList>(inp.v.t); 902f9824439SKrzysztof Parzyszek 90333faa828SKrzysztof Parzyszek return Lastprivate{{/*LastprivateModifier=*/maybeApplyToV(convert, m0), 904f9824439SKrzysztof Parzyszek /*List=*/makeObjects(t1, semaCtx)}}; 905ea2cfcc1SKrzysztof Parzyszek } 906ea2cfcc1SKrzysztof Parzyszek 907ea2cfcc1SKrzysztof Parzyszek Linear make(const parser::OmpClause::Linear &inp, 908ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 909ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpLinearClause 910148a5579SKrzysztof Parzyszek CLAUSET_ENUM_CONVERT( // 911cfd67c21SKrzysztof Parzyszek convert, parser::OmpLinearModifier::Value, Linear::LinearModifier, 912148a5579SKrzysztof Parzyszek // clang-format off 913148a5579SKrzysztof Parzyszek MS(Ref, Ref) 914148a5579SKrzysztof Parzyszek MS(Val, Val) 915148a5579SKrzysztof Parzyszek MS(Uval, Uval) 916148a5579SKrzysztof Parzyszek // clang-format on 917148a5579SKrzysztof Parzyszek ); 918148a5579SKrzysztof Parzyszek 91903cbe426SKrzysztof Parzyszek auto &mods = semantics::OmpGetModifiers(inp.v); 92003cbe426SKrzysztof Parzyszek auto *m0 = 92103cbe426SKrzysztof Parzyszek semantics::OmpGetUniqueModifier<parser::OmpStepComplexModifier>(mods); 92203cbe426SKrzysztof Parzyszek auto *m1 = 92303cbe426SKrzysztof Parzyszek semantics::OmpGetUniqueModifier<parser::OmpStepSimpleModifier>(mods); 92403cbe426SKrzysztof Parzyszek assert((!m0 || !m1) && "Simple and complex modifiers both present"); 925148a5579SKrzysztof Parzyszek 92603cbe426SKrzysztof Parzyszek auto *m2 = semantics::OmpGetUniqueModifier<parser::OmpLinearModifier>(mods); 92703cbe426SKrzysztof Parzyszek auto &t1 = std::get<parser::OmpObjectList>(inp.v.t); 92803cbe426SKrzysztof Parzyszek 92903cbe426SKrzysztof Parzyszek auto &&maybeStep = m0 ? maybeApplyToV(makeExprFn(semaCtx), m0) 93003cbe426SKrzysztof Parzyszek : m1 ? maybeApplyToV(makeExprFn(semaCtx), m1) 93103cbe426SKrzysztof Parzyszek : std::optional<Linear::StepComplexModifier>{}; 93203cbe426SKrzysztof Parzyszek 93303cbe426SKrzysztof Parzyszek return Linear{{/*StepComplexModifier=*/std::move(maybeStep), 93403cbe426SKrzysztof Parzyszek /*LinearModifier=*/maybeApplyToV(convert, m2), 93503cbe426SKrzysztof Parzyszek /*List=*/makeObjects(t1, semaCtx)}}; 936ea2cfcc1SKrzysztof Parzyszek } 937ea2cfcc1SKrzysztof Parzyszek 938ea2cfcc1SKrzysztof Parzyszek Link make(const parser::OmpClause::Link &inp, 939ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 940ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpObjectList 9414d177435SKrzysztof Parzyszek return Link{/*List=*/makeObjects(inp.v, semaCtx)}; 942ea2cfcc1SKrzysztof Parzyszek } 943ea2cfcc1SKrzysztof Parzyszek 944ea2cfcc1SKrzysztof Parzyszek Map make(const parser::OmpClause::Map &inp, 945ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 946ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpMapClause 947148a5579SKrzysztof Parzyszek CLAUSET_ENUM_CONVERT( // 94852755ac2SKrzysztof Parzyszek convert1, parser::OmpMapType::Value, Map::MapType, 949148a5579SKrzysztof Parzyszek // clang-format off 950148a5579SKrzysztof Parzyszek MS(Alloc, Alloc) 951148a5579SKrzysztof Parzyszek MS(Delete, Delete) 952697d65deSKrzysztof Parzyszek MS(From, From) 953697d65deSKrzysztof Parzyszek MS(Release, Release) 954697d65deSKrzysztof Parzyszek MS(To, To) 955697d65deSKrzysztof Parzyszek MS(Tofrom, Tofrom) 956148a5579SKrzysztof Parzyszek // clang-format on 957148a5579SKrzysztof Parzyszek ); 958148a5579SKrzysztof Parzyszek 959697d65deSKrzysztof Parzyszek CLAUSET_ENUM_CONVERT( // 96052755ac2SKrzysztof Parzyszek convert2, parser::OmpMapTypeModifier::Value, Map::MapTypeModifier, 961697d65deSKrzysztof Parzyszek // clang-format off 962697d65deSKrzysztof Parzyszek MS(Always, Always) 963697d65deSKrzysztof Parzyszek MS(Close, Close) 964a8d506b3SKrzysztof Parzyszek MS(Ompx_Hold, OmpxHold) 965697d65deSKrzysztof Parzyszek MS(Present, Present) 966697d65deSKrzysztof Parzyszek // clang-format on 967697d65deSKrzysztof Parzyszek ); 968148a5579SKrzysztof Parzyszek 96952755ac2SKrzysztof Parzyszek auto &mods = semantics::OmpGetModifiers(inp.v); 97052755ac2SKrzysztof Parzyszek auto *t1 = semantics::OmpGetUniqueModifier<parser::OmpMapper>(mods); 97152755ac2SKrzysztof Parzyszek auto *t2 = semantics::OmpGetUniqueModifier<parser::OmpIterator>(mods); 97252755ac2SKrzysztof Parzyszek auto *t3 = semantics::OmpGetUniqueModifier<parser::OmpMapType>(mods); 97352755ac2SKrzysztof Parzyszek auto &t4 = std::get<parser::OmpObjectList>(inp.v.t); 97492604d7cSMats Petersson 97552755ac2SKrzysztof Parzyszek auto mappers = [&]() -> std::optional<List<Mapper>> { 976973fa983SKrzysztof Parzyszek if (t1) 97752755ac2SKrzysztof Parzyszek return List<Mapper>{Mapper{makeObject(t1->v, semaCtx)}}; 978973fa983SKrzysztof Parzyszek return std::nullopt; 979973fa983SKrzysztof Parzyszek }(); 980973fa983SKrzysztof Parzyszek 98152755ac2SKrzysztof Parzyszek auto iterator = [&]() -> std::optional<Iterator> { 982973fa983SKrzysztof Parzyszek if (t2) 98352755ac2SKrzysztof Parzyszek return makeIterator(*t2, semaCtx); 98452755ac2SKrzysztof Parzyszek return std::nullopt; 98552755ac2SKrzysztof Parzyszek }(); 986697d65deSKrzysztof Parzyszek 98752755ac2SKrzysztof Parzyszek auto type = [&]() -> std::optional<Map::MapType> { 98852755ac2SKrzysztof Parzyszek if (t3) 98952755ac2SKrzysztof Parzyszek return convert1(t3->v); 99052755ac2SKrzysztof Parzyszek return Map::MapType::Tofrom; 99152755ac2SKrzysztof Parzyszek }(); 992697d65deSKrzysztof Parzyszek 99352755ac2SKrzysztof Parzyszek Map::MapTypeModifiers typeMods; 99452755ac2SKrzysztof Parzyszek for (auto *typeMod : 99552755ac2SKrzysztof Parzyszek semantics::OmpGetRepeatableModifier<parser::OmpMapTypeModifier>(mods)) { 99652755ac2SKrzysztof Parzyszek typeMods.push_back(convert2(typeMod->v)); 99752755ac2SKrzysztof Parzyszek } 99852755ac2SKrzysztof Parzyszek std::optional<Map::MapTypeModifiers> maybeTypeMods{}; 99952755ac2SKrzysztof Parzyszek if (!typeMods.empty()) 100052755ac2SKrzysztof Parzyszek maybeTypeMods = std::move(typeMods); 100152755ac2SKrzysztof Parzyszek 100252755ac2SKrzysztof Parzyszek return Map{{/*MapType=*/std::move(type), 100352755ac2SKrzysztof Parzyszek /*MapTypeModifiers=*/std::move(maybeTypeMods), 100452755ac2SKrzysztof Parzyszek /*Mapper=*/std::move(mappers), /*Iterator=*/std::move(iterator), 100552755ac2SKrzysztof Parzyszek /*LocatorList=*/makeObjects(t4, semaCtx)}}; 1006148a5579SKrzysztof Parzyszek } 1007148a5579SKrzysztof Parzyszek 1008*15ab7be2SKrzysztof Parzyszek Match make(const parser::OmpClause::Match &inp, 1009*15ab7be2SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1010*15ab7be2SKrzysztof Parzyszek return Match{}; 1011*15ab7be2SKrzysztof Parzyszek } 1012*15ab7be2SKrzysztof Parzyszek 1013148a5579SKrzysztof Parzyszek // MemoryOrder: empty 1014148a5579SKrzysztof Parzyszek // Mergeable: empty 1015148a5579SKrzysztof Parzyszek 1016148a5579SKrzysztof Parzyszek Message make(const parser::OmpClause::Message &inp, 1017148a5579SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1018148a5579SKrzysztof Parzyszek // inp -> empty 1019148a5579SKrzysztof Parzyszek llvm_unreachable("Empty: message"); 1020ea2cfcc1SKrzysztof Parzyszek } 1021ea2cfcc1SKrzysztof Parzyszek 1022ea2cfcc1SKrzysztof Parzyszek Nocontext make(const parser::OmpClause::Nocontext &inp, 1023ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1024ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::ScalarLogicalExpr 1025148a5579SKrzysztof Parzyszek return Nocontext{/*DoNotUpdateContext=*/makeExpr(inp.v, semaCtx)}; 1026ea2cfcc1SKrzysztof Parzyszek } 1027ea2cfcc1SKrzysztof Parzyszek 1028148a5579SKrzysztof Parzyszek // Nogroup: empty 1029148a5579SKrzysztof Parzyszek 1030ea2cfcc1SKrzysztof Parzyszek Nontemporal make(const parser::OmpClause::Nontemporal &inp, 1031ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1032ea2cfcc1SKrzysztof Parzyszek // inp.v -> std::list<parser::Name> 1033148a5579SKrzysztof Parzyszek return Nontemporal{/*List=*/makeList(inp.v, makeObjectFn(semaCtx))}; 1034ea2cfcc1SKrzysztof Parzyszek } 1035ea2cfcc1SKrzysztof Parzyszek 103689c556cfSKrzysztof Parzyszek // NoOpenmp: empty 103789c556cfSKrzysztof Parzyszek // NoOpenmpRoutines: empty 103889c556cfSKrzysztof Parzyszek // NoParallelism: empty 1039148a5579SKrzysztof Parzyszek // Notinbranch: empty 1040148a5579SKrzysztof Parzyszek 1041ea2cfcc1SKrzysztof Parzyszek Novariants make(const parser::OmpClause::Novariants &inp, 1042ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1043ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::ScalarLogicalExpr 1044148a5579SKrzysztof Parzyszek return Novariants{/*DoNotUseVariant=*/makeExpr(inp.v, semaCtx)}; 1045ea2cfcc1SKrzysztof Parzyszek } 1046ea2cfcc1SKrzysztof Parzyszek 1047148a5579SKrzysztof Parzyszek // Nowait: empty 1048148a5579SKrzysztof Parzyszek 1049ea2cfcc1SKrzysztof Parzyszek NumTasks make(const parser::OmpClause::NumTasks &inp, 1050ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 10515621929fSKiran Chandramohan // inp.v -> parser::OmpNumTasksClause 1052bde79c0eSKrzysztof Parzyszek auto &mods = semantics::OmpGetModifiers(inp.v); 1053bde79c0eSKrzysztof Parzyszek auto *m0 = semantics::OmpGetUniqueModifier<parser::OmpPrescriptiveness>(mods); 10545621929fSKiran Chandramohan auto &t1 = std::get<parser::ScalarIntExpr>(inp.v.t); 1055bde79c0eSKrzysztof Parzyszek return NumTasks{{/*Prescriptiveness=*/maybeApplyToV(makePrescriptiveness, m0), 10565621929fSKiran Chandramohan /*NumTasks=*/makeExpr(t1, semaCtx)}}; 1057ea2cfcc1SKrzysztof Parzyszek } 1058ea2cfcc1SKrzysztof Parzyszek 1059ea2cfcc1SKrzysztof Parzyszek NumTeams make(const parser::OmpClause::NumTeams &inp, 1060ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1061ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::ScalarIntExpr 106230646461SKrzysztof Parzyszek List<NumTeams::Range> v{{{/*LowerBound=*/std::nullopt, 106330646461SKrzysztof Parzyszek /*UpperBound=*/makeExpr(inp.v, semaCtx)}}}; 106430646461SKrzysztof Parzyszek return NumTeams{/*List=*/v}; 1065ea2cfcc1SKrzysztof Parzyszek } 1066ea2cfcc1SKrzysztof Parzyszek 1067ea2cfcc1SKrzysztof Parzyszek NumThreads make(const parser::OmpClause::NumThreads &inp, 1068ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1069ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::ScalarIntExpr 1070148a5579SKrzysztof Parzyszek return NumThreads{/*Nthreads=*/makeExpr(inp.v, semaCtx)}; 1071ea2cfcc1SKrzysztof Parzyszek } 1072ea2cfcc1SKrzysztof Parzyszek 1073148a5579SKrzysztof Parzyszek // OmpxAttribute: empty 1074148a5579SKrzysztof Parzyszek // OmpxBare: empty 1075148a5579SKrzysztof Parzyszek 1076ea2cfcc1SKrzysztof Parzyszek OmpxDynCgroupMem make(const parser::OmpClause::OmpxDynCgroupMem &inp, 1077ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1078ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::ScalarIntExpr 1079ea2cfcc1SKrzysztof Parzyszek return OmpxDynCgroupMem{makeExpr(inp.v, semaCtx)}; 1080ea2cfcc1SKrzysztof Parzyszek } 1081ea2cfcc1SKrzysztof Parzyszek 1082ea2cfcc1SKrzysztof Parzyszek Order make(const parser::OmpClause::Order &inp, 1083ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1084ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpOrderClause 1085ea2cfcc1SKrzysztof Parzyszek using wrapped = parser::OmpOrderClause; 1086148a5579SKrzysztof Parzyszek 1087148a5579SKrzysztof Parzyszek CLAUSET_ENUM_CONVERT( // 1088e79cd246SKrzysztof Parzyszek convert1, parser::OmpOrderModifier::Value, Order::OrderModifier, 1089148a5579SKrzysztof Parzyszek // clang-format off 1090148a5579SKrzysztof Parzyszek MS(Reproducible, Reproducible) 1091148a5579SKrzysztof Parzyszek MS(Unconstrained, Unconstrained) 1092148a5579SKrzysztof Parzyszek // clang-format on 1093148a5579SKrzysztof Parzyszek ); 1094148a5579SKrzysztof Parzyszek 1095148a5579SKrzysztof Parzyszek CLAUSET_ENUM_CONVERT( // 1096e79cd246SKrzysztof Parzyszek convert2, wrapped::Ordering, Order::Ordering, 1097148a5579SKrzysztof Parzyszek // clang-format off 1098148a5579SKrzysztof Parzyszek MS(Concurrent, Concurrent) 1099148a5579SKrzysztof Parzyszek // clang-format on 1100148a5579SKrzysztof Parzyszek ); 1101148a5579SKrzysztof Parzyszek 1102e79cd246SKrzysztof Parzyszek auto &mods = semantics::OmpGetModifiers(inp.v); 1103e79cd246SKrzysztof Parzyszek auto *t0 = semantics::OmpGetUniqueModifier<parser::OmpOrderModifier>(mods); 1104e79cd246SKrzysztof Parzyszek auto &t1 = std::get<wrapped::Ordering>(inp.v.t); 1105148a5579SKrzysztof Parzyszek 1106e79cd246SKrzysztof Parzyszek return Order{{/*OrderModifier=*/maybeApplyToV(convert1, t0), 1107e79cd246SKrzysztof Parzyszek /*Ordering=*/convert2(t1)}}; 1108ea2cfcc1SKrzysztof Parzyszek } 1109ea2cfcc1SKrzysztof Parzyszek 1110148a5579SKrzysztof Parzyszek Ordered make(const parser::OmpClause::Ordered &inp, 1111148a5579SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1112148a5579SKrzysztof Parzyszek // inp.v -> std::optional<parser::ScalarIntConstantExpr> 1113148a5579SKrzysztof Parzyszek return Ordered{/*N=*/maybeApply(makeExprFn(semaCtx), inp.v)}; 1114148a5579SKrzysztof Parzyszek } 1115148a5579SKrzysztof Parzyszek 1116*15ab7be2SKrzysztof Parzyszek // See also Default. 1117*15ab7be2SKrzysztof Parzyszek Otherwise make(const parser::OmpClause::Otherwise &inp, 1118*15ab7be2SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1119*15ab7be2SKrzysztof Parzyszek return Otherwise{}; 1120*15ab7be2SKrzysztof Parzyszek } 1121148a5579SKrzysztof Parzyszek 1122ea2cfcc1SKrzysztof Parzyszek Partial make(const parser::OmpClause::Partial &inp, 1123ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1124ea2cfcc1SKrzysztof Parzyszek // inp.v -> std::optional<parser::ScalarIntConstantExpr> 1125148a5579SKrzysztof Parzyszek return Partial{/*UnrollFactor=*/maybeApply(makeExprFn(semaCtx), inp.v)}; 1126ea2cfcc1SKrzysztof Parzyszek } 1127ea2cfcc1SKrzysztof Parzyszek 1128ea2cfcc1SKrzysztof Parzyszek Priority make(const parser::OmpClause::Priority &inp, 1129ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1130ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::ScalarIntExpr 1131148a5579SKrzysztof Parzyszek return Priority{/*PriorityValue=*/makeExpr(inp.v, semaCtx)}; 1132ea2cfcc1SKrzysztof Parzyszek } 1133ea2cfcc1SKrzysztof Parzyszek 1134ea2cfcc1SKrzysztof Parzyszek Private make(const parser::OmpClause::Private &inp, 1135ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1136ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpObjectList 11374d177435SKrzysztof Parzyszek return Private{/*List=*/makeObjects(inp.v, semaCtx)}; 1138ea2cfcc1SKrzysztof Parzyszek } 1139ea2cfcc1SKrzysztof Parzyszek 1140ea2cfcc1SKrzysztof Parzyszek ProcBind make(const parser::OmpClause::ProcBind &inp, 1141ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1142ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpProcBindClause 1143148a5579SKrzysztof Parzyszek using wrapped = parser::OmpProcBindClause; 1144148a5579SKrzysztof Parzyszek 1145148a5579SKrzysztof Parzyszek CLAUSET_ENUM_CONVERT( // 1146608f4ae1SKrzysztof Parzyszek convert, wrapped::AffinityPolicy, ProcBind::AffinityPolicy, 1147148a5579SKrzysztof Parzyszek // clang-format off 1148148a5579SKrzysztof Parzyszek MS(Close, Close) 1149148a5579SKrzysztof Parzyszek MS(Master, Master) 1150148a5579SKrzysztof Parzyszek MS(Spread, Spread) 1151148a5579SKrzysztof Parzyszek MS(Primary, Primary) 1152148a5579SKrzysztof Parzyszek // clang-format on 1153148a5579SKrzysztof Parzyszek ); 1154148a5579SKrzysztof Parzyszek return ProcBind{/*AffinityPolicy=*/convert(inp.v.v)}; 1155ea2cfcc1SKrzysztof Parzyszek } 1156ea2cfcc1SKrzysztof Parzyszek 1157148a5579SKrzysztof Parzyszek // Read: empty 1158148a5579SKrzysztof Parzyszek 1159ea2cfcc1SKrzysztof Parzyszek Reduction make(const parser::OmpClause::Reduction &inp, 1160ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1161ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpReductionClause 116217cb8a53SKiran Chandramohan CLAUSET_ENUM_CONVERT( // 11634fc1141eSKrzysztof Parzyszek convert, parser::OmpReductionModifier::Value, 11644fc1141eSKrzysztof Parzyszek Reduction::ReductionModifier, 116517cb8a53SKiran Chandramohan // clang-format off 116617cb8a53SKiran Chandramohan MS(Inscan, Inscan) 116717cb8a53SKiran Chandramohan MS(Task, Task) 116817cb8a53SKiran Chandramohan MS(Default, Default) 116917cb8a53SKiran Chandramohan // clang-format on 117017cb8a53SKiran Chandramohan ); 117117cb8a53SKiran Chandramohan 11724fc1141eSKrzysztof Parzyszek auto &mods = semantics::OmpGetModifiers(inp.v); 117358f9c4fcSKrzysztof Parzyszek auto *m0 = 11744fc1141eSKrzysztof Parzyszek semantics::OmpGetUniqueModifier<parser::OmpReductionModifier>(mods); 117558f9c4fcSKrzysztof Parzyszek auto *m1 = 11764fc1141eSKrzysztof Parzyszek semantics::OmpGetUniqueModifier<parser::OmpReductionIdentifier>(mods); 117758f9c4fcSKrzysztof Parzyszek auto &t1 = std::get<parser::OmpObjectList>(inp.v.t); 117858f9c4fcSKrzysztof Parzyszek assert(m1 && "OmpReductionIdentifier is required"); 1179e79cd246SKrzysztof Parzyszek 1180148a5579SKrzysztof Parzyszek return Reduction{ 118158f9c4fcSKrzysztof Parzyszek {/*ReductionModifier=*/maybeApplyToV(convert, m0), 118258f9c4fcSKrzysztof Parzyszek /*ReductionIdentifiers=*/{makeReductionOperator(*m1, semaCtx)}, 118358f9c4fcSKrzysztof Parzyszek /*List=*/makeObjects(t1, semaCtx)}}; 1184ea2cfcc1SKrzysztof Parzyszek } 1185ea2cfcc1SKrzysztof Parzyszek 1186148a5579SKrzysztof Parzyszek // Relaxed: empty 1187148a5579SKrzysztof Parzyszek // Release: empty 1188148a5579SKrzysztof Parzyszek // ReverseOffload: empty 1189148a5579SKrzysztof Parzyszek 1190ea2cfcc1SKrzysztof Parzyszek Safelen make(const parser::OmpClause::Safelen &inp, 1191ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1192ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::ScalarIntConstantExpr 1193148a5579SKrzysztof Parzyszek return Safelen{/*Length=*/makeExpr(inp.v, semaCtx)}; 1194ea2cfcc1SKrzysztof Parzyszek } 1195ea2cfcc1SKrzysztof Parzyszek 1196ea2cfcc1SKrzysztof Parzyszek Schedule make(const parser::OmpClause::Schedule &inp, 1197ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1198ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpScheduleClause 1199ea2cfcc1SKrzysztof Parzyszek using wrapped = parser::OmpScheduleClause; 1200ea2cfcc1SKrzysztof Parzyszek 1201148a5579SKrzysztof Parzyszek CLAUSET_ENUM_CONVERT( // 1202e79cd246SKrzysztof Parzyszek convert1, wrapped::Kind, Schedule::Kind, 1203148a5579SKrzysztof Parzyszek // clang-format off 1204148a5579SKrzysztof Parzyszek MS(Static, Static) 1205148a5579SKrzysztof Parzyszek MS(Dynamic, Dynamic) 1206148a5579SKrzysztof Parzyszek MS(Guided, Guided) 1207148a5579SKrzysztof Parzyszek MS(Auto, Auto) 1208148a5579SKrzysztof Parzyszek MS(Runtime, Runtime) 1209148a5579SKrzysztof Parzyszek // clang-format on 1210148a5579SKrzysztof Parzyszek ); 1211148a5579SKrzysztof Parzyszek 1212148a5579SKrzysztof Parzyszek CLAUSET_ENUM_CONVERT( // 1213e79cd246SKrzysztof Parzyszek convert2, parser::OmpOrderingModifier::Value, Schedule::OrderingModifier, 1214148a5579SKrzysztof Parzyszek // clang-format off 1215148a5579SKrzysztof Parzyszek MS(Monotonic, Monotonic) 1216148a5579SKrzysztof Parzyszek MS(Nonmonotonic, Nonmonotonic) 1217148a5579SKrzysztof Parzyszek // clang-format on 1218148a5579SKrzysztof Parzyszek ); 1219148a5579SKrzysztof Parzyszek 1220148a5579SKrzysztof Parzyszek CLAUSET_ENUM_CONVERT( // 1221e79cd246SKrzysztof Parzyszek convert3, parser::OmpChunkModifier::Value, Schedule::ChunkModifier, 1222148a5579SKrzysztof Parzyszek // clang-format off 1223148a5579SKrzysztof Parzyszek MS(Simd, Simd) 1224148a5579SKrzysztof Parzyszek // clang-format on 1225148a5579SKrzysztof Parzyszek ); 1226148a5579SKrzysztof Parzyszek 1227e79cd246SKrzysztof Parzyszek auto &mods = semantics::OmpGetModifiers(inp.v); 1228e79cd246SKrzysztof Parzyszek auto *t0 = semantics::OmpGetUniqueModifier<parser::OmpOrderingModifier>(mods); 1229e79cd246SKrzysztof Parzyszek auto *t1 = semantics::OmpGetUniqueModifier<parser::OmpChunkModifier>(mods); 1230e79cd246SKrzysztof Parzyszek auto &t2 = std::get<wrapped::Kind>(inp.v.t); 1231e79cd246SKrzysztof Parzyszek auto &t3 = std::get<std::optional<parser::ScalarIntExpr>>(inp.v.t); 1232ea2cfcc1SKrzysztof Parzyszek 1233e79cd246SKrzysztof Parzyszek return Schedule{{/*Kind=*/convert1(t2), 1234e79cd246SKrzysztof Parzyszek /*OrderingModifier=*/maybeApplyToV(convert2, t0), 1235e79cd246SKrzysztof Parzyszek /*ChunkModifier=*/maybeApplyToV(convert3, t1), 1236e79cd246SKrzysztof Parzyszek /*ChunkSize=*/maybeApply(makeExprFn(semaCtx), t3)}}; 1237148a5579SKrzysztof Parzyszek } 1238148a5579SKrzysztof Parzyszek 1239148a5579SKrzysztof Parzyszek // SeqCst: empty 1240148a5579SKrzysztof Parzyszek 1241148a5579SKrzysztof Parzyszek Severity make(const parser::OmpClause::Severity &inp, 1242148a5579SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1243148a5579SKrzysztof Parzyszek // inp -> empty 1244148a5579SKrzysztof Parzyszek llvm_unreachable("Empty: severity"); 1245ea2cfcc1SKrzysztof Parzyszek } 1246ea2cfcc1SKrzysztof Parzyszek 1247ea2cfcc1SKrzysztof Parzyszek Shared make(const parser::OmpClause::Shared &inp, 1248ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1249ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpObjectList 12504d177435SKrzysztof Parzyszek return Shared{/*List=*/makeObjects(inp.v, semaCtx)}; 1251ea2cfcc1SKrzysztof Parzyszek } 1252ea2cfcc1SKrzysztof Parzyszek 1253148a5579SKrzysztof Parzyszek // Simd: empty 1254148a5579SKrzysztof Parzyszek 1255ea2cfcc1SKrzysztof Parzyszek Simdlen make(const parser::OmpClause::Simdlen &inp, 1256ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1257ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::ScalarIntConstantExpr 1258148a5579SKrzysztof Parzyszek return Simdlen{/*Length=*/makeExpr(inp.v, semaCtx)}; 1259ea2cfcc1SKrzysztof Parzyszek } 1260ea2cfcc1SKrzysztof Parzyszek 1261ea2cfcc1SKrzysztof Parzyszek Sizes make(const parser::OmpClause::Sizes &inp, 1262ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1263ea2cfcc1SKrzysztof Parzyszek // inp.v -> std::list<parser::ScalarIntExpr> 1264148a5579SKrzysztof Parzyszek return Sizes{/*SizeList=*/makeList(inp.v, makeExprFn(semaCtx))}; 1265ea2cfcc1SKrzysztof Parzyszek } 1266ea2cfcc1SKrzysztof Parzyszek 12675b03efb8SMichael Kruse Permutation make(const parser::OmpClause::Permutation &inp, 12685b03efb8SMichael Kruse semantics::SemanticsContext &semaCtx) { 12695b03efb8SMichael Kruse // inp.v -> std::list<parser::ScalarIntConstantExpr> 12705b03efb8SMichael Kruse return Permutation{/*ArgList=*/makeList(inp.v, makeExprFn(semaCtx))}; 12715b03efb8SMichael Kruse } 12725b03efb8SMichael Kruse 1273ea2cfcc1SKrzysztof Parzyszek TaskReduction make(const parser::OmpClause::TaskReduction &inp, 1274ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1275ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpReductionClause 12764fc1141eSKrzysztof Parzyszek auto &mods = semantics::OmpGetModifiers(inp.v); 127758f9c4fcSKrzysztof Parzyszek auto *m0 = 12784fc1141eSKrzysztof Parzyszek semantics::OmpGetUniqueModifier<parser::OmpReductionIdentifier>(mods); 1279ea2cfcc1SKrzysztof Parzyszek auto &t1 = std::get<parser::OmpObjectList>(inp.v.t); 128058f9c4fcSKrzysztof Parzyszek assert(m0 && "OmpReductionIdentifier is required"); 1281e79cd246SKrzysztof Parzyszek 1282ea2cfcc1SKrzysztof Parzyszek return TaskReduction{ 128358f9c4fcSKrzysztof Parzyszek {/*ReductionIdentifiers=*/{makeReductionOperator(*m0, semaCtx)}, 12844d177435SKrzysztof Parzyszek /*List=*/makeObjects(t1, semaCtx)}}; 1285ea2cfcc1SKrzysztof Parzyszek } 1286ea2cfcc1SKrzysztof Parzyszek 1287ea2cfcc1SKrzysztof Parzyszek ThreadLimit make(const parser::OmpClause::ThreadLimit &inp, 1288ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1289ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::ScalarIntExpr 1290148a5579SKrzysztof Parzyszek return ThreadLimit{/*Threadlim=*/makeExpr(inp.v, semaCtx)}; 1291ea2cfcc1SKrzysztof Parzyszek } 1292ea2cfcc1SKrzysztof Parzyszek 1293148a5579SKrzysztof Parzyszek // Threadprivate: empty 1294148a5579SKrzysztof Parzyszek // Threads: empty 1295148a5579SKrzysztof Parzyszek 1296ea2cfcc1SKrzysztof Parzyszek To make(const parser::OmpClause::To &inp, 1297ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 12981c6ec29bSKrzysztof Parzyszek // inp.v -> parser::OmpToClause 12991c6ec29bSKrzysztof Parzyszek CLAUSET_ENUM_CONVERT( // 130052755ac2SKrzysztof Parzyszek convert, parser::OmpExpectation::Value, To::Expectation, 13011c6ec29bSKrzysztof Parzyszek // clang-format off 13021c6ec29bSKrzysztof Parzyszek MS(Present, Present) 13031c6ec29bSKrzysztof Parzyszek // clang-format on 13041c6ec29bSKrzysztof Parzyszek ); 13051c6ec29bSKrzysztof Parzyszek 130652755ac2SKrzysztof Parzyszek auto &mods = semantics::OmpGetModifiers(inp.v); 130752755ac2SKrzysztof Parzyszek auto *t0 = semantics::OmpGetUniqueModifier<parser::OmpExpectation>(mods); 130852755ac2SKrzysztof Parzyszek auto *t1 = semantics::OmpGetUniqueModifier<parser::OmpMapper>(mods); 130952755ac2SKrzysztof Parzyszek auto *t2 = semantics::OmpGetUniqueModifier<parser::OmpIterator>(mods); 131052755ac2SKrzysztof Parzyszek auto &t3 = std::get<parser::OmpObjectList>(inp.v.t); 13111c6ec29bSKrzysztof Parzyszek 131252755ac2SKrzysztof Parzyszek auto mappers = [&]() -> std::optional<List<Mapper>> { 131352755ac2SKrzysztof Parzyszek if (t1) 131452755ac2SKrzysztof Parzyszek return List<Mapper>{Mapper{makeObject(t1->v, semaCtx)}}; 13151c6ec29bSKrzysztof Parzyszek return std::nullopt; 13161c6ec29bSKrzysztof Parzyszek }(); 13171c6ec29bSKrzysztof Parzyszek 13181c6ec29bSKrzysztof Parzyszek auto iterator = [&]() -> std::optional<Iterator> { 131952755ac2SKrzysztof Parzyszek if (t2) 132052755ac2SKrzysztof Parzyszek return makeIterator(*t2, semaCtx); 13211c6ec29bSKrzysztof Parzyszek return std::nullopt; 13221c6ec29bSKrzysztof Parzyszek }(); 13231c6ec29bSKrzysztof Parzyszek 132452755ac2SKrzysztof Parzyszek return To{{/*Expectation=*/maybeApplyToV(convert, t0), 132552755ac2SKrzysztof Parzyszek /*Mappers=*/{std::move(mappers)}, 13261c6ec29bSKrzysztof Parzyszek /*Iterator=*/std::move(iterator), 132752755ac2SKrzysztof Parzyszek /*LocatorList=*/makeObjects(t3, semaCtx)}}; 1328ea2cfcc1SKrzysztof Parzyszek } 1329ea2cfcc1SKrzysztof Parzyszek 1330148a5579SKrzysztof Parzyszek // UnifiedAddress: empty 1331148a5579SKrzysztof Parzyszek // UnifiedSharedMemory: empty 1332148a5579SKrzysztof Parzyszek 1333ea2cfcc1SKrzysztof Parzyszek Uniform make(const parser::OmpClause::Uniform &inp, 1334ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1335ea2cfcc1SKrzysztof Parzyszek // inp.v -> std::list<parser::Name> 1336148a5579SKrzysztof Parzyszek return Uniform{/*ParameterList=*/makeList(inp.v, makeObjectFn(semaCtx))}; 1337148a5579SKrzysztof Parzyszek } 1338148a5579SKrzysztof Parzyszek 1339148a5579SKrzysztof Parzyszek // Unknown: empty 1340148a5579SKrzysztof Parzyszek // Untied: empty 1341148a5579SKrzysztof Parzyszek 1342148a5579SKrzysztof Parzyszek Update make(const parser::OmpClause::Update &inp, 1343148a5579SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1344c478aab6SKrzysztof Parzyszek // inp.v -> parser::OmpUpdateClause 1345f87737f3SKrzysztof Parzyszek auto depType = 1346f87737f3SKrzysztof Parzyszek common::visit([](auto &&s) { return makeDepType(s); }, inp.v.u); 1347f87737f3SKrzysztof Parzyszek return Update{/*DependenceType=*/depType}; 1348148a5579SKrzysztof Parzyszek } 1349148a5579SKrzysztof Parzyszek 1350148a5579SKrzysztof Parzyszek Use make(const parser::OmpClause::Use &inp, 1351148a5579SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1352148a5579SKrzysztof Parzyszek // inp -> empty 1353148a5579SKrzysztof Parzyszek llvm_unreachable("Empty: use"); 1354ea2cfcc1SKrzysztof Parzyszek } 1355ea2cfcc1SKrzysztof Parzyszek 1356ea2cfcc1SKrzysztof Parzyszek UseDeviceAddr make(const parser::OmpClause::UseDeviceAddr &inp, 1357ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1358ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpObjectList 13594d177435SKrzysztof Parzyszek return UseDeviceAddr{/*List=*/makeObjects(inp.v, semaCtx)}; 1360ea2cfcc1SKrzysztof Parzyszek } 1361ea2cfcc1SKrzysztof Parzyszek 1362ea2cfcc1SKrzysztof Parzyszek UseDevicePtr make(const parser::OmpClause::UseDevicePtr &inp, 1363ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1364ea2cfcc1SKrzysztof Parzyszek // inp.v -> parser::OmpObjectList 13654d177435SKrzysztof Parzyszek return UseDevicePtr{/*List=*/makeObjects(inp.v, semaCtx)}; 1366ea2cfcc1SKrzysztof Parzyszek } 1367148a5579SKrzysztof Parzyszek 1368148a5579SKrzysztof Parzyszek UsesAllocators make(const parser::OmpClause::UsesAllocators &inp, 1369148a5579SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1370148a5579SKrzysztof Parzyszek // inp -> empty 1371148a5579SKrzysztof Parzyszek llvm_unreachable("Empty: uses_allocators"); 1372148a5579SKrzysztof Parzyszek } 1373148a5579SKrzysztof Parzyszek 1374148a5579SKrzysztof Parzyszek // Weak: empty 1375*15ab7be2SKrzysztof Parzyszek 1376*15ab7be2SKrzysztof Parzyszek When make(const parser::OmpClause::When &inp, 1377*15ab7be2SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1378*15ab7be2SKrzysztof Parzyszek return When{}; 1379*15ab7be2SKrzysztof Parzyszek } 1380*15ab7be2SKrzysztof Parzyszek 1381148a5579SKrzysztof Parzyszek // Write: empty 1382ea2cfcc1SKrzysztof Parzyszek } // namespace clause 1383ea2cfcc1SKrzysztof Parzyszek 13847a66e420SKrzysztof Parzyszek Clause makeClause(const parser::OmpClause &cls, 1385ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1386*15ab7be2SKrzysztof Parzyszek return Fortran::common::visit( // 1387*15ab7be2SKrzysztof Parzyszek common::visitors{ 1388*15ab7be2SKrzysztof Parzyszek [&](const parser::OmpClause::Default &s) { 1389*15ab7be2SKrzysztof Parzyszek using DSA = parser::OmpDefaultClause::DataSharingAttribute; 1390*15ab7be2SKrzysztof Parzyszek if (std::holds_alternative<DSA>(s.v.u)) { 1391*15ab7be2SKrzysztof Parzyszek return makeClause(llvm::omp::Clause::OMPC_default, 1392*15ab7be2SKrzysztof Parzyszek clause::makeDefault(s, semaCtx), cls.source); 1393*15ab7be2SKrzysztof Parzyszek } else { 1394*15ab7be2SKrzysztof Parzyszek return makeClause(llvm::omp::Clause::OMPC_otherwise, 1395*15ab7be2SKrzysztof Parzyszek clause::makeOtherwise(s, semaCtx), cls.source); 1396*15ab7be2SKrzysztof Parzyszek } 1397*15ab7be2SKrzysztof Parzyszek }, 1398ea2cfcc1SKrzysztof Parzyszek [&](auto &&s) { 1399852e4779SKrzysztof Parzyszek return makeClause(cls.Id(), clause::make(s, semaCtx), cls.source); 1400ea2cfcc1SKrzysztof Parzyszek }, 1401*15ab7be2SKrzysztof Parzyszek }, 1402ea2cfcc1SKrzysztof Parzyszek cls.u); 1403ea2cfcc1SKrzysztof Parzyszek } 1404ea2cfcc1SKrzysztof Parzyszek 14054d177435SKrzysztof Parzyszek List<Clause> makeClauses(const parser::OmpClauseList &clauses, 1406ea2cfcc1SKrzysztof Parzyszek semantics::SemanticsContext &semaCtx) { 1407ea2cfcc1SKrzysztof Parzyszek return makeList(clauses.v, [&](const parser::OmpClause &s) { 1408ea2cfcc1SKrzysztof Parzyszek return makeClause(s, semaCtx); 1409ea2cfcc1SKrzysztof Parzyszek }); 1410ea2cfcc1SKrzysztof Parzyszek } 1411be7c9e39SKrzysztof Parzyszek 1412be7c9e39SKrzysztof Parzyszek bool transferLocations(const List<Clause> &from, List<Clause> &to) { 1413be7c9e39SKrzysztof Parzyszek bool allDone = true; 1414be7c9e39SKrzysztof Parzyszek 1415be7c9e39SKrzysztof Parzyszek for (Clause &clause : to) { 1416be7c9e39SKrzysztof Parzyszek if (!clause.source.empty()) 1417be7c9e39SKrzysztof Parzyszek continue; 1418be7c9e39SKrzysztof Parzyszek auto found = 1419be7c9e39SKrzysztof Parzyszek llvm::find_if(from, [&](const Clause &c) { return c.id == clause.id; }); 1420be7c9e39SKrzysztof Parzyszek // This is not completely accurate, but should be good enough for now. 1421be7c9e39SKrzysztof Parzyszek // It can be improved in the future if necessary, but in cases of 1422be7c9e39SKrzysztof Parzyszek // synthesized clauses getting accurate location may be impossible. 1423be7c9e39SKrzysztof Parzyszek if (found != from.end()) { 1424be7c9e39SKrzysztof Parzyszek clause.source = found->source; 1425be7c9e39SKrzysztof Parzyszek } else { 1426be7c9e39SKrzysztof Parzyszek // Found a clause that won't have "source". 1427be7c9e39SKrzysztof Parzyszek allDone = false; 1428be7c9e39SKrzysztof Parzyszek } 1429be7c9e39SKrzysztof Parzyszek } 1430be7c9e39SKrzysztof Parzyszek 1431be7c9e39SKrzysztof Parzyszek return allDone; 1432be7c9e39SKrzysztof Parzyszek } 1433be7c9e39SKrzysztof Parzyszek 1434f9e55796SKrzysztof Parzyszek } // namespace Fortran::lower::omp 1435