62class OmpStructureChecker :
public OmpStructureCheckerBase {
64 using Base = OmpStructureCheckerBase;
68 using llvmOmpClause =
const llvm::omp::Clause;
79 bool Enter(
const parser::EndSubroutineStmt &);
81 bool Enter(
const parser::EndFunctionStmt &);
87 void Enter(
const parser::ExecutionPart &);
88 void Leave(
const parser::ExecutionPart &);
176 void Enter(
const parser::OmpContextSelector &);
177 void Leave(
const parser::OmpContextSelector &);
179#define GEN_FLANG_CLAUSE_CHECK_ENTER
180#include "llvm/Frontend/OpenMP/OMP.inc"
183 bool CheckAllowedClause(llvmOmpClause clause);
184 void CheckVariableListItem(
const SymbolSourceMap &symbols);
185 void CheckDirectiveSpelling(
189 void CheckMultipleOccurrence(semantics::UnorderedSymbolSet &listVars,
191 const std::string &clauseName);
192 void CheckMultListItems();
193 void CheckStructureComponent(
195 bool HasInvalidWorksharingNesting(
197 bool IsCloselyNestedRegion(
const OmpDirectiveSet &set);
198 bool IsNestedInDirective(llvm::omp::Directive directive);
199 bool InTargetRegion();
200 void HasInvalidTeamsNesting(
204 bool HasRequires(llvm::omp::Clause req);
206 void CheckAllowedMapTypes(
209 const std::list<parser::OmpTraitProperty> &GetTraitPropertyList(
211 std::optional<llvm::omp::Clause> GetClauseFromProperty(
214 void CheckTraitSelectorList(
const std::list<parser::OmpTraitSelector> &);
217 bool VerifyTraitPropertyLists(
219 void CheckTraitSelector(
223 void CheckTraitCondition(
225 void CheckTraitDeviceNum(
227 void CheckTraitRequires(
232 llvm::StringRef getClauseName(llvm::omp::Clause clause)
override;
233 llvm::StringRef getDirectiveName(llvm::omp::Directive directive)
override;
236 typename LessTy,
typename RangeTy,
237 typename IterTy =
decltype(std::declval<RangeTy>().begin())>
238 std::optional<IterTy> FindDuplicate(RangeTy &&);
241 void CheckDependArraySection(
252 void CheckThreadprivateOrDeclareTargetVar(
const parser::Name &);
255 void CheckSymbolName(
257 void CheckSymbolNames(
259 void CheckIntentInPointer(SymbolSourceMap &,
const llvm::omp::Clause);
260 void CheckProcedurePointer(SymbolSourceMap &,
const llvm::omp::Clause);
262 llvm::StringRef clause,
bool suggestToUseCrayPointer =
true);
264 void CheckDefinableObjects(SymbolSourceMap &,
const llvm::omp::Clause);
265 void CheckCopyingPolymorphicAllocatable(
266 SymbolSourceMap &,
const llvm::omp::Clause);
267 void CheckPrivateSymbolsInOuterCxt(
268 SymbolSourceMap &, DirectivesClauseTriple &,
const llvm::omp::Clause);
271 void CheckIsLoopIvPartOfClause(
273 bool CheckTargetBlockOnlyTeams(
const parser::Block &);
276 void CheckIndividualAllocateDirective(
285 template <
typename T,
typename D>
bool IsOperatorValid(
const T &,
const D &);
291 std::string_view name,
bool checkTypeOnPointer =
true);
300 void CheckAtomicReadAssignment(
302 void CheckAtomicWriteAssignment(
304 std::optional<evaluate::Assignment> CheckAtomicUpdateAssignment(
306 std::pair<bool, bool> CheckAtomicUpdateAssignmentRhs(
const SomeExpr &atom,
308 void CheckAtomicConditionalUpdateAssignment(
const SomeExpr &cond,
311 void CheckAtomicConditionalUpdateStmt(
319 void CheckAtomicConditionalUpdateCapture(
326 void CheckScanModifier(
const parser::OmpClause::Reduction &x);
330 void CheckNestedBlock(
335 void CheckTargetUpdate();
337 void CheckDependenceType(
const parser::OmpDependenceType::Value &x);
338 void CheckTaskDependenceType(
const parser::OmpTaskDependenceType::Value &x);
339 std::optional<llvm::omp::Directive> GetCancelType(
341 const std::optional<parser::OmpClauseList> &maybeClauses);
342 void CheckCancellationNest(
345 void CheckReductionObjects(
354 void ChecksOnOrderedAsBlock();
357 void ChecksOnOrderedAsStandalone();
358 void CheckOrderedDependClause(std::optional<std::int64_t> orderedValue);
359 void CheckReductionArraySection(
362 const parser::Name &name,
const llvm::omp::Clause clause);
363 void CheckSharedBindingInOuterContext(
368 void CheckAllowedRequiresClause(llvmOmpClause clause);
369 bool deviceConstructFound_{
false};
373 void EnterDirectiveNest(
const int index) { directiveNest_[index]++; }
374 void ExitDirectiveNest(
const int index) { directiveNest_[index]--; }
375 int GetDirectiveNest(
const int index) {
return directiveNest_[index]; }
377 inline void ErrIfLHSAndRHSSymbolsMatch(
379 inline void ErrIfNonScalarAssignmentStmt(
381 enum directiveNestType :
int {
383 TargetBlockOnlyTeams,
388 LastType = MetadirectiveNest,
390 int directiveNest_[LastType + 1] = {0};
392 int allocateDirectiveLevel{0};
394 SymbolSourceMap deferredNonVariables_;
398 std::vector<LoopConstruct> loopStack_;
400 std::vector<const Scope *> scopeStack_;
402 enum class PartKind :
int {
408 std::vector<PartKind> partStack_;