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 &);
93 void Enter(
const parser::ExecutionPart &);
94 void Leave(
const parser::ExecutionPart &);
180 void Enter(
const parser::OmpContextSelector &);
181 void Leave(
const parser::OmpContextSelector &);
184 void Leave(
const parser::GotoStmt &);
188 void Leave(
const parser::AltReturnSpec &);
189 void Leave(
const parser::ErrLabel &);
190 void Leave(
const parser::EndLabel &);
191 void Leave(
const parser::EorLabel &);
193#define GEN_FLANG_CLAUSE_CHECK_ENTER
194#include "llvm/Frontend/OpenMP/OMP.inc"
208 std::string_view name,
bool checkTypeOnPointer =
true);
217 void CheckAtomicReadAssignment(
219 void CheckAtomicWriteAssignment(
221 std::optional<evaluate::Assignment> CheckAtomicUpdateAssignment(
223 std::pair<bool, bool> CheckAtomicUpdateAssignmentRhs(
const SomeExpr &atom,
225 void CheckAtomicConditionalUpdateAssignment(
const SomeExpr &cond,
228 void CheckAtomicConditionalUpdateStmt(
236 void CheckAtomicConditionalUpdateCapture(
255 void CheckScanModifier(
const parser::OmpClause::Reduction &x);
259 const std::list<parser::OmpTraitProperty> &GetTraitPropertyList(
261 std::optional<llvm::omp::Clause> GetClauseFromProperty(
264 void CheckTraitSelectorList(
const std::list<parser::OmpTraitSelector> &);
267 bool VerifyTraitPropertyLists(
269 void CheckTraitSelector(
273 void CheckTraitCondition(
275 void CheckTraitDeviceNum(
277 void CheckTraitRequires(
283 bool IsAllowedClause(llvm::omp::Clause clauseId);
284 bool CheckAllowedClause(llvmOmpClause clause);
285 void CheckVariableListItem(
const SymbolSourceMap &symbols);
286 void CheckDirectiveSpelling(
293 void CheckSourceLabel(
const parser::Label &);
297 void CheckMultipleOccurrence(semantics::UnorderedSymbolSet &listVars,
299 const std::string &clauseName);
300 void CheckMultListItems();
301 void CheckStructureComponent(
303 bool HasInvalidWorksharingNesting(
306 bool IsCloselyNestedRegion(
const OmpDirectiveSet &set);
307 bool IsNestedInDirective(llvm::omp::Directive directive);
308 bool IsCombinedParallelWorksharing(llvm::omp::Directive directive)
const;
309 bool InTargetRegion();
310 void HasInvalidTeamsNesting(
312 bool HasRequires(llvm::omp::Clause req);
313 void CheckAllowedMapTypes(
316 llvm::StringRef getClauseName(llvm::omp::Clause clause)
override;
317 llvm::StringRef getDirectiveName(llvm::omp::Directive directive)
override;
320 typename LessTy,
typename RangeTy,
321 typename IterTy =
decltype(std::declval<RangeTy>().begin())>
322 std::optional<IterTy> FindDuplicate(RangeTy &&);
334 void CheckThreadprivateOrDeclareTargetVar(
const parser::Name &);
337 void CheckSymbolName(
339 void CheckSymbolNames(
341 void CheckIntentInPointer(SymbolSourceMap &,
const llvm::omp::Clause);
342 void CheckAssumedSizeArray(SymbolSourceMap &,
const llvm::omp::Clause);
343 void CheckProcedurePointer(SymbolSourceMap &,
const llvm::omp::Clause);
345 llvm::StringRef clause,
bool suggestToUseCrayPointer =
true);
347 void CheckDefinableObjects(SymbolSourceMap &,
const llvm::omp::Clause);
348 void CheckCopyingPolymorphicAllocatable(
349 SymbolSourceMap &,
const llvm::omp::Clause);
350 void CheckPrivateSymbolsInOuterCxt(
351 SymbolSourceMap &, DirectivesClauseTriple &,
const llvm::omp::Clause);
352 void CheckIsLoopIvPartOfClause(
354 bool CheckTargetBlockOnlyTeams(
const parser::Block &);
357 void CheckIndividualAllocateDirective(
365 void CheckTargetUpdate();
367 void CheckDependenceType(
const parser::OmpDependenceType::Value &x);
368 void CheckTaskDependenceType(
const parser::OmpTaskDependenceType::Value &x);
369 std::optional<llvm::omp::Directive> GetCancelType(
371 const std::optional<parser::OmpClauseList> &maybeClauses);
372 void CheckCancellationNest(
374 void CheckReductionObjects(
383 void ChecksOnOrderedAsBlock();
386 void ChecksOnOrderedAsStandalone();
387 void CheckOrderedDependClause(std::optional<std::int64_t> orderedValue);
388 void CheckReductionArraySection(
391 const parser::Name &name,
const llvm::omp::Clause clause);
392 void CheckLastPartRefForArraySection(
394 void CheckSharedBindingInOuterContext(
400 void CheckAllowedRequiresClause(llvmOmpClause clause);
403 void EnterDirectiveNest(
const int index) { directiveNest_[index]++; }
404 void ExitDirectiveNest(
const int index) { directiveNest_[index]--; }
405 int GetDirectiveNest(
const int index) {
return directiveNest_[index]; }
407 bool deviceConstructFound_{
false};
408 enum directiveNestType :
int {
410 TargetBlockOnlyTeams,
415 LastType = MetadirectiveNest,
417 int directiveNest_[LastType + 1] = {0};
419 int allocateDirectiveLevel_{0};
421 SymbolSourceMap deferredNonVariables_;
426 std::vector<LoopOrConstruct> constructStack_;
428 std::vector<const Scope *> scopeStack_;
432 std::vector<const parser::OmpDirectiveSpecification *> dirStack_;
434 enum class PartKind :
int {
440 std::vector<PartKind> partStack_;
442 std::multimap<
const parser::Label,
443 std::pair<parser::CharBlock, const parser::OpenMPConstruct *>>
445 std::map<
const parser::Label,
446 std::pair<parser::CharBlock, const parser::OpenMPConstruct *>>