14#ifndef FORTRAN_SEMANTICS_CHECK_OMP_STRUCTURE_H_
15#define FORTRAN_SEMANTICS_CHECK_OMP_STRUCTURE_H_
17#include "check-directive-structure.h"
18#include "flang/Common/enum-set.h"
19#include "flang/Parser/parse-tree.h"
20#include "flang/Semantics/openmp-directive-sets.h"
21#include "flang/Semantics/semantics.h"
22#include "llvm/Frontend/OpenMP/OMPConstants.h"
27#define GEN_FLANG_DIRECTIVE_CLAUSE_SETS
28#include "llvm/Frontend/OpenMP/OMP.inc"
33 Clause::OMPC_private, Clause::OMPC_firstprivate, Clause::OMPC_lastprivate};
42 Directive::OMPD_do_simd,
43 Directive::OMPD_sections,
44 Directive::OMPD_single,
45 Directive::OMPD_workshare,
50namespace Fortran::semantics {
54using SymbolSourceMap = std::multimap<const Symbol *, parser::CharBlock>;
56using DirectivesClauseTriple = std::multimap<llvm::omp::Directive,
57 std::pair<llvm::omp::Directive, const OmpClauseSet>>;
61 parser::OmpClause, llvm::omp::Clause_enumSize> {
68#define GEN_FLANG_DIRECTIVE_CLAUSE_MAP
69#include
"llvm/Frontend/OpenMP/OMP.inc"
72 using llvmOmpClause =
const llvm::omp::Clause;
155 void Enter(
const parser::OmpContextSelector &);
156 void Leave(
const parser::OmpContextSelector &);
158#define GEN_FLANG_CLAUSE_CHECK_ENTER
159#include "llvm/Frontend/OpenMP/OMP.inc"
161 void Leave(
const parser::OmpClause::Fail &);
166 bool CheckAllowedClause(llvmOmpClause clause);
167 bool IsVariableListItem(
const Symbol &sym);
168 bool IsExtendedListItem(
const Symbol &sym);
169 bool IsCommonBlock(
const Symbol &sym);
171 void CheckMultipleOccurrence(semantics::UnorderedSymbolSet &listVars,
173 const std::string &clauseName);
174 void CheckMultListItems();
175 void CheckStructureComponent(
176 const parser::OmpObjectList &objects, llvm::omp::Clause clauseId);
177 bool HasInvalidWorksharingNesting(
180 void HasInvalidTeamsNesting(
185 void CheckAllowedMapTypes(
const parser::OmpMapType::Value &,
186 const std::list<parser::OmpMapType::Value> &);
187 llvm::StringRef getClauseName(llvm::omp::Clause clause)
override;
188 llvm::StringRef getDirectiveName(llvm::omp::Directive directive)
override;
191 typename LessTy,
typename RangeTy,
192 typename IterTy =
decltype(std::declval<RangeTy>().begin())>
193 std::optional<IterTy> FindDuplicate(RangeTy &&);
196 std::optional<parser::CharBlock> GetObjectSource(
199 void CheckDependArraySection(
204 const parser::OmpObjectList &objList, llvm::StringRef clause =
"");
205 void CheckThreadprivateOrDeclareTargetVar(
206 const parser::OmpObjectList &objList);
207 void CheckSymbolNames(
209 void CheckIntentInPointer(SymbolSourceMap &,
const llvm::omp::Clause);
210 void CheckProcedurePointer(SymbolSourceMap &,
const llvm::omp::Clause);
211 void CheckCrayPointee(
const parser::OmpObjectList &objectList,
212 llvm::StringRef clause,
bool suggestToUseCrayPointer =
true);
213 void GetSymbolsInObjectList(
const parser::OmpObjectList &, SymbolSourceMap &);
214 void CheckDefinableObjects(SymbolSourceMap &,
const llvm::omp::Clause);
215 void CheckCopyingPolymorphicAllocatable(
216 SymbolSourceMap &,
const llvm::omp::Clause);
217 void CheckPrivateSymbolsInOuterCxt(
218 SymbolSourceMap &, DirectivesClauseTriple &,
const llvm::omp::Clause);
221 void CheckIsLoopIvPartOfClause(
222 llvmOmpClause clause,
const parser::OmpObjectList &ompObjectList);
223 bool CheckTargetBlockOnlyTeams(
const parser::Block &);
231 template <
typename T,
typename D>
bool IsOperatorValid(
const T &,
const D &);
232 void CheckAtomicMemoryOrderClause(
243 void CheckTargetUpdate();
244 void CheckDependenceType(
const parser::OmpDependenceType::Value &x);
245 void CheckTaskDependenceType(
const parser::OmpTaskDependenceType::Value &x);
246 void CheckCancellationNest(
249 void CheckReductionObjects(
250 const parser::OmpObjectList &objects, llvm::omp::Clause clauseId);
253 void CheckReductionObjectTypes(
const parser::OmpObjectList &objects,
257 void ChecksOnOrderedAsBlock();
260 void ChecksOnOrderedAsStandalone();
261 void CheckOrderedDependClause(std::optional<std::int64_t> orderedValue);
262 void CheckReductionArraySection(
263 const parser::OmpObjectList &ompObjectList, llvm::omp::Clause clauseId);
265 const parser::Name &name,
const llvm::omp::Clause clause);
266 void CheckSharedBindingInOuterContext(
267 const parser::OmpObjectList &ompObjectList);
272 const parser::OmpObjectList &ompObjectList);
273 void CheckPredefinedAllocatorRestriction(
275 bool isPredefinedAllocator{
false};
277 void CheckAllowedRequiresClause(llvmOmpClause clause);
278 bool deviceConstructFound_{
false};
282 void EnterDirectiveNest(
const int index) { directiveNest_[index]++; }
283 void ExitDirectiveNest(
const int index) { directiveNest_[index]--; }
284 int GetDirectiveNest(
const int index) {
return directiveNest_[index]; }
285 template <
typename D>
void CheckHintClause(D *, D *);
287 inline void ErrIfLHSAndRHSSymbolsMatch(
289 inline void ErrIfNonScalarAssignmentStmt(
291 enum directiveNestType :
int {
293 TargetBlockOnlyTeams,
297 LastType = ContextSelectorNest,
299 int directiveNest_[LastType + 1] = {0};
301 SymbolSourceMap deferredNonVariables_;
305 std::vector<LoopConstruct> loopStack_;
306 bool isFailClause{
false};
311template <
typename LessTy,
typename RangeTy,
typename IterTy>
312std::optional<IterTy> OmpStructureChecker::FindDuplicate(RangeTy &&range) {
316 std::set<IterTy, LessTy> uniq;
317 for (
auto it{range.begin()}, end{range.end()}; it != end; ++it) {
318 if (!uniq.insert(it).second) {
Definition: enum-set.h:28
Definition: indirection.h:31
Definition: char-block.h:28
Definition: check-directive-structure.h:181
Definition: check-omp-structure.h:61
Definition: semantics.h:67
Definition: parse-tree.h:1911
Definition: parse-tree.h:2016
Definition: parse-tree.h:1818
Definition: parse-tree.h:2338
Definition: parse-tree.h:1700
Definition: parse-tree.h:580
Definition: parse-tree.h:4646
Definition: parse-tree.h:4610
Definition: parse-tree.h:4662
Definition: parse-tree.h:4619
Definition: parse-tree.h:4637
Definition: parse-tree.h:4628
Definition: parse-tree.h:4671
Definition: parse-tree.h:4796
Definition: parse-tree.h:4369
Definition: parse-tree.h:4353
Definition: parse-tree.h:4460
Definition: parse-tree.h:4455
Definition: parse-tree.h:3462
Definition: parse-tree.h:4037
Definition: parse-tree.h:4802
Definition: parse-tree.h:4790
Definition: parse-tree.h:4418
Definition: parse-tree.h:4394
Definition: parse-tree.h:4110
Definition: parse-tree.h:3474
Definition: parse-tree.h:4581
Definition: parse-tree.h:4683
Definition: parse-tree.h:4808
Definition: parse-tree.h:4711
Definition: parse-tree.h:4704
Definition: parse-tree.h:4823
Definition: parse-tree.h:4557
Definition: parse-tree.h:4530
Definition: parse-tree.h:4536
Definition: parse-tree.h:4483
Definition: parse-tree.h:4509
Definition: parse-tree.h:4470
Definition: parse-tree.h:4724
Definition: parse-tree.h:4747
Definition: parse-tree.h:4566
Definition: parse-tree.h:4756
Definition: parse-tree.h:4814
Definition: parse-tree.h:4516
Definition: parse-tree.h:4439
Definition: parse-tree.h:4769
Definition: parse-tree.h:4523
Definition: parse-tree.h:1865
Definition: parse-tree.h:3678
Definition: parse-tree.h:3750
Definition: parse-tree.h:3840
Definition: parse-tree.h:3849