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 &);
146 void Enter(
const parser::OmpContextSelector &);
147 void Leave(
const parser::OmpContextSelector &);
150 void Leave(
const parser::GotoStmt &);
154 void Leave(
const parser::AltReturnSpec &);
155 void Leave(
const parser::ErrLabel &);
156 void Leave(
const parser::EndLabel &);
157 void Leave(
const parser::EorLabel &);
159#define GEN_FLANG_CLAUSE_CHECK_ENTER
160#include "llvm/Frontend/OpenMP/OMP.inc"
174 std::string_view name,
bool checkTypeOnPointer =
true);
183 void CheckAtomicReadAssignment(
185 void CheckAtomicWriteAssignment(
187 std::optional<evaluate::Assignment> CheckAtomicUpdateAssignment(
189 std::pair<bool, bool> CheckAtomicUpdateAssignmentRhs(
const SomeExpr &atom,
191 void CheckAtomicConditionalUpdateAssignment(
const SomeExpr &cond,
194 void CheckAtomicConditionalUpdateStmt(
202 void CheckAtomicConditionalUpdateCapture(
220 void CheckScanModifier(
const parser::OmpClause::Reduction &x);
224 void CheckOmpDeclareVariantDirective(
226 void CheckDeclareVariantUserConditions(
const parser::OmpContextSelector &);
227 const std::list<parser::OmpTraitProperty> &GetTraitPropertyList(
229 std::optional<llvm::omp::Clause> GetClauseFromProperty(
232 void CheckTraitSelectorList(
const std::list<parser::OmpTraitSelector> &);
233 void CheckContextSelectorSpecification(
const parser::OmpContextSelector &);
236 bool VerifyTraitPropertyLists(
238 void CheckTraitSelector(
242 void CheckTraitCondition(
244 void CheckTraitDeviceNum(
246 void CheckTraitRequires(
252 bool IsAllowedClause(llvm::omp::Clause clauseId);
253 bool CheckAllowedClause(llvm::omp::Clause clause);
255 void CheckDirectiveSpelling(
261 void CheckSourceLabel(
const parser::Label &);
265 void CheckMultipleOccurrence(semantics::UnorderedSymbolSet &listVars,
267 const std::string &clauseName);
268 void CheckMultListItems();
269 void CheckStructureComponent(
271 void CheckStructureComponent(
273 bool HasInvalidWorksharingNesting(
276 bool IsCloselyNestedRegion(
const OmpDirectiveSet &set);
277 bool IsNestedInDirective(llvm::omp::Directive directive);
278 bool IsCombinedParallelWorksharing(llvm::omp::Directive directive)
const;
279 bool InTargetRegion();
280 void HasInvalidTeamsNesting(
282 bool HasRequires(llvm::omp::Clause req);
283 void CheckAllowedMapTypes(
286 llvm::StringRef getClauseName(llvm::omp::Clause clause)
override;
287 llvm::StringRef getDirectiveName(llvm::omp::Directive directive)
override;
290 typename LessTy,
typename RangeTy,
291 typename IterTy =
decltype(std::declval<RangeTy>().begin())>
292 std::optional<IterTy> FindDuplicate(RangeTy &&);
307 void CheckThreadprivateOrDeclareTargetVar(
const parser::Name &);
310 void CheckIntentInPointer(SymbolSourceMap &,
const llvm::omp::Clause);
311 void CheckProcedurePointer(SymbolSourceMap &,
const llvm::omp::Clause);
313 llvm::StringRef clause,
bool suggestToUseCrayPointer =
true);
315 void CheckDefinableObjects(SymbolSourceMap &,
const llvm::omp::Clause);
316 void CheckCopyingPolymorphicAllocatable(
317 SymbolSourceMap &,
const llvm::omp::Clause);
318 void CheckPrivateSymbolsInOuterCxt(
319 SymbolSourceMap &, DirectivesClauseTriple &,
const llvm::omp::Clause);
320 bool CheckTargetBlockOnlyTeams(
const parser::Block &);
323 void CheckIndividualAllocateDirective(
331 void CheckTargetUpdate();
333 void CheckDependenceType(
const parser::OmpDependenceType::Value &x);
334 void CheckTaskDependenceType(
const parser::OmpTaskDependenceType::Value &x);
335 std::optional<llvm::omp::Directive> GetCancelType(
337 const std::optional<parser::OmpClauseList> &maybeClauses);
338 void CheckCancellationNest(
340 void CheckReductionObjects(
350 void ChecksOnOrderedAsBlock();
353 void ChecksOnOrderedAsStandalone();
354 void CheckOrderedDependClause(std::optional<std::int64_t> orderedValue);
355 void CheckReductionArraySection(
358 const parser::Name &name,
const llvm::omp::Clause clause);
359 void CheckLastPartRefForArraySection(
361 void CheckSharedBindingInOuterContext(
367 void CheckAllowedRequiresClause(llvm::omp::Clause clause);
370 void EnterDirectiveNest(
const int index) { directiveNest_[index]++; }
371 void ExitDirectiveNest(
const int index) { directiveNest_[index]--; }
372 int GetDirectiveNest(
const int index) {
return directiveNest_[index]; }
374 bool deviceConstructFound_{
false};
375 enum directiveNestType :
int {
377 TargetBlockOnlyTeams,
382 LastType = MetadirectiveNest,
384 int directiveNest_[LastType + 1] = {0};
386 std::set<std::pair<const Symbol *, const Symbol *>> declareVariantPairs_;
388 int allocateDirectiveLevel_{0};
394 std::vector<LoopOrConstruct> constructStack_;
396 std::vector<const Scope *> scopeStack_;
400 std::vector<const parser::OmpDirectiveSpecification *> dirStack_;
402 enum class PartKind :
int {
408 std::vector<PartKind> partStack_;
410 std::multimap<
const parser::Label,
411 std::pair<parser::CharBlock, const parser::OpenMPConstruct *>>
413 std::map<
const parser::Label,
414 std::pair<parser::CharBlock, const parser::OpenMPConstruct *>>