55class OmpStructureChecker :
public OmpStructureCheckerBase {
57 using Base = OmpStructureCheckerBase;
71 void Enter(
const parser::EndSubroutineStmt &);
73 void Enter(
const parser::EndFunctionStmt &);
74 void Enter(
const parser::MpSubprogramStmt &);
75 void Enter(
const parser::EndMpSubprogramStmt &);
83 void Enter(
const parser::ExecutionPart &);
84 void Leave(
const parser::ExecutionPart &);
173 void Enter(
const parser::OmpContextSelector &);
174 void Leave(
const parser::OmpContextSelector &);
177 void Leave(
const parser::GotoStmt &);
181 void Leave(
const parser::AltReturnSpec &);
182 void Leave(
const parser::ErrLabel &);
183 void Leave(
const parser::EndLabel &);
184 void Leave(
const parser::EorLabel &);
186#define GEN_FLANG_CLAUSE_CHECK_ENTER
187#include "llvm/Frontend/OpenMP/OMP.inc"
201 std::string_view name,
bool checkTypeOnPointer =
true);
210 void CheckAtomicReadAssignment(
212 void CheckAtomicWriteAssignment(
214 std::optional<evaluate::Assignment> CheckAtomicUpdateAssignment(
216 std::pair<bool, bool> CheckAtomicUpdateAssignmentRhs(
const SomeExpr &atom,
218 void CheckAtomicConditionalUpdateAssignment(
const SomeExpr &cond,
221 void CheckAtomicConditionalUpdateStmt(
229 void CheckAtomicConditionalUpdateCapture(
247 void CheckScanModifier(
const parser::OmpClause::Reduction &x);
251 void CheckOmpDeclareVariantDirective(
253 void CheckDeclareVariantUserConditions(
const parser::OmpContextSelector &);
254 const std::list<parser::OmpTraitProperty> &GetTraitPropertyList(
256 std::optional<llvm::omp::Clause> GetClauseFromProperty(
259 void CheckTraitSelectorList(
const std::list<parser::OmpTraitSelector> &);
260 void CheckContextSelectorSpecification(
const parser::OmpContextSelector &);
263 bool VerifyTraitPropertyLists(
265 void CheckTraitSelector(
269 void CheckTraitCondition(
271 void CheckTraitDeviceNum(
273 void CheckTraitRequires(
279 bool IsAllowedClause(llvm::omp::Clause clauseId);
280 bool CheckAllowedClause(llvm::omp::Clause clause);
282 void CheckDirectiveSpelling(
288 void CheckSourceLabel(
const parser::Label &);
292 void CheckMultipleOccurrence(semantics::UnorderedSymbolSet &listVars,
294 const std::string &clauseName);
295 void CheckMultListItems();
296 void CheckStructureComponent(
298 void CheckStructureComponent(
300 bool HasInvalidWorksharingNesting(
303 bool IsCloselyNestedRegion(
const OmpDirectiveSet &set);
304 bool IsNestedInDirective(llvm::omp::Directive directive);
305 bool IsCombinedParallelWorksharing(llvm::omp::Directive directive)
const;
306 bool InTargetRegion();
307 void HasInvalidTeamsNesting(
309 bool HasRequires(llvm::omp::Clause req);
310 void CheckAllowedMapTypes(
313 llvm::StringRef getClauseName(llvm::omp::Clause clause)
override;
314 llvm::StringRef getDirectiveName(llvm::omp::Directive directive)
override;
317 typename LessTy,
typename RangeTy,
318 typename IterTy =
decltype(std::declval<RangeTy>().begin())>
319 std::optional<IterTy> FindDuplicate(RangeTy &&);
334 void CheckThreadprivateOrDeclareTargetVar(
const parser::Name &);
337 void CheckIntentInPointer(SymbolSourceMap &,
const llvm::omp::Clause);
338 void CheckProcedurePointer(SymbolSourceMap &,
const llvm::omp::Clause);
340 llvm::StringRef clause,
bool suggestToUseCrayPointer =
true);
342 void CheckDefinableObjects(SymbolSourceMap &,
const llvm::omp::Clause);
343 void CheckCopyingPolymorphicAllocatable(
344 SymbolSourceMap &,
const llvm::omp::Clause);
345 void CheckPrivateSymbolsInOuterCxt(
346 SymbolSourceMap &, DirectivesClauseTriple &,
const llvm::omp::Clause);
347 bool CheckTargetBlockOnlyTeams(
const parser::Block &);
350 void CheckIndividualAllocateDirective(
358 void CheckTargetUpdate();
360 void CheckDependenceType(
const parser::OmpDependenceType::Value &x);
361 void CheckTaskDependenceType(
const parser::OmpTaskDependenceType::Value &x);
362 std::optional<llvm::omp::Directive> GetCancelType(
364 const std::optional<parser::OmpClauseList> &maybeClauses);
365 void CheckCancellationNest(
367 void CheckReductionObjects(
376 void ChecksOnOrderedAsBlock();
379 void ChecksOnOrderedAsStandalone();
380 void CheckOrderedDependClause(std::optional<std::int64_t> orderedValue);
381 void CheckReductionArraySection(
384 const parser::Name &name,
const llvm::omp::Clause clause);
385 void CheckLastPartRefForArraySection(
387 void CheckSharedBindingInOuterContext(
393 void CheckAllowedRequiresClause(llvm::omp::Clause clause);
396 void EnterDirectiveNest(
const int index) { directiveNest_[index]++; }
397 void ExitDirectiveNest(
const int index) { directiveNest_[index]--; }
398 int GetDirectiveNest(
const int index) {
return directiveNest_[index]; }
400 bool deviceConstructFound_{
false};
401 enum directiveNestType :
int {
403 TargetBlockOnlyTeams,
408 LastType = MetadirectiveNest,
410 int directiveNest_[LastType + 1] = {0};
412 std::set<std::pair<const Symbol *, const Symbol *>> declareVariantPairs_;
414 int allocateDirectiveLevel_{0};
420 std::vector<LoopOrConstruct> constructStack_;
422 std::vector<const Scope *> scopeStack_;
426 std::vector<const parser::OmpDirectiveSpecification *> dirStack_;
428 enum class PartKind :
int {
434 std::vector<PartKind> partStack_;
436 std::multimap<
const parser::Label,
437 std::pair<parser::CharBlock, const parser::OpenMPConstruct *>>
439 std::map<
const parser::Label,
440 std::pair<parser::CharBlock, const parser::OpenMPConstruct *>>