66class OmpStructureChecker :
public OmpStructureCheckerBase {
68 using Base = OmpStructureCheckerBase;
82 bool Enter(
const parser::EndSubroutineStmt &);
84 bool Enter(
const parser::EndFunctionStmt &);
92 void Enter(
const parser::ExecutionPart &);
93 void Leave(
const parser::ExecutionPart &);
179 void Enter(
const parser::OmpContextSelector &);
180 void Leave(
const parser::OmpContextSelector &);
183 void Leave(
const parser::GotoStmt &);
187 void Leave(
const parser::AltReturnSpec &);
188 void Leave(
const parser::ErrLabel &);
189 void Leave(
const parser::EndLabel &);
190 void Leave(
const parser::EorLabel &);
192#define GEN_FLANG_CLAUSE_CHECK_ENTER
193#include "llvm/Frontend/OpenMP/OMP.inc"
207 std::string_view name,
bool checkTypeOnPointer =
true);
216 void CheckAtomicReadAssignment(
218 void CheckAtomicWriteAssignment(
220 std::optional<evaluate::Assignment> CheckAtomicUpdateAssignment(
222 std::pair<bool, bool> CheckAtomicUpdateAssignmentRhs(
const SomeExpr &atom,
224 void CheckAtomicConditionalUpdateAssignment(
const SomeExpr &cond,
227 void CheckAtomicConditionalUpdateStmt(
235 void CheckAtomicConditionalUpdateCapture(
254 void CheckScanModifier(
const parser::OmpClause::Reduction &x);
258 const std::list<parser::OmpTraitProperty> &GetTraitPropertyList(
260 std::optional<llvm::omp::Clause> GetClauseFromProperty(
263 void CheckTraitSelectorList(
const std::list<parser::OmpTraitSelector> &);
266 bool VerifyTraitPropertyLists(
268 void CheckTraitSelector(
272 void CheckTraitCondition(
274 void CheckTraitDeviceNum(
276 void CheckTraitRequires(
282 bool IsAllowedClause(llvm::omp::Clause clauseId);
283 bool CheckAllowedClause(llvm::omp::Clause clause);
284 void CheckVariableListItem(
const SymbolSourceMap &symbols);
285 void CheckDirectiveSpelling(
292 void CheckSourceLabel(
const parser::Label &);
296 void CheckMultipleOccurrence(semantics::UnorderedSymbolSet &listVars,
298 const std::string &clauseName);
299 void CheckMultListItems();
300 void CheckStructureComponent(
302 bool HasInvalidWorksharingNesting(
305 bool IsCloselyNestedRegion(
const OmpDirectiveSet &set);
306 bool IsNestedInDirective(llvm::omp::Directive directive);
307 bool IsCombinedParallelWorksharing(llvm::omp::Directive directive)
const;
308 bool InTargetRegion();
309 void HasInvalidTeamsNesting(
311 bool HasRequires(llvm::omp::Clause req);
312 void CheckAllowedMapTypes(
315 llvm::StringRef getClauseName(llvm::omp::Clause clause)
override;
316 llvm::StringRef getDirectiveName(llvm::omp::Directive directive)
override;
319 typename LessTy,
typename RangeTy,
320 typename IterTy =
decltype(std::declval<RangeTy>().begin())>
321 std::optional<IterTy> FindDuplicate(RangeTy &&);
333 void CheckThreadprivateOrDeclareTargetVar(
const parser::Name &);
336 void CheckSymbolName(
338 void CheckSymbolNames(
340 void CheckIntentInPointer(SymbolSourceMap &,
const llvm::omp::Clause);
341 void CheckAssumedSizeArray(SymbolSourceMap &,
const llvm::omp::Clause);
342 void CheckProcedurePointer(SymbolSourceMap &,
const llvm::omp::Clause);
344 llvm::StringRef clause,
bool suggestToUseCrayPointer =
true);
346 void CheckDefinableObjects(SymbolSourceMap &,
const llvm::omp::Clause);
347 void CheckCopyingPolymorphicAllocatable(
348 SymbolSourceMap &,
const llvm::omp::Clause);
349 void CheckPrivateSymbolsInOuterCxt(
350 SymbolSourceMap &, DirectivesClauseTriple &,
const llvm::omp::Clause);
351 void CheckIsLoopIvPartOfClause(
353 bool CheckTargetBlockOnlyTeams(
const parser::Block &);
356 void CheckIndividualAllocateDirective(
364 void CheckTargetUpdate();
366 void CheckDependenceType(
const parser::OmpDependenceType::Value &x);
367 void CheckTaskDependenceType(
const parser::OmpTaskDependenceType::Value &x);
368 std::optional<llvm::omp::Directive> GetCancelType(
370 const std::optional<parser::OmpClauseList> &maybeClauses);
371 void CheckCancellationNest(
373 void CheckReductionObjects(
382 void ChecksOnOrderedAsBlock();
385 void ChecksOnOrderedAsStandalone();
386 void CheckOrderedDependClause(std::optional<std::int64_t> orderedValue);
387 void CheckReductionArraySection(
390 const parser::Name &name,
const llvm::omp::Clause clause);
391 void CheckLastPartRefForArraySection(
393 void CheckSharedBindingInOuterContext(
399 void CheckAllowedRequiresClause(llvm::omp::Clause clause);
402 void EnterDirectiveNest(
const int index) { directiveNest_[index]++; }
403 void ExitDirectiveNest(
const int index) { directiveNest_[index]--; }
404 int GetDirectiveNest(
const int index) {
return directiveNest_[index]; }
406 bool deviceConstructFound_{
false};
407 enum directiveNestType :
int {
409 TargetBlockOnlyTeams,
414 LastType = MetadirectiveNest,
416 int directiveNest_[LastType + 1] = {0};
418 int allocateDirectiveLevel_{0};
420 SymbolSourceMap deferredNonVariables_;
425 std::vector<LoopOrConstruct> constructStack_;
427 std::vector<const Scope *> scopeStack_;
431 std::vector<const parser::OmpDirectiveSpecification *> dirStack_;
433 enum class PartKind :
int {
439 std::vector<PartKind> partStack_;
441 std::multimap<
const parser::Label,
442 std::pair<parser::CharBlock, const parser::OpenMPConstruct *>>
444 std::map<
const parser::Label,
445 std::pair<parser::CharBlock, const parser::OpenMPConstruct *>>