66class OmpStructureChecker :
public OmpStructureCheckerBase {
68 using Base = OmpStructureCheckerBase;
82 void Enter(
const parser::EndSubroutineStmt &);
84 void Enter(
const parser::EndFunctionStmt &);
85 void Enter(
const parser::MpSubprogramStmt &);
86 void Enter(
const parser::EndMpSubprogramStmt &);
94 void Enter(
const parser::ExecutionPart &);
95 void Leave(
const parser::ExecutionPart &);
184 void Enter(
const parser::OmpContextSelector &);
185 void Leave(
const parser::OmpContextSelector &);
188 void Leave(
const parser::GotoStmt &);
192 void Leave(
const parser::AltReturnSpec &);
193 void Leave(
const parser::ErrLabel &);
194 void Leave(
const parser::EndLabel &);
195 void Leave(
const parser::EorLabel &);
197#define GEN_FLANG_CLAUSE_CHECK_ENTER
198#include "llvm/Frontend/OpenMP/OMP.inc"
212 std::string_view name,
bool checkTypeOnPointer =
true);
221 void CheckAtomicReadAssignment(
223 void CheckAtomicWriteAssignment(
225 std::optional<evaluate::Assignment> CheckAtomicUpdateAssignment(
227 std::pair<bool, bool> CheckAtomicUpdateAssignmentRhs(
const SomeExpr &atom,
229 void CheckAtomicConditionalUpdateAssignment(
const SomeExpr &cond,
232 void CheckAtomicConditionalUpdateStmt(
240 void CheckAtomicConditionalUpdateCapture(
258 void CheckScanModifier(
const parser::OmpClause::Reduction &x);
262 void CheckOmpDeclareVariantDirective(
264 void CheckDeclareVariantUserConditions(
const parser::OmpContextSelector &);
265 const std::list<parser::OmpTraitProperty> &GetTraitPropertyList(
267 std::optional<llvm::omp::Clause> GetClauseFromProperty(
270 void CheckTraitSelectorList(
const std::list<parser::OmpTraitSelector> &);
271 void CheckContextSelectorSpecification(
const parser::OmpContextSelector &);
274 bool VerifyTraitPropertyLists(
276 void CheckTraitSelector(
280 void CheckTraitCondition(
282 void CheckTraitDeviceNum(
284 void CheckTraitRequires(
290 bool IsAllowedClause(llvm::omp::Clause clauseId);
291 bool CheckAllowedClause(llvm::omp::Clause clause);
293 void CheckDirectiveSpelling(
299 void CheckSourceLabel(
const parser::Label &);
303 void CheckMultipleOccurrence(semantics::UnorderedSymbolSet &listVars,
305 const std::string &clauseName);
306 void CheckMultListItems();
307 void CheckStructureComponent(
309 void CheckStructureComponent(
311 bool HasInvalidWorksharingNesting(
314 bool IsCloselyNestedRegion(
const OmpDirectiveSet &set);
315 bool IsNestedInDirective(llvm::omp::Directive directive);
316 bool IsCombinedParallelWorksharing(llvm::omp::Directive directive)
const;
317 bool InTargetRegion();
318 void HasInvalidTeamsNesting(
320 bool HasRequires(llvm::omp::Clause req);
321 void CheckAllowedMapTypes(
324 llvm::StringRef getClauseName(llvm::omp::Clause clause)
override;
325 llvm::StringRef getDirectiveName(llvm::omp::Directive directive)
override;
328 typename LessTy,
typename RangeTy,
329 typename IterTy =
decltype(std::declval<RangeTy>().begin())>
330 std::optional<IterTy> FindDuplicate(RangeTy &&);
336 void CheckTypeParamInquiry(
338 void CheckTypeParamInquiry(
345 void CheckThreadprivateOrDeclareTargetVar(
const parser::Name &);
348 void CheckSymbolName(
350 void CheckSymbolNames(
352 void CheckIntentInPointer(SymbolSourceMap &,
const llvm::omp::Clause);
353 void CheckProcedurePointer(SymbolSourceMap &,
const llvm::omp::Clause);
355 llvm::StringRef clause,
bool suggestToUseCrayPointer =
true);
357 void CheckDefinableObjects(SymbolSourceMap &,
const llvm::omp::Clause);
358 void CheckCopyingPolymorphicAllocatable(
359 SymbolSourceMap &,
const llvm::omp::Clause);
360 void CheckPrivateSymbolsInOuterCxt(
361 SymbolSourceMap &, DirectivesClauseTriple &,
const llvm::omp::Clause);
362 bool CheckTargetBlockOnlyTeams(
const parser::Block &);
365 void CheckIndividualAllocateDirective(
373 void CheckTargetUpdate();
375 void CheckDependenceType(
const parser::OmpDependenceType::Value &x);
376 void CheckTaskDependenceType(
const parser::OmpTaskDependenceType::Value &x);
377 std::optional<llvm::omp::Directive> GetCancelType(
379 const std::optional<parser::OmpClauseList> &maybeClauses);
380 void CheckCancellationNest(
382 void CheckReductionObjects(
391 void ChecksOnOrderedAsBlock();
394 void ChecksOnOrderedAsStandalone();
395 void CheckOrderedDependClause(std::optional<std::int64_t> orderedValue);
396 void CheckReductionArraySection(
399 const parser::Name &name,
const llvm::omp::Clause clause);
400 void CheckLastPartRefForArraySection(
402 void CheckSharedBindingInOuterContext(
408 void CheckAllowedRequiresClause(llvm::omp::Clause clause);
410 void CheckTempDescriptorMappings();
412 void EnterDirectiveNest(
const int index) { directiveNest_[index]++; }
413 void ExitDirectiveNest(
const int index) { directiveNest_[index]--; }
414 int GetDirectiveNest(
const int index) {
return directiveNest_[index]; }
416 bool deviceConstructFound_{
false};
417 enum directiveNestType :
int {
419 TargetBlockOnlyTeams,
424 LastType = MetadirectiveNest,
426 int directiveNest_[LastType + 1] = {0};
428 std::set<std::pair<const Symbol *, const Symbol *>> declareVariantPairs_;
430 int allocateDirectiveLevel_{0};
436 std::multimap<const Symbol *, parser::CharBlock> tempDescriptorEnterMaps_;
437 std::set<const Symbol *> tempDescriptorExitMaps_;
442 std::vector<LoopOrConstruct> constructStack_;
444 std::vector<const Scope *> scopeStack_;
448 std::vector<const parser::OmpDirectiveSpecification *> dirStack_;
450 enum class PartKind :
int {
456 std::vector<PartKind> partStack_;
458 std::multimap<
const parser::Label,
459 std::pair<parser::CharBlock, const parser::OpenMPConstruct *>>
461 std::map<
const parser::Label,
462 std::pair<parser::CharBlock, const parser::OpenMPConstruct *>>