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(
198 bool IsCloselyNestedRegion(
const OmpDirectiveSet &set);
199 bool IsNestedInDirective(llvm::omp::Directive directive);
200 bool IsCombinedParallelWorksharing(llvm::omp::Directive directive)
const;
201 bool InTargetRegion();
202 void HasInvalidTeamsNesting(
206 bool HasRequires(llvm::omp::Clause req);
208 void CheckAllowedMapTypes(
211 const std::list<parser::OmpTraitProperty> &GetTraitPropertyList(
213 std::optional<llvm::omp::Clause> GetClauseFromProperty(
216 void CheckTraitSelectorList(
const std::list<parser::OmpTraitSelector> &);
219 bool VerifyTraitPropertyLists(
221 void CheckTraitSelector(
225 void CheckTraitCondition(
227 void CheckTraitDeviceNum(
229 void CheckTraitRequires(
234 llvm::StringRef getClauseName(llvm::omp::Clause clause)
override;
235 llvm::StringRef getDirectiveName(llvm::omp::Directive directive)
override;
238 typename LessTy,
typename RangeTy,
239 typename IterTy =
decltype(std::declval<RangeTy>().begin())>
240 std::optional<IterTy> FindDuplicate(RangeTy &&);
243 void CheckDependArraySection(
254 void CheckThreadprivateOrDeclareTargetVar(
const parser::Name &);
257 void CheckSymbolName(
259 void CheckSymbolNames(
261 void CheckIntentInPointer(SymbolSourceMap &,
const llvm::omp::Clause);
262 void CheckProcedurePointer(SymbolSourceMap &,
const llvm::omp::Clause);
264 llvm::StringRef clause,
bool suggestToUseCrayPointer =
true);
266 void CheckDefinableObjects(SymbolSourceMap &,
const llvm::omp::Clause);
267 void CheckCopyingPolymorphicAllocatable(
268 SymbolSourceMap &,
const llvm::omp::Clause);
269 void CheckPrivateSymbolsInOuterCxt(
270 SymbolSourceMap &, DirectivesClauseTriple &,
const llvm::omp::Clause);
273 void CheckIsLoopIvPartOfClause(
275 bool CheckTargetBlockOnlyTeams(
const parser::Block &);
278 void CheckIndividualAllocateDirective(
287 template <
typename T,
typename D>
bool IsOperatorValid(
const T &,
const D &);
293 std::string_view name,
bool checkTypeOnPointer =
true);
302 void CheckAtomicReadAssignment(
304 void CheckAtomicWriteAssignment(
306 std::optional<evaluate::Assignment> CheckAtomicUpdateAssignment(
308 std::pair<bool, bool> CheckAtomicUpdateAssignmentRhs(
const SomeExpr &atom,
310 void CheckAtomicConditionalUpdateAssignment(
const SomeExpr &cond,
313 void CheckAtomicConditionalUpdateStmt(
321 void CheckAtomicConditionalUpdateCapture(
328 void CheckScanModifier(
const parser::OmpClause::Reduction &x);
334 void CheckTargetUpdate();
336 void CheckDependenceType(
const parser::OmpDependenceType::Value &x);
337 void CheckTaskDependenceType(
const parser::OmpTaskDependenceType::Value &x);
338 std::optional<llvm::omp::Directive> GetCancelType(
340 const std::optional<parser::OmpClauseList> &maybeClauses);
341 void CheckCancellationNest(
344 void CheckReductionObjects(
353 void ChecksOnOrderedAsBlock();
356 void ChecksOnOrderedAsStandalone();
357 void CheckOrderedDependClause(std::optional<std::int64_t> orderedValue);
358 void CheckReductionArraySection(
361 const parser::Name &name,
const llvm::omp::Clause clause);
362 void CheckSharedBindingInOuterContext(
369 void CheckAllowedRequiresClause(llvmOmpClause clause);
370 bool deviceConstructFound_{
false};
374 void EnterDirectiveNest(
const int index) { directiveNest_[index]++; }
375 void ExitDirectiveNest(
const int index) { directiveNest_[index]--; }
376 int GetDirectiveNest(
const int index) {
return directiveNest_[index]; }
378 inline void ErrIfLHSAndRHSSymbolsMatch(
380 inline void ErrIfNonScalarAssignmentStmt(
382 enum directiveNestType :
int {
384 TargetBlockOnlyTeams,
389 LastType = MetadirectiveNest,
391 int directiveNest_[LastType + 1] = {0};
393 int allocateDirectiveLevel{0};
395 SymbolSourceMap deferredNonVariables_;
399 std::vector<LoopConstruct> loopStack_;
401 std::vector<const Scope *> scopeStack_;
403 enum class PartKind :
int {
409 std::vector<PartKind> partStack_;