Lines Matching refs:parser
22 void OmpStructureChecker::Enter(const parser::OmpClause::X &) { \
27 void OmpStructureChecker::Enter(const parser::OmpClause::X &c) { \
33 void OmpStructureChecker::Enter(const parser::OmpClause::X &c) { \
40 void OmpStructureChecker::Enter(const parser::X &) { \
54 static const parser::Designator *GetDesignatorFromObj(
55 const parser::OmpObject &object) {
56 return std::get_if<parser::Designator>(&object.u);
59 static const parser::DataRef *GetDataRefFromObj(
60 const parser::OmpObject &object) {
62 return std::get_if<parser::DataRef>(&desg->u);
67 static const parser::ArrayElement *GetArrayElementFromObj(
68 const parser::OmpObject &object) {
70 using ElementIndirection = common::Indirection<parser::ArrayElement>;
82 OmpWorkshareBlockChecker(SemanticsContext &context, parser::CharBlock source)
88 bool Pre(const parser::AssignmentStmt &assignment) {
89 const auto &var{std::get<parser::Variable>(assignment.t)};
90 const auto &expr{std::get<parser::Expr>(assignment.t)};
105 bool Pre(const parser::Expr &expr) {
134 parser::CharBlock source_;
145 bool Pre(const parser::DoConstruct &dc) {
148 std::get<parser::Statement<parser::NonLabelDoStmt>>(dc.t)};
150 std::get<std::optional<parser::Name>>(doStmt.statement.t)};
168 void Post(const parser::DoConstruct &dc) { level_++; }
170 bool Pre(const parser::CycleStmt &cyclestmt) {
187 bool Pre(const parser::ExitStmt &exitStmt) {
204 bool Pre(const parser::Statement<parser::ActionStmt> &actionstmt) {
211 const parser::CharBlock *source_;
226 bool Pre(const parser::Name &name) {
271 auto clauseName{parser::ToUpperCaseLetters(getClauseName(clause).str())};
272 auto dirName{parser::ToUpperCaseLetters(getDirectiveName(dir).str())};
372 const parser::OmpObject &object) {
375 [&](const parser::Name &x) {
379 [&](const parser::Designator &x) {
392 const std::list<parser::Name> &nameList, const parser::CharBlock &item,
409 const auto &alignedClause{std::get<parser::OmpClause::Aligned>(clause->u)};
411 std::list<parser::Name> alignedNameList;
413 if (const auto *name{parser::Unwrap<parser::Name>(ompObject)}) {
443 std::get<parser::OmpClause::Nontemporal>(clause->u)};
451 auto &linearClause{std::get<parser::OmpClause::Linear>(clause->u)};
452 std::list<parser::Name> nameList;
455 std::get<parser::OmpObjectList>(linearClause.v.t), symbols);
457 return parser::Name{pair.second, const_cast<Symbol *>(pair.first)};
464 const parser::CharBlock &source, const OmpDirectiveSet &set) {
478 const parser::OpenMPLoopConstruct &x) {
480 const auto &beginLoopDir{std::get<parser::OmpBeginLoopDirective>(x.t)};
481 const auto &beginDir{std::get<parser::OmpLoopDirective>(beginLoopDir.t)};
501 const parser::OpenMPLoopConstruct &x) {
502 const auto &beginLoopDir{std::get<parser::OmpBeginLoopDirective>(x.t)};
503 const auto &beginDir{std::get<parser::OmpLoopDirective>(beginLoopDir.t)};
505 auto teamsBindingChecker = [&](parser::MessageFixedText msg) {
506 const auto &clauseList{std::get<parser::OmpClauseList>(beginLoopDir.t)};
509 std::get_if<parser::OmpClause::Bind>(&clause.u)}) {
510 if (bindClause->v.v != parser::OmpBindClause::Binding::Teams) {
536 const llvm::omp::Directive &dir, const parser::CharBlock &source) {
545 const parser::CharBlock &source, const parser::Name &name) {
565 const parser::CharBlock &source,
566 const parser::OmpObjectList &ompObjectList) {
570 [&](const parser::Designator &designator) {
572 std::get_if<parser::DataRef>(&designator.u)}) {
573 if (const auto *name{std::get_if<parser::Name>(&dataRef->u)}) {
578 [&](const parser::Name &name) {
591 const parser::OmpClause *ompClause = nullptr;
592 if constexpr (std::is_same_v<D, const parser::OmpAtomicClauseList>) {
593 ompClause = std::get_if<parser::OmpClause>(&clause.u);
596 } else if constexpr (std::is_same_v<D, const parser::OmpClauseList>) {
599 if (const parser::OmpClause::Hint *hintClause{
600 std::get_if<parser::OmpClause::Hint>(&ompClause->u)}) {
627 void OmpStructureChecker::Enter(const parser::OmpDirectiveSpecification &x) {
631 void OmpStructureChecker::Leave(const parser::OmpDirectiveSpecification &) {
635 void OmpStructureChecker::Enter(const parser::OmpMetadirectiveDirective &x) {
639 void OmpStructureChecker::Leave(const parser::OmpMetadirectiveDirective &) {
643 void OmpStructureChecker::Enter(const parser::OpenMPConstruct &x) {
659 void OmpStructureChecker::Leave(const parser::OpenMPConstruct &) {
667 void OmpStructureChecker::Enter(const parser::OpenMPDeclarativeConstruct &x) {
671 void OmpStructureChecker::Leave(const parser::OpenMPDeclarativeConstruct &x) {
675 void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
677 const auto &beginLoopDir{std::get<parser::OmpBeginLoopDirective>(x.t)};
678 const auto &beginDir{std::get<parser::OmpLoopDirective>(beginLoopDir.t)};
682 std::get<std::optional<parser::OmpEndLoopDirective>>(x.t)}) {
684 std::get<parser::OmpLoopDirective>(endLoopDir.value().t)};
686 CheckMatching<parser::OmpLoopDirective>(beginDir, endDir);
718 std::get<std::optional<parser::DoConstruct>>(x.t)}) {
719 const auto &doBlock{std::get<parser::Block>(doConstruct->t)};
735 const parser::Name OmpStructureChecker::GetLoopIndex(
736 const parser::DoConstruct *x) {
737 using Bounds = parser::LoopControl::Bounds;
740 void OmpStructureChecker::SetLoopInfo(const parser::OpenMPLoopConstruct &x) {
742 std::get<std::optional<parser::DoConstruct>>(x.t)}) {
743 const parser::DoConstruct *loop{&*loopConstruct};
745 const parser::Name &itrVal{GetLoopIndex(loop)};
752 const parser::OmpIteratorSpecifier &x) {
758 const auto &[begin, end, step]{std::get<parser::SubscriptTriplet>(x.t).t};
788 void OmpStructureChecker::CheckIteratorModifier(const parser::OmpIterator &x) {
792 auto &typeDecl{std::get<parser::TypeDeclarationStmt>(iterSpec.t)};
793 auto &typeSpec{std::get<parser::DeclarationTypeSpec>(typeDecl.t)};
794 if (!std::holds_alternative<parser::IntrinsicTypeSpec>(typeSpec.u)) {
797 auto &intrinType{std::get<parser::IntrinsicTypeSpec>(typeSpec.u)};
798 if (!std::holds_alternative<parser::IntegerTypeSpec>(intrinType.u)) {
811 const parser::OpenMPLoopConstruct &x) {
813 std::get<std::optional<parser::DoConstruct>>(x.t)}) {
815 for (const parser::DoConstruct *loop{&*loopConstruct}; loop;) {
817 const parser::Name &itrVal{GetLoopIndex(loop)};
829 const auto &block{std::get<parser::Block>(loop->t)};
831 loop = it != block.end() ? parser::Unwrap<parser::DoConstruct>(*it)
837 void OmpStructureChecker::CheckSIMDNest(const parser::OpenMPConstruct &c) {
854 [&](const parser::OpenMPBlockConstruct &c) {
856 std::get<parser::OmpBeginBlockDirective>(c.t)};
858 std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
861 std::get<parser::OmpClauseList>(beginBlockDir.t)};
863 if (std::get_if<parser::OmpClause::Simd>(&clause.u)) {
870 [&](const parser::OpenMPStandaloneConstruct &c) {
872 std::get_if<parser::OpenMPSimpleStandaloneConstruct>(
874 const auto &dir{std::get<parser::OmpSimpleStandaloneDirective>(
878 std::get<parser::OmpClauseList>(simpleConstruct->t)};
880 if (std::get_if<parser::OmpClause::Simd>(&clause.u)) {
891 [&](const parser::OpenMPLoopConstruct &c) {
893 std::get<parser::OmpBeginLoopDirective>(c.t)};
895 std::get<parser::OmpLoopDirective>(beginLoopDir.t)};
901 [&](const parser::OpenMPAtomicConstruct &c) {
909 context_.Say(parser::FindSourceLocation(c),
917 void OmpStructureChecker::CheckTargetNest(const parser::OpenMPConstruct &c) {
923 [&](const parser::OpenMPBlockConstruct &c) {
925 std::get<parser::OmpBeginBlockDirective>(c.t)};
927 std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
933 [&](const parser::OpenMPStandaloneConstruct &c) {
936 [&](const parser::OpenMPSimpleStandaloneConstruct &c) {
938 std::get<parser::OmpSimpleStandaloneDirective>(c.t)};
952 [&](const parser::OpenMPLoopConstruct &c) {
954 std::get<parser::OmpBeginLoopDirective>(c.t)};
956 std::get<parser::OmpLoopDirective>(beginLoopDir.t)};
967 parser::FindSourceLocation(c),
969 parser::ToUpperCaseLetters(
975 const parser::OpenMPLoopConstruct &x) {
976 const auto &beginLoopDir{std::get<parser::OmpBeginLoopDirective>(x.t)};
977 const auto &clauseList{std::get<parser::OmpClauseList>(beginLoopDir.t)};
984 std::get_if<parser::OmpClause::Collapse>(&clause.u)}) {
990 std::get_if<parser::OmpClause::Ordered>(&clause.u)}) {
1005 const parser::OpenMPLoopConstruct &x) {
1008 parser::Walk(x, checker);
1012 const parser::OpenMPLoopConstruct &x) {
1014 const auto &beginLoopDir{std::get<parser::OmpBeginLoopDirective>(x.t)};
1015 const auto &clauses{std::get<parser::OmpClauseList>(beginLoopDir.t)};
1021 if (auto *linearClause{std::get_if<parser::OmpClause::Linear>(&clause.u)}) {
1022 auto &objects{std::get<parser::OmpObjectList>(linearClause->v.t)};
1038 std::get<std::optional<parser::DoConstruct>>(x.t)}) {
1039 for (const parser::DoConstruct *loop{&*loopConstruct}; loop;) {
1041 const parser::Name &itrVal{GetLoopIndex(loop)};
1052 const auto &block{std::get<parser::Block>(loop->t)};
1054 loop = it != block.end() ? parser::Unwrap<parser::DoConstruct>(*it)
1069 void OmpStructureChecker::Leave(const parser::OpenMPLoopConstruct &x) {
1070 const auto &beginLoopDir{std::get<parser::OmpBeginLoopDirective>(x.t)};
1071 const auto &clauseList{std::get<parser::OmpClauseList>(beginLoopDir.t)};
1077 using ReductionModifier = parser::OmpReductionModifier;
1080 std::get_if<parser::OmpClause::Reduction>(&clause.u)}) {
1086 std::get<parser::OmpObjectList>(reductionClause->v.t)};
1087 auto checkReductionSymbolInScan = [&](const parser::Name *name) {
1102 [&](const parser::Designator &designator) {
1123 auto *loopc{std::get_if<const parser::OpenMPLoopConstruct *>(&top)};
1129 void OmpStructureChecker::Enter(const parser::OmpEndLoopDirective &x) {
1130 const auto &dir{std::get<parser::OmpLoopDirective>(x.t)};
1148 void OmpStructureChecker::Leave(const parser::OmpEndLoopDirective &x) {
1155 void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
1156 const auto &beginBlockDir{std::get<parser::OmpBeginBlockDirective>(x.t)};
1157 const auto &endBlockDir{std::get<parser::OmpEndBlockDirective>(x.t)};
1158 const auto &beginDir{std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
1159 const auto &endDir{std::get<parser::OmpBlockDirective>(endBlockDir.t)};
1160 const parser::Block &block{std::get<parser::Block>(x.t)};
1162 CheckMatching<parser::OmpBlockDirective>(beginDir, endDir);
1180 context_.Say(parser::FindSourceLocation(x),
1226 const auto &clauses{std::get<parser::OmpClauseList>(beginBlockDir.t)};
1228 if (std::get_if<parser::OmpClause::Untied>(&clause.u)) {
1230 parser::Walk(block, check);
1241 const parser::OpenMPBlockConstruct &x) {
1247 context_.Say(parser::FindSourceLocation(x),
1254 void OmpStructureChecker::Leave(const parser::OpenMPBlockConstruct &) {
1291 std::get<parser::OmpClause::Ordered>(clause->u)};
1331 void OmpStructureChecker::Leave(const parser::OmpBeginBlockDirective &) {
1342 void OmpStructureChecker::Enter(const parser::OpenMPSectionsConstruct &x) {
1344 std::get<parser::OmpBeginSectionsDirective>(x.t)};
1345 const auto &endSectionsDir{std::get<parser::OmpEndSectionsDirective>(x.t)};
1347 std::get<parser::OmpSectionsDirective>(beginSectionsDir.t)};
1348 const auto &endDir{std::get<parser::OmpSectionsDirective>(endSectionsDir.t)};
1349 CheckMatching<parser::OmpSectionsDirective>(beginDir, endDir);
1352 const auto §ionBlocks{std::get<parser::OmpSectionBlocks>(x.t)};
1353 for (const parser::OpenMPConstruct &block : sectionBlocks.v) {
1354 CheckNoBranching(std::get<parser::OpenMPSectionConstruct>(block.u).v,
1361 void OmpStructureChecker::Leave(const parser::OpenMPSectionsConstruct &) {
1365 void OmpStructureChecker::Enter(const parser::OmpEndSectionsDirective &x) {
1366 const auto &dir{std::get<parser::OmpSectionsDirective>(x.t)};
1384 void OmpStructureChecker::Leave(const parser::OmpEndSectionsDirective &x) {
1391 const parser::OmpObjectList &objList) {
1395 [&](const parser::Designator &) {
1396 if (const auto *name{parser::Unwrap<parser::Name>(ompObject)}) {
1480 [&](const parser::Name &) {}, // common block
1486 void OmpStructureChecker::Enter(const parser::OpenMPThreadprivate &c) {
1487 const auto &dir{std::get<parser::Verbatim>(c.t)};
1492 void OmpStructureChecker::Leave(const parser::OpenMPThreadprivate &c) {
1493 const auto &dir{std::get<parser::Verbatim>(c.t)};
1494 const auto &objectList{std::get<parser::OmpObjectList>(c.t)};
1501 void OmpStructureChecker::Enter(const parser::OpenMPDeclareSimdConstruct &x) {
1502 const auto &dir{std::get<parser::Verbatim>(x.t)};
1506 void OmpStructureChecker::Leave(const parser::OpenMPDeclareSimdConstruct &) {
1510 void OmpStructureChecker::Enter(const parser::OpenMPDepobjConstruct &x) {
1511 const auto &dir{std::get<parser::Verbatim>(x.t)};
1517 auto &clause{std::get<parser::OmpClause>(x.t)};
1519 auto getSymbol{[&](const parser::OmpObject &obj) {
1524 auto &wrapper{std::get<parser::OmpClause::Destroy>(clause.u)};
1525 if (const std::optional<parser::OmpDestroyClause> &destroy{wrapper.v}) {
1526 const Symbol *constrSym{getSymbol(std::get<parser::OmpObject>(x.t))};
1539 void OmpStructureChecker::Leave(const parser::OpenMPDepobjConstruct &x) {
1543 void OmpStructureChecker::Enter(const parser::OpenMPRequiresConstruct &x) {
1544 const auto &dir{std::get<parser::Verbatim>(x.t)};
1548 void OmpStructureChecker::Leave(const parser::OpenMPRequiresConstruct &) {
1552 void OmpStructureChecker::CheckAlignValue(const parser::OmpClause &clause) {
1553 if (auto *align{std::get_if<parser::OmpClause::Align>(&clause.u)}) {
1561 void OmpStructureChecker::Enter(const parser::OpenMPDeclarativeAllocate &x) {
1563 const auto &dir{std::get<parser::Verbatim>(x.t)};
1564 const auto &objectList{std::get<parser::OmpObjectList>(x.t)};
1566 const auto &clauseList{std::get<parser::OmpClauseList>(x.t)};
1573 void OmpStructureChecker::Leave(const parser::OpenMPDeclarativeAllocate &x) {
1574 const auto &dir{std::get<parser::Verbatim>(x.t)};
1575 const auto &objectList{std::get<parser::OmpObjectList>(x.t)};
1580 void OmpStructureChecker::Enter(const parser::OmpClause::Allocator &x) {
1589 void OmpStructureChecker::Enter(const parser::OmpClause::Allocate &x) {
1595 OmpGetUniqueModifier<parser::OmpAlignModifier>(modifiers)}) {
1603 if (auto *alloc{OmpGetUniqueModifier<parser::OmpAllocatorComplexModifier>(
1607 if (auto *alloc{OmpGetUniqueModifier<parser::OmpAllocatorSimpleModifier>(
1614 void OmpStructureChecker::Enter(const parser::OmpDeclareTargetWithClause &x) {
1618 void OmpStructureChecker::Leave(const parser::OmpDeclareTargetWithClause &x) {
1620 const parser::OmpClause *enterClause =
1622 const parser::OmpClause *toClause = FindClause(llvm::omp::Clause::OMPC_to);
1623 const parser::OmpClause *linkClause =
1637 void OmpStructureChecker::Enter(const parser::OpenMPDeclareMapperConstruct &x) {
1638 const auto &dir{std::get<parser::Verbatim>(x.t)};
1641 const auto &spec{std::get<parser::OmpDeclareMapperSpecifier>(x.t)};
1642 const auto &type = std::get<parser::TypeSpec>(spec.t);
1643 if (!std::get_if<parser::DerivedTypeSpec>(&type.u)) {
1648 void OmpStructureChecker::Leave(const parser::OpenMPDeclareMapperConstruct &) {
1652 void OmpStructureChecker::Enter(const parser::OpenMPDeclareTargetConstruct &x) {
1653 const auto &dir{std::get<parser::Verbatim>(x.t)};
1657 void OmpStructureChecker::Enter(const parser::OmpDeclareTargetWithList &x) {
1689 const parser::CharBlock &source, const parser::OmpObjectList &objList) {
1693 [&](const parser::Designator &designator) {
1694 if (const auto *name{parser::Unwrap<parser::Name>(ompObject)}) {
1702 [&](const parser::Name &name) {
1714 void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &x) {
1715 const auto &dir{std::get<parser::Verbatim>(x.t)};
1716 const auto &spec{std::get<parser::OmpDeclareTargetSpecifier>(x.t)};
1721 if (const auto *objectList{parser::Unwrap<parser::OmpObjectList>(spec.u)}) {
1727 parser::Unwrap<parser::OmpClauseList>(spec.u)}) {
1733 [&](const parser::OmpClause::To &toClause) {
1735 auto &objList{std::get<parser::OmpObjectList>(toClause.v.t)};
1740 [&](const parser::OmpClause::Link &linkClause) {
1745 [&](const parser::OmpClause::Enter &enterClause) {
1751 [&](const parser::OmpClause::DeviceType &deviceTypeClause) {
1754 parser::OmpDeviceTypeClause::DeviceTypeDescription::Host) {
1772 void OmpStructureChecker::Enter(const parser::OmpErrorDirective &x) {
1773 const auto &dir{std::get<parser::Verbatim>(x.t)};
1777 void OmpStructureChecker::Enter(const parser::OpenMPDispatchConstruct &x) {
1779 const auto &block{std::get<parser::Block>(x.t)};
1788 if (const parser::AssignmentStmt *
1789 assignStmt{parser::Unwrap<parser::AssignmentStmt>(*it)}) {
1790 if (parser::Unwrap<parser::FunctionReference>(assignStmt->t)) {
1793 } else if (parser::Unwrap<parser::CallStmt>(*it)) {
1803 void OmpStructureChecker::Leave(const parser::OpenMPDispatchConstruct &x) {
1807 void OmpStructureChecker::Leave(const parser::OmpErrorDirective &x) {
1811 void OmpStructureChecker::Enter(const parser::OmpClause::At &x) {
1814 if (x.v.v == parser::OmpAtClause::ActionTime::Execution) {
1821 void OmpStructureChecker::Enter(const parser::OpenMPExecutableAllocate &x) {
1823 const auto &dir{std::get<parser::Verbatim>(x.t)};
1824 const auto &objectList{std::get<std::optional<parser::OmpObjectList>>(x.t)};
1826 const auto &clauseList{std::get<parser::OmpClauseList>(x.t)};
1835 void OmpStructureChecker::Leave(const parser::OpenMPExecutableAllocate &x) {
1836 const auto &dir{std::get<parser::Verbatim>(x.t)};
1837 const auto &objectList{std::get<std::optional<parser::OmpObjectList>>(x.t)};
1843 void OmpStructureChecker::Enter(const parser::OpenMPAllocatorsConstruct &x) {
1845 const auto &dir{std::get<parser::Verbatim>(x.t)};
1847 const auto &clauseList{std::get<parser::OmpClauseList>(x.t)};
1850 parser::Unwrap<parser::OmpClause::Allocate>(clause)}) {
1852 dir.source, std::get<parser::OmpObjectList>(allocClause->v.t));
1857 void OmpStructureChecker::Leave(const parser::OpenMPAllocatorsConstruct &x) {
1858 const auto &dir{std::get<parser::Verbatim>(x.t)};
1859 const auto &clauseList{std::get<parser::OmpClauseList>(x.t)};
1862 std::get_if<parser::OmpClause::Allocate>(&clause.u)}) {
1864 dir.source, std::get<parser::OmpObjectList>(allocClause->v.t));
1871 const parser::OpenMPSimpleStandaloneConstruct &x) {
1872 if (std::get<parser::OmpClauseList>(x.t).v.size() != 1) {
1886 const parser::OpenMPSimpleStandaloneConstruct &x) {
1892 context_.Say(parser::FindSourceLocation(x),
1909 auto visitDoacross{[&](const parser::OmpDoacross &doa,
1910 const parser::CharBlock &src) {
1913 [&](const parser::OmpDoacross::Source &) { dependSourceCount++; },
1914 [&](const parser::OmpDoacross::Sink &) { dependSinkCount++; }},
1930 const auto &dependClause{std::get<parser::OmpClause::Depend>(clause->u)};
1931 if (auto *doAcross{std::get_if<parser::OmpDoacross>(&dependClause.v.u)}) {
1939 auto &doaClause{std::get<parser::OmpClause::Doacross>(clause->u)};
1949 std::get<parser::OmpClause::Ordered>(clause->u)};
1969 auto visitDoacross{[&](const parser::OmpDoacross &doa,
1970 const parser::CharBlock &src) {
1971 if (auto *sinkVector{std::get_if<parser::OmpDoacross::Sink>(&doa.u)}) {
1980 auto &dependClause{std::get<parser::OmpClause::Depend>(clause->u)};
1981 if (auto *doAcross{std::get_if<parser::OmpDoacross>(&dependClause.v.u)}) {
1986 auto &doaClause{std::get<parser::OmpClause::Doacross>(clause->u)};
1992 const parser::OmpClause *toWrapper{FindClause(llvm::omp::Clause::OMPC_to)};
1993 const parser::OmpClause *fromWrapper{
2002 auto &fromClause{std::get<parser::OmpClause::From>(fromWrapper->u).v};
2003 auto &toClause{std::get<parser::OmpClause::To>(toWrapper->u).v};
2005 std::get<parser::OmpObjectList>(fromClause.t), fromSymbols);
2007 std::get<parser::OmpObjectList>(toClause.t), toSymbols);
2026 const parser::OmpTaskDependenceType::Value &x) {
2032 case parser::OmpTaskDependenceType::Value::In:
2033 case parser::OmpTaskDependenceType::Value::Out:
2034 case parser::OmpTaskDependenceType::Value::Inout:
2036 case parser::OmpTaskDependenceType::Value::Mutexinoutset:
2037 case parser::OmpTaskDependenceType::Value::Depobj:
2040 case parser::OmpTaskDependenceType::Value::Inoutset:
2048 parser::ToUpperCaseLetters(
2049 parser::OmpTaskDependenceType::EnumToString(x)),
2055 const parser::OmpDependenceType::Value &x) {
2061 case parser::OmpDependenceType::Value::Source:
2062 case parser::OmpDependenceType::Value::Sink:
2070 parser::ToUpperCaseLetters(parser::OmpDependenceType::EnumToString(x)),
2076 const parser::OpenMPSimpleStandaloneConstruct &x) {
2077 const auto &dir{std::get<parser::OmpSimpleStandaloneDirective>(x.t)};
2092 const parser::OpenMPSimpleStandaloneConstruct &x) {
2107 void OmpStructureChecker::Enter(const parser::OpenMPFlushConstruct &x) {
2108 const auto &dir{std::get<parser::Verbatim>(x.t)};
2112 void OmpStructureChecker::Leave(const parser::OpenMPFlushConstruct &x) {
2117 std::get<std::optional<parser::OmpObjectList>>(x.t)}) {
2118 context_.Say(parser::FindSourceLocation(flushList),
2126 void OmpStructureChecker::Enter(const parser::OpenMPCancelConstruct &x) {
2127 const auto &dir{std::get<parser::Verbatim>(x.t)};
2128 const auto &type{std::get<parser::OmpCancelType>(x.t)};
2133 void OmpStructureChecker::Leave(const parser::OpenMPCancelConstruct &) {
2137 void OmpStructureChecker::Enter(const parser::OpenMPCriticalConstruct &x) {
2138 const auto &dir{std::get<parser::OmpCriticalDirective>(x.t)};
2139 const auto &endDir{std::get<parser::OmpEndCriticalDirective>(x.t)};
2141 const auto &block{std::get<parser::Block>(x.t)};
2143 const auto &dirName{std::get<std::optional<parser::Name>>(dir.t)};
2144 const auto &endDirName{std::get<std::optional<parser::Name>>(endDir.t)};
2145 const auto &ompClause{std::get<parser::OmpClauseList>(dir.t)};
2150 parser::MessageFormattedText{
2156 parser::MessageFormattedText{
2162 parser::MessageFormattedText{
2169 parser::MessageFormattedText{
2173 CheckHintClause<const parser::OmpClauseList>(&ompClause, nullptr);
2176 void OmpStructureChecker::Leave(const parser::OpenMPCriticalConstruct &) {
2181 const parser::OpenMPCancellationPointConstruct &x) {
2182 const auto &dir{std::get<parser::Verbatim>(x.t)};
2183 const auto &type{std::get<parser::OmpCancelType>(x.t)};
2190 const parser::OpenMPCancellationPointConstruct &) {
2195 const parser::CharBlock &source, const parser::OmpCancelType::Type &type) {
2207 case parser::OmpCancelType::Type::Taskgroup:
2236 parser::ToUpperCaseLetters(
2237 parser::OmpCancelType::EnumToString(type)),
2241 case parser::OmpCancelType::Type::Sections:
2247 case parser::OmpCancelType::Type::Do:
2253 case parser::OmpCancelType::Type::Parallel:
2264 parser::ToUpperCaseLetters(parser::OmpCancelType::EnumToString(type)),
2266 parser::ToUpperCaseLetters(
2272 case parser::OmpCancelType::Type::Taskgroup:
2277 parser::ToUpperCaseLetters(
2278 parser::OmpCancelType::EnumToString(type)));
2280 case parser::OmpCancelType::Type::Sections:
2285 parser::ToUpperCaseLetters(
2286 parser::OmpCancelType::EnumToString(type)));
2288 case parser::OmpCancelType::Type::Do:
2293 parser::ToUpperCaseLetters(
2294 parser::OmpCancelType::EnumToString(type)));
2296 case parser::OmpCancelType::Type::Parallel:
2301 parser::ToUpperCaseLetters(
2302 parser::OmpCancelType::EnumToString(type)));
2308 void OmpStructureChecker::Enter(const parser::OmpEndBlockDirective &x) {
2309 const auto &dir{std::get<parser::OmpBlockDirective>(x.t)};
2336 void OmpStructureChecker::Leave(const parser::OmpEndBlockDirective &x) {
2345 const parser::Variable &var) {
2352 std::get<common::Indirection<parser::Designator>>(var.u);
2354 std::get_if<parser::DataRef>(&designator.value().u);
2355 const parser::Name *name =
2356 dataRef ? std::get_if<parser::Name>(&dataRef->u) : nullptr;
2366 const parser::Variable &var, const parser::Expr &expr) {
2376 const common::Indirection<parser::Designator> *designator =
2377 std::get_if<common::Indirection<parser::Designator>>(&expr.u);
2397 const parser::Variable &var, const parser::Expr &expr) {
2424 std::variant<parser::Expr::Add, parser::Expr::Multiply,
2425 parser::Expr::Subtract, parser::Expr::Divide, parser::Expr::AND,
2426 parser::Expr::OR, parser::Expr::EQV, parser::Expr::NEQV>;
2427 using BinaryOperators = std::variant<parser::Expr::Add,
2428 parser::Expr::Multiply, parser::Expr::Subtract, parser::Expr::Divide,
2429 parser::Expr::AND, parser::Expr::OR, parser::Expr::EQV,
2430 parser::Expr::NEQV, parser::Expr::Power, parser::Expr::Concat,
2431 parser::Expr::LT, parser::Expr::LE, parser::Expr::EQ, parser::Expr::NE,
2432 parser::Expr::GE, parser::Expr::GT>;
2451 const parser::AssignmentStmt &assignmentStmt) {
2452 const auto &var{std::get<parser::Variable>(assignmentStmt.t)};
2453 const auto &expr{std::get<parser::Expr>(assignmentStmt.t)};
2456 [&](const common::Indirection<parser::Designator> &designator) {
2458 std::get_if<parser::DataRef>(&designator.value().u);
2460 dataRef ? std::get_if<parser::Name>(&dataRef->u) : nullptr;
2468 // Anything other than a `parser::Designator` is not allowed
2480 const parser::AssignmentStmt &assignmentStmt) {
2481 const auto &var{std::get<parser::Variable>(assignmentStmt.t)};
2482 const auto &expr{std::get<parser::Expr>(assignmentStmt.t)};
2489 const parser::AssignmentStmt &assignment) {
2490 const auto &expr{std::get<parser::Expr>(assignment.t)};
2491 const auto &var{std::get<parser::Variable>(assignment.t)};
2496 [&](const common::Indirection<parser::FunctionReference> &x) {
2499 std::get<parser::ProcedureDesignator>(x.value().v.t)};
2500 const parser::Name *name{
2501 std::get_if<parser::Name>(&procedureDesignator.u)};
2574 const parser::OmpAtomicCompare &atomicCompareConstruct) {
2592 const parser::OmpAtomicCapture &atomicCaptureConstruct) {
2593 const parser::AssignmentStmt &stmt1 =
2594 std::get<parser::OmpAtomicCapture::Stmt1>(atomicCaptureConstruct.t)
2596 const auto &stmt1Var{std::get<parser::Variable>(stmt1.t)};
2597 const auto &stmt1Expr{std::get<parser::Expr>(stmt1.t)};
2599 const parser::AssignmentStmt &stmt2 =
2600 std::get<parser::OmpAtomicCapture::Stmt2>(atomicCaptureConstruct.t)
2602 const auto &stmt2Var{std::get<parser::Variable>(stmt2.t)};
2603 const auto &stmt2Expr{std::get<parser::Expr>(stmt2.t)};
2641 const parser::OmpAtomicClauseList *leftHandClauseList,
2642 const parser::OmpAtomicClauseList *rightHandClauseList) {
2645 auto checkForValidMemoryOrderClause = [&](const parser::OmpAtomicClauseList
2648 if (std::get_if<parser::OmpFailClause>(&clause.u)) {
2656 if (std::get_if<parser::OmpMemoryOrderClause>(&clause.u)) {
2675 void OmpStructureChecker::Enter(const parser::OpenMPAtomicConstruct &x) {
2678 [&](const parser::OmpAtomic &atomicConstruct) {
2679 const auto &dir{std::get<parser::Verbatim>(atomicConstruct.t)};
2683 std::get<parser::Statement<parser::AssignmentStmt>>(
2687 &std::get<parser::OmpAtomicClauseList>(atomicConstruct.t),
2689 CheckHintClause<const parser::OmpAtomicClauseList>(
2690 &std::get<parser::OmpAtomicClauseList>(atomicConstruct.t),
2693 [&](const parser::OmpAtomicUpdate &atomicUpdate) {
2694 const auto &dir{std::get<parser::Verbatim>(atomicUpdate.t)};
2698 std::get<parser::Statement<parser::AssignmentStmt>>(
2703 CheckHintClause<const parser::OmpAtomicClauseList>(
2706 [&](const parser::OmpAtomicRead &atomicRead) {
2707 const auto &dir{std::get<parser::Verbatim>(atomicRead.t)};
2712 CheckHintClause<const parser::OmpAtomicClauseList>(
2715 std::get<parser::Statement<parser::AssignmentStmt>>(
2719 [&](const parser::OmpAtomicWrite &atomicWrite) {
2720 const auto &dir{std::get<parser::Verbatim>(atomicWrite.t)};
2725 CheckHintClause<const parser::OmpAtomicClauseList>(
2728 std::get<parser::Statement<parser::AssignmentStmt>>(
2732 [&](const parser::OmpAtomicCapture &atomicCapture) {
2733 const auto &dir{std::get<parser::Verbatim>(atomicCapture.t)};
2738 CheckHintClause<const parser::OmpAtomicClauseList>(
2742 [&](const parser::OmpAtomicCompare &atomicCompare) {
2743 const auto &dir{std::get<parser::Verbatim>(atomicCompare.t)};
2748 CheckHintClause<const parser::OmpAtomicClauseList>(
2756 void OmpStructureChecker::Leave(const parser::OpenMPAtomicConstruct &) {
2766 void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
2771 const auto &schedClause{std::get<parser::OmpClause::Schedule>(clause->u)};
2774 OmpGetUniqueModifier<parser::OmpOrderingModifier>(modifiers)};
2776 ordering->v == parser::OmpOrderingModifier::Value::Nonmonotonic) {
2788 std::get<parser::OmpClause::Ordered>(clause->u)};
2796 std::get<parser::OmpClause::Collapse>(clause2->u)};
2820 std::get<parser::OmpClause::Simdlen>(clause->u)};
2822 std::get<parser::OmpClause::Safelen>(clause2->u)};
2840 std::get<parser::OmpClause::Order>(o_clause->u)};
2841 if (std::get<parser::OmpOrderClause::Ordering>(orderClause.v.t) ==
2842 parser::OmpOrderClause::Ordering::Concurrent) {
2861 auto testThreadprivateVarErr = [&](Symbol sym, parser::Name name,
2866 parser::ToUpperCaseLetters(getClauseName(clauseTy).str()));
2882 [&](const parser::Designator &) {
2884 parser::Unwrap<parser::Name>(ompObject)}) {
2891 [&](const parser::Name &name) {
2910 void OmpStructureChecker::Enter(const parser::OmpClause &x) {
2925 if (const parser::OmpObjectList *objList{GetOmpObjectList(x)}) {
3009 void OmpStructureChecker::Enter(const parser::OmpClause::AcqRel &) {
3014 void OmpStructureChecker::Enter(const parser::OmpClause::Acquire &) {
3019 void OmpStructureChecker::Enter(const parser::OmpClause::Release &) {
3024 void OmpStructureChecker::Enter(const parser::OmpClause::Relaxed &) {
3029 void OmpStructureChecker::Enter(const parser::OmpClause::SeqCst &) {
3034 void OmpStructureChecker::Enter(const parser::OmpClause::Fail &) {
3040 void OmpStructureChecker::Leave(const parser::OmpClause::Fail &) {
3045 void OmpStructureChecker::Enter(const parser::OmpFailClause &) {
3051 void OmpStructureChecker::Leave(const parser::OmpFailClause &) {
3059 void OmpStructureChecker::Enter(const parser::OmpClause::Destroy &x) {
3082 void OmpStructureChecker::Enter(const parser::OmpClause::Reduction &x) {
3084 auto &objects{std::get<parser::OmpObjectList>(x.v.t)};
3090 OmpGetUniqueModifier<parser::OmpReductionIdentifier>(modifiers)};
3096 using ReductionModifier = parser::OmpReductionModifier;
3110 void OmpStructureChecker::Enter(const parser::OmpClause::InReduction &x) {
3112 auto &objects{std::get<parser::OmpObjectList>(x.v.t)};
3118 OmpGetUniqueModifier<parser::OmpReductionIdentifier>(modifiers)};
3128 void OmpStructureChecker::Enter(const parser::OmpClause::TaskReduction &x) {
3130 auto &objects{std::get<parser::OmpObjectList>(x.v.t)};
3136 OmpGetUniqueModifier<parser::OmpReductionIdentifier>(modifiers)};
3147 const parser::OmpReductionIdentifier &ident, parser::CharBlock source,
3149 auto visitOperator{[&](const parser::DefinedOperator &dOpr) {
3151 std::get_if<parser::DefinedOperator::IntrinsicOperator>(&dOpr.u)}) {
3153 case parser::DefinedOperator::IntrinsicOperator::Add:
3154 case parser::DefinedOperator::IntrinsicOperator::Multiply:
3155 case parser::DefinedOperator::IntrinsicOperator::AND:
3156 case parser::DefinedOperator::IntrinsicOperator::OR:
3157 case parser::DefinedOperator::IntrinsicOperator::EQV:
3158 case parser::DefinedOperator::IntrinsicOperator::NEQV:
3160 case parser::DefinedOperator::IntrinsicOperator::Subtract:
3170 parser::ToUpperCaseLetters(getClauseName(clauseId).str()));
3174 auto visitDesignator{[&](const parser::ProcedureDesignator &procD) {
3175 const parser::Name *name{std::get_if<parser::Name>(&procD.u)};
3185 parser::ToUpperCaseLetters(getClauseName(clauseId).str()));
3196 const parser::OmpObjectList &objects, llvm::omp::Clause clauseId) {
3202 for (const parser::OmpObject &object : objects.v) {
3216 for (const parser::OmpObject &object : objects.v) {
3223 parser::ToUpperCaseLetters(getClauseName(clauseId).str()));
3232 for (const parser::OmpObject &object : objects.v) {
3234 const parser::DataRef &base = elem->base;
3235 if (!std::holds_alternative<parser::Name>(base.u)) {
3239 parser::ToUpperCaseLetters(getClauseName(clauseId).str()));
3244 for (const parser::OmpObject &object : objects.v) {
3250 parser::ToUpperCaseLetters(getClauseName(clauseId).str()));
3258 const parser::OmpReductionIdentifier &ident, const DeclTypeSpec &type) {
3266 auto checkOperator{[&](const parser::DefinedOperator &dOpr) {
3268 std::get_if<parser::DefinedOperator::IntrinsicOperator>(&dOpr.u)}) {
3275 case parser::DefinedOperator::IntrinsicOperator::Multiply:
3276 case parser::DefinedOperator::IntrinsicOperator::Add:
3277 case parser::DefinedOperator::IntrinsicOperator::Subtract:
3282 case parser::DefinedOperator::IntrinsicOperator::AND:
3283 case parser::DefinedOperator::IntrinsicOperator::OR:
3284 case parser::DefinedOperator::IntrinsicOperator::EQV:
3285 case parser::DefinedOperator::IntrinsicOperator::NEQV:
3297 auto checkDesignator{[&](const parser::ProcedureDesignator &procD) {
3298 const parser::Name *name{std::get_if<parser::Name>(&procD.u)};
3326 const parser::OmpObjectList &objects,
3327 const parser::OmpReductionIdentifier &ident) {
3345 const parser::OmpReductionModifier &modifier) {
3346 using ReductionModifier = parser::OmpReductionModifier;
3396 const parser::OmpObjectList &ompObjectList, llvm::omp::Clause clauseId) {
3398 if (const auto *dataRef{parser::Unwrap<parser::DataRef>(ompObject)}) {
3400 parser::Unwrap<parser::ArrayElement>(ompObject)}) {
3408 const parser::OmpObjectList &redObjectList) {
3419 if (const auto *name{parser::Unwrap<parser::Name>(ompObject)}) {
3423 parser::Unwrap<parser::Name>(redOmpObject)}) {
3431 parser::ToUpperCaseLetters(
3435 parser::ToUpperCaseLetters(
3450 void OmpStructureChecker::Enter(const parser::OmpClause::Ordered &x) {
3465 void OmpStructureChecker::Enter(const parser::OmpClause::Shared &x) {
3470 void OmpStructureChecker::Enter(const parser::OmpClause::Private &x) {
3479 void OmpStructureChecker::Enter(const parser::OmpClause::Nowait &x) {
3485 parser::ToUpperCaseLetters(
3487 parser::ToUpperCaseLetters(GetContext().directiveSource.ToString()),
3488 parser::ToUpperCaseLetters(GetContext().directiveSource.ToString()));
3493 const parser::DataRef *dataRef) {
3496 parser::Unwrap<parser::StructureComponent>(dataRef)}) {
3513 const parser::CharBlock &source, const parser::OmpObjectList &objList,
3518 [&](const parser::Designator &designator) {
3520 std::get_if<parser::DataRef>(&designator.u)}) {
3526 } else if (parser::Unwrap<parser::StructureComponent>(
3528 parser::Unwrap<parser::ArrayElement>(ompObject)) {
3546 [&](const parser::Name &name) {},
3552 void OmpStructureChecker::Enter(const parser::OmpClause::Firstprivate &x) {
3595 llvmOmpClause clause, const parser::OmpObjectList &ompObjectList) {
3597 if (const parser::Name *name{parser::Unwrap<parser::Name>(ompObject)}) {
3602 parser::ToUpperCaseLetters(getClauseName(clause).str()));
3614 void OmpStructureChecker::Leave(const parser::OmpAtomicRead &) {
3619 void OmpStructureChecker::Leave(const parser::OmpAtomicWrite &) {
3624 void OmpStructureChecker::Leave(const parser::OmpAtomicUpdate &) {
3631 void OmpStructureChecker::Leave(const parser::OmpAtomic &) {
3644 void OmpStructureChecker::Enter(const parser::OmpClause::Aligned &x) {
3649 if (auto *align{OmpGetUniqueModifier<parser::OmpAlignment>(modifiers)}) {
3659 void OmpStructureChecker::Enter(const parser::OmpClause::Defaultmap &x) {
3662 using ImplicitBehavior = parser::OmpDefaultmapClause::ImplicitBehavior;
3668 parser::ToUpperCaseLetters(
3669 parser::OmpDefaultmapClause::EnumToString(behavior)),
3680 OmpGetUniqueModifier<parser::OmpVariableCategory>(modifiers)};
3682 using VariableCategory = parser::OmpVariableCategory;
3694 parser::ToUpperCaseLetters(VariableCategory::EnumToString(category)),
3700 void OmpStructureChecker::Enter(const parser::OmpClause::If &x) {
3730 if (auto *dnm{OmpGetUniqueModifier<parser::OmpDirectiveNameModifier>(
3733 std::string subName{parser::ToUpperCaseLetters(
3735 std::string dirName{parser::ToUpperCaseLetters(
3738 parser::CharBlock modifierSource{OmpGetModifierSource(modifiers, dnm)};
3739 auto desc{OmpGetDescriptor<parser::OmpDirectiveNameModifier>()};
3782 void OmpStructureChecker::Enter(const parser::OmpClause::Linear &x) {
3786 parser::CharBlock clauseSource{GetContext().clauseSource};
3787 const parser::OmpLinearModifier *linearMod{nullptr};
3790 auto &objects{std::get<parser::OmpObjectList>(x.v.t)};
3794 auto CheckIntegerNoRef{[&](const Symbol *symbol, parser::CharBlock source) {
3796 auto &desc{OmpGetDescriptor<parser::OmpLinearModifier>()};
3805 linearMod = OmpGetUniqueModifier<parser::OmpLinearModifier>(modifiers);
3815 auto &desc{OmpGetDescriptor<parser::OmpLinearModifier>()};
3817 if (linearMod->v != parser::OmpLinearModifier::Value::Ref) {
3827 if (linearMod->v == parser::OmpLinearModifier::Value::Ref ||
3828 linearMod->v == parser::OmpLinearModifier::Value::Uval) {
3848 const auto &orderedClause{std::get<parser::OmpClause::Ordered>(clause->u)};
3879 const parser::OmpMapType::Value &type,
3880 const std::list<parser::OmpMapType::Value> &allowedMapTypeList) {
3885 [&](const parser::OmpMapType::Value &mapType) {
3886 commaSeparatedMapTypes.append(parser::ToUpperCaseLetters(
3887 parser::OmpMapType::EnumToString(mapType)));
3897 void OmpStructureChecker::Enter(const parser::OmpClause::Map &x) {
3911 if (auto *iter{OmpGetUniqueModifier<parser::OmpIterator>(modifiers)}) {
3914 if (auto *type{OmpGetUniqueModifier<parser::OmpMapType>(modifiers)}) {
3915 using Value = parser::OmpMapType::Value;
3940 OmpGetRepeatableModifier<parser::OmpMapTypeModifier>(modifiers)};
3944 const parser::OmpMapTypeModifier *pa = *a;
3945 const parser::OmpMapTypeModifier *pb = *b;
3952 parser::ToUpperCaseLetters(
3953 parser::OmpMapTypeModifier::EnumToString((**maybeIter)->v)));
3957 void OmpStructureChecker::Enter(const parser::OmpClause::Schedule &x) {
3959 const parser::OmpScheduleClause &scheduleClause = x.v;
3968 auto kind{std::get<parser::OmpScheduleClause::Kind>(scheduleClause.t)};
3970 std::get<std::optional<parser::ScalarIntExpr>>(scheduleClause.t)};
3972 if (kind == parser::OmpScheduleClause::Kind::Runtime ||
3973 kind == parser::OmpScheduleClause::Kind::Auto) {
3977 parser::ToUpperCaseLetters(
3978 parser::OmpScheduleClause::EnumToString(kind)));
3980 if (const auto &chunkExpr{std::get<std::optional<parser::ScalarIntExpr>>(
3988 OmpGetUniqueModifier<parser::OmpOrderingModifier>(modifiers)};
3990 ordering->v == parser::OmpOrderingModifier::Value::Nonmonotonic) {
3991 if (kind != parser::OmpScheduleClause::Kind::Dynamic &&
3992 kind != parser::OmpScheduleClause::Kind::Guided) {
4001 void OmpStructureChecker::Enter(const parser::OmpClause::Device &x) {
4003 const parser::OmpDeviceClause &deviceClause{x.v};
4004 const auto &device{std::get<parser::ScalarIntExpr>(deviceClause.t)};
4014 OmpGetUniqueModifier<parser::OmpDeviceModifier>(modifiers)}) {
4015 using Value = parser::OmpDeviceModifier::Value;
4017 auto name{OmpGetDescriptor<parser::OmpDeviceModifier>().name};
4020 name.str(), parser::ToUpperCaseLetters(getDirectiveName(dir)));
4026 void OmpStructureChecker::Enter(const parser::OmpClause::Depend &x) {
4031 auto *doaDep{std::get_if<parser::OmpDoacross>(&x.v.u)};
4032 auto *taskDep{std::get_if<parser::OmpDependClause::TaskDep>(&x.v.u)};
4052 parser::OmpTaskDependenceType::Value::Depobj;
4067 parser::ToUpperCaseLetters(getDirectiveName(dir)));
4071 auto &objList{std::get<parser::OmpObjectList>(taskDep->t)};
4082 if (const auto *name{std::get_if<parser::Name>(&object.u)}) {
4087 } else if (auto *designator{std::get_if<parser::Designator>(&object.u)}) {
4088 if (auto *dataRef{std::get_if<parser::DataRef>(&designator->u)}) {
4091 std::get_if<common::Indirection<parser::ArrayElement>>(
4102 if (OmpGetUniqueModifier<parser::OmpIterator>(modifiers)) {
4112 void OmpStructureChecker::Enter(const parser::OmpClause::Doacross &x) {
4117 void OmpStructureChecker::CheckDoacross(const parser::OmpDoacross &doa) {
4118 if (std::holds_alternative<parser::OmpDoacross::Source>(doa.u)) {
4127 auto &sink{std::get<parser::OmpDoacross::Sink>(doa.u)};
4128 const std::list<parser::OmpIteration> &vec{sink.v.v};
4132 using Iterator = std::list<parser::OmpIteration>::const_iterator;
4134 auto namea{std::get<parser::Name>(a->t)};
4135 auto nameb{std::get<parser::Name>(b->t)};
4144 auto name{std::get<parser::Name>((*maybeIter)->t)};
4154 auto GetLoopDirective{[](const parser::OpenMPLoopConstruct &x) {
4155 auto &begin{std::get<parser::OmpBeginLoopDirective>(x.t)};
4156 return std::get<parser::OmpLoopDirective>(begin.t).v;
4158 auto GetLoopClauses{[](const parser::OpenMPLoopConstruct &x)
4159 -> const std::list<parser::OmpClause> & {
4160 auto &begin{std::get<parser::OmpBeginLoopDirective>(x.t)};
4161 return std::get<parser::OmpClauseList>(begin.t).v;
4166 if (auto *doc{std::get_if<const parser::DoConstruct *>(&loop)}) {
4169 if (auto *b{std::get_if<parser::LoopControl::Bounds>(&control->u)}) {
4175 auto *loopc{std::get_if<const parser::OpenMPLoopConstruct *>(&loop)};
4179 auto IsOrdered{[](const parser::OmpClause &c) {
4189 for (const parser::OmpIteration &iter : vec) {
4190 auto &name{std::get<parser::Name>(iter.t)};
4207 parser::ToUpperCaseLetters(getClauseName(clause).str()));
4213 void OmpStructureChecker::Enter(const parser::OmpClause::Copyprivate &x) {
4224 parser::ToUpperCaseLetters(
4226 parser::ToUpperCaseLetters(GetContext().directiveSource.ToString()),
4227 parser::ToUpperCaseLetters(GetContext().directiveSource.ToString()));
4231 void OmpStructureChecker::Enter(const parser::OmpClause::Lastprivate &x) {
4234 const auto &objectList{std::get<parser::OmpObjectList>(x.v.t)};
4261 void OmpStructureChecker::Enter(const parser::OmpClause::Copyin &x) {
4271 const parser::OmpObjectList &objects, llvm::omp::Clause clauseId) {
4272 auto CheckComponent{[&](const parser::Designator &designator) {
4273 if (auto *dataRef{std::get_if<parser::DataRef>(&designator.u)}) {
4275 if (auto *comp{parser::Unwrap<parser::StructureComponent>(*dataRef)}) {
4278 parser::ToUpperCaseLetters(getClauseName(clauseId).str()));
4288 [&](const parser::Name &name) {},
4294 void OmpStructureChecker::Enter(const parser::OmpClause::Update &x) {
4299 auto *depType{std::get_if<parser::OmpDependenceType>(&x.v.u)};
4300 auto *taskType{std::get_if<parser::OmpTaskDependenceType>(&x.v.u)};
4320 taskType->v == parser::OmpTaskDependenceType::Value::Depobj;
4332 void OmpStructureChecker::Enter(const parser::OmpClause::UseDevicePtr &x) {
4340 std::get<parser::OmpClause::UseDevicePtr>(clause->u)};
4342 std::list<parser::Name> useDevicePtrNameList;
4344 if (const auto *name{parser::Unwrap<parser::Name>(ompObject)}) {
4361 void OmpStructureChecker::Enter(const parser::OmpClause::UseDeviceAddr &x) {
4370 std::get<parser::OmpClause::UseDeviceAddr>(clause->u)};
4372 std::list<parser::Name> useDeviceAddrNameList;
4374 if (const auto *name{parser::Unwrap<parser::Name>(ompObject)}) {
4385 void OmpStructureChecker::Enter(const parser::OmpClause::IsDevicePtr &x) {
4392 std::get<parser::OmpClause::IsDevicePtr>(clause->u)};
4417 void OmpStructureChecker::Enter(const parser::OmpClause::HasDeviceAddr &x) {
4425 std::get<parser::OmpClause::HasDeviceAddr>(clause->u)};
4427 std::list<parser::Name> hasDeviceAddrNameList;
4429 if (const auto *name{parser::Unwrap<parser::Name>(ompObject)}) {
4438 void OmpStructureChecker::Enter(const parser::OmpClause::Enter &x) {
4440 const parser::OmpObjectList &objList{x.v};
4451 void OmpStructureChecker::Enter(const parser::OmpClause::From &x) {
4461 if (auto *iter{OmpGetUniqueModifier<parser::OmpIterator>(modifiers)}) {
4465 const auto &objList{std::get<parser::OmpObjectList>(x.v.t)};
4478 for (const parser::OmpObject &object : objList.v) {
4484 void OmpStructureChecker::Enter(const parser::OmpClause::To &x) {
4506 if (auto *iter{OmpGetUniqueModifier<parser::OmpIterator>(modifiers)}) {
4510 const auto &objList{std::get<parser::OmpObjectList>(x.v.t)};
4523 for (const parser::OmpObject &object : objList.v) {
4529 void OmpStructureChecker::Enter(const parser::OmpClause::OmpxBare &x) {
4536 parser::ToUpperCaseLetters(getClauseName(llvm::omp::OMPC_ompx_bare)));
4540 void OmpStructureChecker::Enter(const parser::OmpContextSelector &ctxSel) {
4544 void OmpStructureChecker::Leave(const parser::OmpContextSelector &) {
4558 const parser::OmpObject &object) {
4559 if (auto *name{std::get_if<parser::Name>(&object.u)}) {
4561 } else if (auto *desg{std::get_if<parser::Designator>(&object.u)}) {
4567 std::optional<parser::CharBlock> OmpStructureChecker::GetObjectSource(
4568 const parser::OmpObject &object) {
4569 if (auto *name{std::get_if<parser::Name>(&object.u)}) {
4571 } else if (auto *desg{std::get_if<parser::Designator>(&object.u)}) {
4577 void OmpStructureChecker::CheckDependList(const parser::DataRef &d) {
4580 [&](const common::Indirection<parser::ArrayElement> &elem) {
4584 [&](const common::Indirection<parser::StructureComponent> &) {
4591 [&](const common::Indirection<parser::CoindexedNamedObject> &) {
4595 [&](const parser::Name &) {},
4602 const parser::ArrayElement &arrayElement, const parser::Name &name,
4607 std::get_if<parser::SubscriptTriplet>(&subscript.u)}) {
4619 parser::ToUpperCaseLetters(getClauseName(clause).str()));
4646 parser::ToUpperCaseLetters(getClauseName(clauseId).str()));
4658 parser::ToUpperCaseLetters(getClauseName(clause).str()));
4664 const parser::OmpObjectList &objectList, llvm::StringRef clause,
4684 const parser::OmpObjectList &objectList, SymbolSourceMap &symbols) {
4686 if (const auto *name{parser::Unwrap<parser::Name>(ompObject)}) {
4710 parser::ToUpperCaseLetters(getClauseName(clause).str()))
4711 .Attach(std::move(msg->set_severity(parser::Severity::Because)));
4739 parser::ToUpperCaseLetters(getClauseName(currClause).str()),
4748 const parser::Block &block) {
4754 parser::Unwrap<parser::OpenMPConstruct>(*it)}) {
4756 std::get_if<parser::OpenMPBlockConstruct>(&ompConstruct->u)}) {
4758 std::get<parser::OmpBeginBlockDirective>(ompBlockConstruct->t)};
4760 std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
4776 const parser::Block &block, parser::CharBlock source) {
4780 if (parser::Unwrap<parser::AssignmentStmt>(*it) ||
4781 parser::Unwrap<parser::ForallStmt>(*it) ||
4782 parser::Unwrap<parser::ForallConstruct>(*it) ||
4783 parser::Unwrap<parser::WhereStmt>(*it) ||
4784 parser::Unwrap<parser::WhereConstruct>(*it)) {
4785 parser::Walk(*it, ompWorkshareBlockChecker);
4787 parser::Unwrap<parser::OpenMPConstruct>(*it)}) {
4789 std::get_if<parser::OpenMPAtomicConstruct>(&ompConstruct->u)}) {
4792 parser::Walk(*ompAtomicConstruct, ompWorkshareBlockChecker);
4794 std::get_if<parser::OpenMPCriticalConstruct>(
4799 std::get<parser::Block>(ompCriticalConstruct->t)};
4806 std::get_if<parser::OpenMPBlockConstruct>(&ompConstruct->u)}) {
4808 std::get<parser::OmpBeginBlockDirective>(ompBlockConstruct->t)};
4810 std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
4813 std::get_if<parser::OpenMPLoopConstruct>(
4816 std::get<parser::OmpBeginLoopDirective>(ompLoopConstruct->t)};
4818 std::get<parser::OmpLoopDirective>(beginLoopDir.t)};
4821 std::get_if<parser::OpenMPSectionsConstruct>(
4824 std::get<parser::OmpBeginSectionsDirective>(
4827 std::get<parser::OmpSectionsDirective>(beginSectionsDir.t)};
4846 void OmpStructureChecker::CheckIfContiguous(const parser::OmpObject &object) {
4848 const parser::Name *name{GetObjectName(object)};
4859 static const parser::Name *Visit(const common::Indirection<T> &x) {
4862 static const parser::Name *Visit(const parser::Substring &x) {
4863 return Visit(std::get<parser::DataRef>(x.t));
4865 static const parser::Name *Visit(const parser::ArrayElement &x) {
4868 static const parser::Name *Visit(const parser::Designator &x) {
4871 static const parser::Name *Visit(const parser::DataRef &x) {
4874 static const parser::Name *Visit(const parser::OmpObject &x) {
4877 template <typename T> static const parser::Name *Visit(T &&) {
4880 static const parser::Name *Visit(const parser::Name &x) { return &x; }
4884 const parser::Name *OmpStructureChecker::GetObjectName(
4885 const parser::OmpObject &object) {
4889 const parser::OmpObjectList *OmpStructureChecker::GetOmpObjectList(
4890 const parser::OmpClause &clause) {
4893 using MemberObjectListClauses = std::tuple<parser::OmpClause::Copyprivate,
4894 parser::OmpClause::Copyin, parser::OmpClause::Enter,
4895 parser::OmpClause::Firstprivate, parser::OmpClause::Link,
4896 parser::OmpClause::Private, parser::OmpClause::Shared,
4897 parser::OmpClause::UseDevicePtr, parser::OmpClause::UseDeviceAddr>;
4900 using TupleObjectListClauses = std::tuple<parser::OmpClause::Aligned,
4901 parser::OmpClause::Allocate, parser::OmpClause::From,
4902 parser::OmpClause::Lastprivate, parser::OmpClause::Map,
4903 parser::OmpClause::Reduction, parser::OmpClause::To>;
4909 [&](const auto &x) -> const parser::OmpObjectList * {
4915 return &(std::get<parser::OmpObjectList>(x.v.t));
4925 const parser::OmpClause::AtomicDefaultMemOrder &x) {
4929 void OmpStructureChecker::Enter(const parser::OmpClause::DynamicAllocators &x) {
4933 void OmpStructureChecker::Enter(const parser::OmpClause::ReverseOffload &x) {
4937 void OmpStructureChecker::Enter(const parser::OmpClause::UnifiedAddress &x) {
4942 const parser::OmpClause::UnifiedSharedMemory &x) {
4946 void OmpStructureChecker::Enter(const parser::DoConstruct &x) {
4951 void OmpStructureChecker::Leave(const parser::DoConstruct &x) {
4955 auto *doc{std::get_if<const parser::DoConstruct *>(&top)};
4971 parser::ToUpperCaseLetters(getClauseName(clause).str()));