@@ -840,51 +840,36 @@ void OmpStructureChecker::CheckReductionArraySection(
840
840
841
841
void OmpStructureChecker::CheckMultipleAppearanceAcrossContext (
842
842
const parser::OmpObjectList &redObjectList) {
843
- const parser::OmpObjectList *objList{nullptr };
844
843
// TODO: Verify the assumption here that the immediately enclosing region is
845
844
// the parallel region to which the worksharing construct having reduction
846
845
// binds to.
847
846
if (auto *enclosingContext{GetEnclosingDirContext ()}) {
848
847
for (auto it : enclosingContext->clauseInfo ) {
849
848
llvmOmpClause type = it.first ;
850
849
const auto *clause = it.second ;
851
- if (type == llvm::omp::Clause::OMPC_private) {
852
- const auto &pClause{std::get<parser::OmpClause::Private>(clause->u )};
853
- objList = &pClause.v ;
854
- } else if (type == llvm::omp::Clause::OMPC_firstprivate) {
855
- const auto &fpClause{
856
- std::get<parser::OmpClause::Firstprivate>(clause->u )};
857
- objList = &fpClause.v ;
858
- } else if (type == llvm::omp::Clause::OMPC_lastprivate) {
859
- const auto &lpClause{
860
- std::get<parser::OmpClause::Lastprivate>(clause->u )};
861
- objList = &lpClause.v ;
862
- } else if (type == llvm::omp::Clause::OMPC_reduction) {
863
- const auto &rClause{std::get<parser::OmpClause::Reduction>(clause->u )};
864
- const auto &olist{std::get<1 >(rClause.v .t )};
865
- objList = &olist;
866
- }
867
- if (objList) {
868
- for (const auto &ompObject : objList->v ) {
869
- if (const auto *name{parser::Unwrap<parser::Name>(ompObject)}) {
870
- if (const auto *symbol{name->symbol }) {
871
- for (const auto &redOmpObject : redObjectList.v ) {
872
- if (const auto *rname{
873
- parser::Unwrap<parser::Name>(redOmpObject)}) {
874
- if (const auto *rsymbol{rname->symbol }) {
875
- if (rsymbol->name () == symbol->name ()) {
876
- context_.Say (GetContext ().clauseSource ,
877
- " %s variable '%s' is %s in outer context must"
878
- " be shared in the parallel regions to which any"
879
- " of the worksharing regions arising from the "
880
- " worksharing"
881
- " construct bind." _err_en_US,
882
- parser::ToUpperCaseLetters (
883
- getClauseName (llvm::omp::Clause::OMPC_reduction)
884
- .str ()),
885
- symbol->name (),
886
- parser::ToUpperCaseLetters (
887
- getClauseName (type).str ()));
850
+ if (llvm::omp::privateReductionSet.test (type)) {
851
+ if (const auto *objList{GetOmpObjectList (*clause)}) {
852
+ for (const auto &ompObject : objList->v ) {
853
+ if (const auto *name{parser::Unwrap<parser::Name>(ompObject)}) {
854
+ if (const auto *symbol{name->symbol }) {
855
+ for (const auto &redOmpObject : redObjectList.v ) {
856
+ if (const auto *rname{
857
+ parser::Unwrap<parser::Name>(redOmpObject)}) {
858
+ if (const auto *rsymbol{rname->symbol }) {
859
+ if (rsymbol->name () == symbol->name ()) {
860
+ context_.Say (GetContext ().clauseSource ,
861
+ " %s variable '%s' is %s in outer context must"
862
+ " be shared in the parallel regions to which any"
863
+ " of the worksharing regions arising from the "
864
+ " worksharing"
865
+ " construct bind." _err_en_US,
866
+ parser::ToUpperCaseLetters (
867
+ getClauseName (llvm::omp::Clause::OMPC_reduction)
868
+ .str ()),
869
+ symbol->name (),
870
+ parser::ToUpperCaseLetters (
871
+ getClauseName (type).str ()));
872
+ }
888
873
}
889
874
}
890
875
}
@@ -1213,7 +1198,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Lastprivate &x) {
1213
1198
DirectivesClauseTriple dirClauseTriple;
1214
1199
SymbolSourceMap currSymbols;
1215
1200
GetSymbolsInObjectList (x.v , currSymbols);
1216
- CheckDefinableObjects (currSymbols, llvm::omp::Clause::OMPC_lastprivate );
1201
+ CheckDefinableObjects (currSymbols, GetClauseKindForParserClass (x) );
1217
1202
1218
1203
// Check lastprivate variables in worksharing constructs
1219
1204
dirClauseTriple.emplace (llvm::omp::Directive::OMPD_do,
@@ -1224,7 +1209,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Lastprivate &x) {
1224
1209
llvm::omp::Directive::OMPD_parallel, llvm::omp::privateReductionSet));
1225
1210
1226
1211
CheckPrivateSymbolsInOuterCxt (
1227
- currSymbols, dirClauseTriple, llvm::omp::Clause::OMPC_lastprivate );
1212
+ currSymbols, dirClauseTriple, GetClauseKindForParserClass (x) );
1228
1213
}
1229
1214
1230
1215
llvm::StringRef OmpStructureChecker::getClauseName (llvm::omp::Clause clause) {
@@ -1368,40 +1353,11 @@ void OmpStructureChecker::CheckPrivateSymbolsInOuterCxt(
1368
1353
if (auto *enclosingContext{GetEnclosingContextWithDir (enclosingDir)}) {
1369
1354
for (auto it{enclosingContext->clauseInfo .begin ()};
1370
1355
it != enclosingContext->clauseInfo .end (); ++it) {
1371
- // TODO: Replace the hard-coded clause names by using autogen checks or
1372
- // a function which maps parser::OmpClause::<name> to the corresponding
1373
- // llvm::omp::Clause::OMPC_<name>
1374
- std::visit (common::visitors{
1375
- [&](const parser::OmpClause::Private &x) {
1376
- if (enclosingClauseSet.test (
1377
- llvm::omp::Clause::OMPC_private)) {
1378
- GetSymbolsInObjectList (x.v , enclosingSymbols);
1379
- }
1380
- },
1381
- [&](const parser::OmpClause::Firstprivate &x) {
1382
- if (enclosingClauseSet.test (
1383
- llvm::omp::Clause::OMPC_firstprivate)) {
1384
- GetSymbolsInObjectList (x.v , enclosingSymbols);
1385
- }
1386
- },
1387
- [&](const parser::OmpClause::Lastprivate &x) {
1388
- if (enclosingClauseSet.test (
1389
- llvm::omp::Clause::OMPC_lastprivate)) {
1390
- GetSymbolsInObjectList (x.v , enclosingSymbols);
1391
- }
1392
- },
1393
- [&](const parser::OmpClause::Reduction &x) {
1394
- if (enclosingClauseSet.test (
1395
- llvm::omp::Clause::OMPC_reduction)) {
1396
- const auto &ompObjectList{
1397
- std::get<parser::OmpObjectList>(x.v .t )};
1398
- GetSymbolsInObjectList (
1399
- ompObjectList, enclosingSymbols);
1400
- }
1401
- },
1402
- [&](const auto &) {},
1403
- },
1404
- it->second ->u );
1356
+ if (enclosingClauseSet.test (it->first )) {
1357
+ if (const auto *ompObjectList{GetOmpObjectList (*it->second )}) {
1358
+ GetSymbolsInObjectList (*ompObjectList, enclosingSymbols);
1359
+ }
1360
+ }
1405
1361
}
1406
1362
1407
1363
// Check if the symbols in current context are private in outer context
@@ -1497,4 +1453,37 @@ void OmpStructureChecker::CheckWorkshareBlockStmts(
1497
1453
}
1498
1454
}
1499
1455
1456
+ const parser::OmpObjectList *OmpStructureChecker::GetOmpObjectList (
1457
+ const parser::OmpClause &clause) {
1458
+
1459
+ // Clauses with OmpObjectList as its data member
1460
+ using MemberObjectListClauses = std::tuple<parser::OmpClause::Copyprivate,
1461
+ parser::OmpClause::Copyin, parser::OmpClause::Firstprivate,
1462
+ parser::OmpClause::From, parser::OmpClause::Lastprivate,
1463
+ parser::OmpClause::Link, parser::OmpClause::Private,
1464
+ parser::OmpClause::Shared, parser::OmpClause::To>;
1465
+
1466
+ // Clauses with OmpObjectList in the tuple
1467
+ using TupleObjectListClauses = std::tuple<parser::OmpClause::Allocate,
1468
+ parser::OmpClause::Map, parser::OmpClause::Reduction>;
1469
+
1470
+ // TODO:: Generate the tuples using TableGen.
1471
+ // Handle other constructs with OmpObjectList such as OpenMPThreadprivate.
1472
+ return std::visit (
1473
+ common::visitors{
1474
+ [&](const auto &x) -> const parser::OmpObjectList * {
1475
+ using Ty = std::decay_t <decltype (x)>;
1476
+ if constexpr (common::HasMember<Ty, MemberObjectListClauses>) {
1477
+ return &x.v ;
1478
+ } else if constexpr (common::HasMember<Ty,
1479
+ TupleObjectListClauses>) {
1480
+ return &(std::get<parser::OmpObjectList>(x.v .t ));
1481
+ } else {
1482
+ return nullptr ;
1483
+ }
1484
+ },
1485
+ },
1486
+ clause.u );
1487
+ }
1488
+
1500
1489
} // namespace Fortran::semantics
0 commit comments