66class OmpStructureChecker :
public OmpStructureCheckerBase {
68 using Base = OmpStructureCheckerBase;
72 using llvmOmpClause =
const llvm::omp::Clause;
83 bool Enter(
const parser::EndSubroutineStmt &);
85 bool Enter(
const parser::EndFunctionStmt &);
91 void Enter(
const parser::ExecutionPart &);
92 void Leave(
const parser::ExecutionPart &);
180 void Enter(
const parser::OmpContextSelector &);
181 void Leave(
const parser::OmpContextSelector &);
183#define GEN_FLANG_CLAUSE_CHECK_ENTER
184#include "llvm/Frontend/OpenMP/OMP.inc"
195 std::string_view name,
bool checkTypeOnPointer =
true);
204 void CheckAtomicReadAssignment(
206 void CheckAtomicWriteAssignment(
208 std::optional<evaluate::Assignment> CheckAtomicUpdateAssignment(
210 std::pair<bool, bool> CheckAtomicUpdateAssignmentRhs(
const SomeExpr &atom,
212 void CheckAtomicConditionalUpdateAssignment(
const SomeExpr &cond,
215 void CheckAtomicConditionalUpdateStmt(
223 void CheckAtomicConditionalUpdateCapture(
242 void CheckScanModifier(
const parser::OmpClause::Reduction &x);
246 const std::list<parser::OmpTraitProperty> &GetTraitPropertyList(
248 std::optional<llvm::omp::Clause> GetClauseFromProperty(
251 void CheckTraitSelectorList(
const std::list<parser::OmpTraitSelector> &);
254 bool VerifyTraitPropertyLists(
256 void CheckTraitSelector(
260 void CheckTraitCondition(
262 void CheckTraitDeviceNum(
264 void CheckTraitRequires(
270 bool IsAllowedClause(llvm::omp::Clause clauseId);
271 bool CheckAllowedClause(llvmOmpClause clause);
272 void CheckVariableListItem(
const SymbolSourceMap &symbols);
273 void CheckDirectiveSpelling(
277 void CheckMultipleOccurrence(semantics::UnorderedSymbolSet &listVars,
279 const std::string &clauseName);
280 void CheckMultListItems();
281 void CheckStructureComponent(
283 bool HasInvalidWorksharingNesting(
286 bool IsCloselyNestedRegion(
const OmpDirectiveSet &set);
287 bool IsNestedInDirective(llvm::omp::Directive directive);
288 bool IsCombinedParallelWorksharing(llvm::omp::Directive directive)
const;
289 bool InTargetRegion();
290 void HasInvalidTeamsNesting(
292 bool HasRequires(llvm::omp::Clause req);
293 void CheckAllowedMapTypes(
296 llvm::StringRef getClauseName(llvm::omp::Clause clause)
override;
297 llvm::StringRef getDirectiveName(llvm::omp::Directive directive)
override;
300 typename LessTy,
typename RangeTy,
301 typename IterTy =
decltype(std::declval<RangeTy>().begin())>
302 std::optional<IterTy> FindDuplicate(RangeTy &&);
314 void CheckThreadprivateOrDeclareTargetVar(
const parser::Name &);
317 void CheckSymbolName(
319 void CheckSymbolNames(
321 void CheckIntentInPointer(SymbolSourceMap &,
const llvm::omp::Clause);
322 void CheckAssumedSizeArray(SymbolSourceMap &,
const llvm::omp::Clause);
323 void CheckProcedurePointer(SymbolSourceMap &,
const llvm::omp::Clause);
325 llvm::StringRef clause,
bool suggestToUseCrayPointer =
true);
327 void CheckDefinableObjects(SymbolSourceMap &,
const llvm::omp::Clause);
328 void CheckCopyingPolymorphicAllocatable(
329 SymbolSourceMap &,
const llvm::omp::Clause);
330 void CheckPrivateSymbolsInOuterCxt(
331 SymbolSourceMap &, DirectivesClauseTriple &,
const llvm::omp::Clause);
332 void CheckIsLoopIvPartOfClause(
334 bool CheckTargetBlockOnlyTeams(
const parser::Block &);
337 void CheckIndividualAllocateDirective(
345 void CheckTargetUpdate();
347 void CheckDependenceType(
const parser::OmpDependenceType::Value &x);
348 void CheckTaskDependenceType(
const parser::OmpTaskDependenceType::Value &x);
349 std::optional<llvm::omp::Directive> GetCancelType(
351 const std::optional<parser::OmpClauseList> &maybeClauses);
352 void CheckCancellationNest(
354 void CheckReductionObjects(
363 void ChecksOnOrderedAsBlock();
366 void ChecksOnOrderedAsStandalone();
367 void CheckOrderedDependClause(std::optional<std::int64_t> orderedValue);
368 void CheckReductionArraySection(
371 const parser::Name &name,
const llvm::omp::Clause clause);
372 void CheckLastPartRefForArraySection(
374 void CheckSharedBindingInOuterContext(
380 void CheckAllowedRequiresClause(llvmOmpClause clause);
383 void EnterDirectiveNest(
const int index) { directiveNest_[index]++; }
384 void ExitDirectiveNest(
const int index) { directiveNest_[index]--; }
385 int GetDirectiveNest(
const int index) {
return directiveNest_[index]; }
387 bool deviceConstructFound_{
false};
388 enum directiveNestType :
int {
390 TargetBlockOnlyTeams,
395 LastType = MetadirectiveNest,
397 int directiveNest_[LastType + 1] = {0};
399 int allocateDirectiveLevel_{0};
401 SymbolSourceMap deferredNonVariables_;
405 std::vector<LoopConstruct> loopStack_;
407 std::vector<const Scope *> scopeStack_;
411 std::vector<const parser::OmpDirectiveSpecification *> dirStack_;
413 enum class PartKind :
int {
419 std::vector<PartKind> partStack_;