62class OmpStructureChecker :
public OmpStructureCheckerBase {
64 using Base = OmpStructureCheckerBase;
68 using llvmOmpClause =
const llvm::omp::Clause;
79 bool Enter(
const parser::EndSubroutineStmt &);
81 bool Enter(
const parser::EndFunctionStmt &);
87 void Enter(
const parser::ExecutionPart &);
88 void Leave(
const parser::ExecutionPart &);
176 void Enter(
const parser::OmpContextSelector &);
177 void Leave(
const parser::OmpContextSelector &);
179#define GEN_FLANG_CLAUSE_CHECK_ENTER
180#include "llvm/Frontend/OpenMP/OMP.inc"
183 bool CheckAllowedClause(llvmOmpClause clause);
184 void CheckVariableListItem(
const SymbolSourceMap &symbols);
185 void CheckDirectiveSpelling(
189 void CheckMultipleOccurrence(semantics::UnorderedSymbolSet &listVars,
191 const std::string &clauseName);
192 void CheckMultListItems();
193 void CheckStructureComponent(
195 bool HasInvalidWorksharingNesting(
198 bool IsCloselyNestedRegion(
const OmpDirectiveSet &set);
199 bool IsNestedInDirective(llvm::omp::Directive directive);
200 bool IsCombinedParallelWorksharing(llvm::omp::Directive directive)
const;
201 bool InTargetRegion();
202 void HasInvalidTeamsNesting(
206 bool HasRequires(llvm::omp::Clause req);
208 void CheckAllowedMapTypes(
211 const std::list<parser::OmpTraitProperty> &GetTraitPropertyList(
213 std::optional<llvm::omp::Clause> GetClauseFromProperty(
216 void CheckTraitSelectorList(
const std::list<parser::OmpTraitSelector> &);
219 bool VerifyTraitPropertyLists(
221 void CheckTraitSelector(
225 void CheckTraitCondition(
227 void CheckTraitDeviceNum(
229 void CheckTraitRequires(
234 llvm::StringRef getClauseName(llvm::omp::Clause clause)
override;
235 llvm::StringRef getDirectiveName(llvm::omp::Directive directive)
override;
238 typename LessTy,
typename RangeTy,
239 typename IterTy =
decltype(std::declval<RangeTy>().begin())>
240 std::optional<IterTy> FindDuplicate(RangeTy &&);
243 void CheckDependArraySection(
254 void CheckThreadprivateOrDeclareTargetVar(
const parser::Name &);
257 void CheckSymbolName(
259 void CheckSymbolNames(
261 void CheckIntentInPointer(SymbolSourceMap &,
const llvm::omp::Clause);
262 void CheckProcedurePointer(SymbolSourceMap &,
const llvm::omp::Clause);
264 llvm::StringRef clause,
bool suggestToUseCrayPointer =
true);
266 void CheckDefinableObjects(SymbolSourceMap &,
const llvm::omp::Clause);
267 void CheckCopyingPolymorphicAllocatable(
268 SymbolSourceMap &,
const llvm::omp::Clause);
269 void CheckPrivateSymbolsInOuterCxt(
270 SymbolSourceMap &, DirectivesClauseTriple &,
const llvm::omp::Clause);
273 void CheckIsLoopIvPartOfClause(
275 bool CheckTargetBlockOnlyTeams(
const parser::Block &);
278 void CheckIndividualAllocateDirective(
287 template <
typename T,
typename D>
bool IsOperatorValid(
const T &,
const D &);
293 std::string_view name,
bool checkTypeOnPointer =
true);
302 void CheckAtomicReadAssignment(
304 void CheckAtomicWriteAssignment(
306 std::optional<evaluate::Assignment> CheckAtomicUpdateAssignment(
308 std::pair<bool, bool> CheckAtomicUpdateAssignmentRhs(
const SomeExpr &atom,
310 void CheckAtomicConditionalUpdateAssignment(
const SomeExpr &cond,
313 void CheckAtomicConditionalUpdateStmt(
321 void CheckAtomicConditionalUpdateCapture(
328 void CheckScanModifier(
const parser::OmpClause::Reduction &x);
333 void CheckTargetUpdate();
335 void CheckDependenceType(
const parser::OmpDependenceType::Value &x);
336 void CheckTaskDependenceType(
const parser::OmpTaskDependenceType::Value &x);
337 std::optional<llvm::omp::Directive> GetCancelType(
339 const std::optional<parser::OmpClauseList> &maybeClauses);
340 void CheckCancellationNest(
343 void CheckReductionObjects(
352 void ChecksOnOrderedAsBlock();
355 void ChecksOnOrderedAsStandalone();
356 void CheckOrderedDependClause(std::optional<std::int64_t> orderedValue);
357 void CheckReductionArraySection(
360 const parser::Name &name,
const llvm::omp::Clause clause);
361 void CheckLastPartRefForArraySection(
363 void CheckSharedBindingInOuterContext(
370 void CheckAllowedRequiresClause(llvmOmpClause clause);
371 bool deviceConstructFound_{
false};
375 void EnterDirectiveNest(
const int index) { directiveNest_[index]++; }
376 void ExitDirectiveNest(
const int index) { directiveNest_[index]--; }
377 int GetDirectiveNest(
const int index) {
return directiveNest_[index]; }
379 inline void ErrIfLHSAndRHSSymbolsMatch(
381 inline void ErrIfNonScalarAssignmentStmt(
383 enum directiveNestType :
int {
385 TargetBlockOnlyTeams,
390 LastType = MetadirectiveNest,
392 int directiveNest_[LastType + 1] = {0};
394 int allocateDirectiveLevel{0};
396 SymbolSourceMap deferredNonVariables_;
400 std::vector<LoopConstruct> loopStack_;
402 std::vector<const Scope *> scopeStack_;
404 enum class PartKind :
int {
410 std::vector<PartKind> partStack_;