xref: /llvm-project/flang/lib/Lower/OpenMP/Clauses.cpp (revision 15ab7be2e049bc0f4ea6744ca037395686a923bc)
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