9#ifndef FORTRAN_SEMANTICS_OPENMP_MODIFIERS_H_
10#define FORTRAN_SEMANTICS_OPENMP_MODIFIERS_H_
12#include "flang/Parser/characters.h"
13#include "flang/Parser/parse-tree.h"
14#include "flang/Semantics/openmp-utils.h"
15#include "flang/Semantics/semantics.h"
16#include "llvm/ADT/STLExtras.h"
17#include "llvm/ADT/StringRef.h"
18#include "llvm/Frontend/OpenMP/OMP.h"
19#include "llvm/Frontend/OpenMP/OMPDescriptors.h"
27namespace Fortran::semantics {
69template <
typename UnionTy>
70const llvm::omp::descriptor::Modifier &OmpGetDescriptor(
71 const UnionTy &modifier) {
73 [](
auto &&m) ->
decltype(
auto) {
74 using SpecificTy = llvm::remove_cvref_t<
decltype(m)>;
75 return llvm::omp::getDescriptor(SpecificTy::Id);
83template <
typename ClauseTy>
84const std::optional<std::list<typename ClauseTy::Modifier>> &OmpGetModifiers(
85 const ClauseTy &clause) {
86 using UnionTy =
typename ClauseTy::Modifier;
87 return std::get<std::optional<std::list<UnionTy>>>(clause.t);
97template <
typename SpecificTy,
typename UnionTy>
98typename std::list<UnionTy>::const_iterator findInRange(
99 typename std::list<UnionTy>::const_iterator begin,
100 typename std::list<UnionTy>::const_iterator end) {
101 for (
auto it{begin}; it != end; ++it) {
102 if (std::holds_alternative<SpecificTy>(it->u)) {
113template <
typename SpecificTy,
typename UnionTy>
114const SpecificTy *OmpGetUniqueModifier(
115 const std::optional<std::list<UnionTy>> &modifiers) {
116 const SpecificTy *found{
nullptr};
118 auto end{modifiers->cend()};
119 auto at{detail::findInRange<SpecificTy, UnionTy>(modifiers->cbegin(), end)};
121 found = &std::get<SpecificTy>(at->u);
127template <
typename SpecificTy>
struct OmpSpecificModifierIterator {
128 using VectorTy = std::vector<const SpecificTy *>;
129 OmpSpecificModifierIterator(
130 std::shared_ptr<VectorTy> list,
typename VectorTy::const_iterator where)
131 : specificList(list), at(where) {}
133 OmpSpecificModifierIterator &operator++() {
138 OmpSpecificModifierIterator &operator--() {
144 const SpecificTy *operator*()
const {
return *at; }
145 bool operator==(
const OmpSpecificModifierIterator &other)
const {
146 assert(specificList.get() == other.specificList.get() &&
147 "comparing unrelated iterators");
148 return at == other.at;
150 bool operator!=(
const OmpSpecificModifierIterator &other)
const {
151 return !(*
this == other);
155 std::shared_ptr<VectorTy> specificList;
156 typename VectorTy::const_iterator at;
159template <
typename SpecificTy,
typename UnionTy>
160llvm::iterator_range<OmpSpecificModifierIterator<SpecificTy>>
161OmpGetRepeatableModifier(
const std::optional<std::list<UnionTy>> &modifiers) {
162 using VectorTy = std::vector<const SpecificTy *>;
163 std::shared_ptr<VectorTy> items(
new VectorTy);
165 for (
auto &m : *modifiers) {
166 if (
auto *s = std::get_if<SpecificTy>(&m.u)) {
171 return llvm::iterator_range(
177template <
typename SpecificTy,
typename UnionTy>
178llvm::iterator_range<OmpSpecificModifierIterator<SpecificTy>>
179OmpGetRepeatableModifier(std::optional<std::list<UnionTy>> &&) =
delete;
181template <
typename SpecificTy,
typename UnionTy>
182Fortran::parser::CharBlock OmpGetModifierSource(
183 const std::optional<std::list<UnionTy>> &modifiers,
184 const SpecificTy *specific) {
185 if (!modifiers || !specific) {
186 return Fortran::parser::CharBlock{};
188 for (
auto &m : *modifiers) {
189 if (std::get_if<SpecificTy>(&m.u) == specific) {
193 llvm_unreachable(
"`specific` must be a member of `modifiers`");
Definition openmp-modifiers.h:127