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 &);
171 void Enter(
const parser::OmpContextSelector &);
172 void Leave(
const parser::OmpContextSelector &);
174#define GEN_FLANG_CLAUSE_CHECK_ENTER
175#include "llvm/Frontend/OpenMP/OMP.inc"
178 bool CheckAllowedClause(llvmOmpClause clause);
179 void CheckVariableListItem(
const SymbolSourceMap &symbols);
180 void CheckDirectiveSpelling(
184 void CheckMultipleOccurrence(semantics::UnorderedSymbolSet &listVars,
186 const std::string &clauseName);
187 void CheckMultListItems();
188 void CheckStructureComponent(
190 bool HasInvalidWorksharingNesting(
192 bool IsCloselyNestedRegion(
const OmpDirectiveSet &set);
193 bool IsNestedInDirective(llvm::omp::Directive directive);
194 bool InTargetRegion();
195 void HasInvalidTeamsNesting(
199 bool HasRequires(llvm::omp::Clause req);
201 void CheckAllowedMapTypes(
204 const std::list<parser::OmpTraitProperty> &GetTraitPropertyList(
206 std::optional<llvm::omp::Clause> GetClauseFromProperty(
209 void CheckTraitSelectorList(
const std::list<parser::OmpTraitSelector> &);
212 bool VerifyTraitPropertyLists(
214 void CheckTraitSelector(
218 void CheckTraitCondition(
220 void CheckTraitDeviceNum(
222 void CheckTraitRequires(
227 llvm::StringRef getClauseName(llvm::omp::Clause clause)
override;
228 llvm::StringRef getDirectiveName(llvm::omp::Directive directive)
override;
231 typename LessTy,
typename RangeTy,
232 typename IterTy =
decltype(std::declval<RangeTy>().begin())>
233 std::optional<IterTy> FindDuplicate(RangeTy &&);
236 void CheckDependArraySection(
245 void CheckThreadprivateOrDeclareTargetVar(
const parser::Name &);
248 void CheckSymbolName(
250 void CheckSymbolNames(
252 void CheckIntentInPointer(SymbolSourceMap &,
const llvm::omp::Clause);
253 void CheckProcedurePointer(SymbolSourceMap &,
const llvm::omp::Clause);
255 llvm::StringRef clause,
bool suggestToUseCrayPointer =
true);
257 void CheckDefinableObjects(SymbolSourceMap &,
const llvm::omp::Clause);
258 void CheckCopyingPolymorphicAllocatable(
259 SymbolSourceMap &,
const llvm::omp::Clause);
260 void CheckPrivateSymbolsInOuterCxt(
261 SymbolSourceMap &, DirectivesClauseTriple &,
const llvm::omp::Clause);
264 void CheckIsLoopIvPartOfClause(
266 bool CheckTargetBlockOnlyTeams(
const parser::Block &);
269 void CheckIndividualAllocateDirective(
278 template <
typename T,
typename D>
bool IsOperatorValid(
const T &,
const D &);
284 std::string_view name,
bool checkTypeOnPointer =
true);
293 void CheckAtomicReadAssignment(
295 void CheckAtomicWriteAssignment(
297 std::optional<evaluate::Assignment> CheckAtomicUpdateAssignment(
299 std::pair<bool, bool> CheckAtomicUpdateAssignmentRhs(
const SomeExpr &atom,
301 void CheckAtomicConditionalUpdateAssignment(
const SomeExpr &cond,
304 void CheckAtomicConditionalUpdateStmt(
312 void CheckAtomicConditionalUpdateCapture(
322 void CheckTargetUpdate();
324 void CheckDependenceType(
const parser::OmpDependenceType::Value &x);
325 void CheckTaskDependenceType(
const parser::OmpTaskDependenceType::Value &x);
326 std::optional<llvm::omp::Directive> GetCancelType(
328 const std::optional<parser::OmpClauseList> &maybeClauses);
329 void CheckCancellationNest(
332 void CheckReductionObjects(
341 void ChecksOnOrderedAsBlock();
344 void ChecksOnOrderedAsStandalone();
345 void CheckOrderedDependClause(std::optional<std::int64_t> orderedValue);
346 void CheckReductionArraySection(
349 const parser::Name &name,
const llvm::omp::Clause clause);
350 void CheckSharedBindingInOuterContext(
355 void CheckAllowedRequiresClause(llvmOmpClause clause);
356 bool deviceConstructFound_{
false};
360 void EnterDirectiveNest(
const int index) { directiveNest_[index]++; }
361 void ExitDirectiveNest(
const int index) { directiveNest_[index]--; }
362 int GetDirectiveNest(
const int index) {
return directiveNest_[index]; }
364 inline void ErrIfLHSAndRHSSymbolsMatch(
366 inline void ErrIfNonScalarAssignmentStmt(
368 enum directiveNestType :
int {
370 TargetBlockOnlyTeams,
375 LastType = MetadirectiveNest,
377 int directiveNest_[LastType + 1] = {0};
379 int allocateDirectiveLevel{0};
381 SymbolSourceMap deferredNonVariables_;
385 std::vector<LoopConstruct> loopStack_;
387 std::vector<const Scope *> scopeStack_;
389 enum class PartKind :
int {
395 std::vector<PartKind> partStack_;