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 &);
91 void Enter(
const parser::ExecutionPart &);
92 void Leave(
const parser::ExecutionPart &);
180 void Enter(
const parser::OmpContextSelector &);
181 void Leave(
const parser::OmpContextSelector &);
183#define GEN_FLANG_CLAUSE_CHECK_ENTER
184#include "llvm/Frontend/OpenMP/OMP.inc"
187 bool CheckAllowedClause(llvmOmpClause clause);
188 void CheckVariableListItem(
const SymbolSourceMap &symbols);
189 void CheckDirectiveSpelling(
193 void CheckMultipleOccurrence(semantics::UnorderedSymbolSet &listVars,
195 const std::string &clauseName);
196 void CheckMultListItems();
197 void CheckStructureComponent(
199 bool HasInvalidWorksharingNesting(
202 bool IsCloselyNestedRegion(
const OmpDirectiveSet &set);
203 bool IsNestedInDirective(llvm::omp::Directive directive);
204 bool IsCombinedParallelWorksharing(llvm::omp::Directive directive)
const;
205 bool InTargetRegion();
206 void HasInvalidTeamsNesting(
210 bool HasRequires(llvm::omp::Clause req);
212 void CheckAllowedMapTypes(
215 const std::list<parser::OmpTraitProperty> &GetTraitPropertyList(
217 std::optional<llvm::omp::Clause> GetClauseFromProperty(
220 void CheckTraitSelectorList(
const std::list<parser::OmpTraitSelector> &);
223 bool VerifyTraitPropertyLists(
225 void CheckTraitSelector(
229 void CheckTraitCondition(
231 void CheckTraitDeviceNum(
233 void CheckTraitRequires(
238 llvm::StringRef getClauseName(llvm::omp::Clause clause)
override;
239 llvm::StringRef getDirectiveName(llvm::omp::Directive directive)
override;
242 typename LessTy,
typename RangeTy,
243 typename IterTy =
decltype(std::declval<RangeTy>().begin())>
244 std::optional<IterTy> FindDuplicate(RangeTy &&);
247 void CheckDependArraySection(
258 void CheckThreadprivateOrDeclareTargetVar(
const parser::Name &);
261 void CheckSymbolName(
263 void CheckSymbolNames(
265 void CheckIntentInPointer(SymbolSourceMap &,
const llvm::omp::Clause);
266 void CheckAssumedSizeArray(SymbolSourceMap &,
const llvm::omp::Clause);
267 void CheckProcedurePointer(SymbolSourceMap &,
const llvm::omp::Clause);
269 llvm::StringRef clause,
bool suggestToUseCrayPointer =
true);
271 void CheckDefinableObjects(SymbolSourceMap &,
const llvm::omp::Clause);
272 void CheckCopyingPolymorphicAllocatable(
273 SymbolSourceMap &,
const llvm::omp::Clause);
274 void CheckPrivateSymbolsInOuterCxt(
275 SymbolSourceMap &, DirectivesClauseTriple &,
const llvm::omp::Clause);
278 void CheckIsLoopIvPartOfClause(
280 bool CheckTargetBlockOnlyTeams(
const parser::Block &);
283 void CheckIndividualAllocateDirective(
292 template <
typename T,
typename D>
bool IsOperatorValid(
const T &,
const D &);
298 std::string_view name,
bool checkTypeOnPointer =
true);
307 void CheckAtomicReadAssignment(
309 void CheckAtomicWriteAssignment(
311 std::optional<evaluate::Assignment> CheckAtomicUpdateAssignment(
313 std::pair<bool, bool> CheckAtomicUpdateAssignmentRhs(
const SomeExpr &atom,
315 void CheckAtomicConditionalUpdateAssignment(
const SomeExpr &cond,
318 void CheckAtomicConditionalUpdateStmt(
326 void CheckAtomicConditionalUpdateCapture(
333 void CheckScanModifier(
const parser::OmpClause::Reduction &x);
340 void CheckTargetUpdate();
342 void CheckDependenceType(
const parser::OmpDependenceType::Value &x);
343 void CheckTaskDependenceType(
const parser::OmpTaskDependenceType::Value &x);
344 std::optional<llvm::omp::Directive> GetCancelType(
346 const std::optional<parser::OmpClauseList> &maybeClauses);
347 void CheckCancellationNest(
350 void CheckReductionObjects(
359 void ChecksOnOrderedAsBlock();
362 void ChecksOnOrderedAsStandalone();
363 void CheckOrderedDependClause(std::optional<std::int64_t> orderedValue);
364 void CheckReductionArraySection(
367 const parser::Name &name,
const llvm::omp::Clause clause);
368 void CheckLastPartRefForArraySection(
370 void CheckSharedBindingInOuterContext(
377 void CheckAllowedRequiresClause(llvmOmpClause clause);
378 bool deviceConstructFound_{
false};
382 void EnterDirectiveNest(
const int index) { directiveNest_[index]++; }
383 void ExitDirectiveNest(
const int index) { directiveNest_[index]--; }
384 int GetDirectiveNest(
const int index) {
return directiveNest_[index]; }
386 inline void ErrIfLHSAndRHSSymbolsMatch(
388 inline void ErrIfNonScalarAssignmentStmt(
390 enum directiveNestType :
int {
392 TargetBlockOnlyTeams,
397 LastType = MetadirectiveNest,
399 int directiveNest_[LastType + 1] = {0};
401 int allocateDirectiveLevel{0};
403 SymbolSourceMap deferredNonVariables_;
407 std::vector<LoopConstruct> loopStack_;
409 std::vector<const Scope *> scopeStack_;
411 enum class PartKind :
int {
417 std::vector<PartKind> partStack_;