@@ -748,7 +748,9 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitNumGangsClause(
748
748
for (auto *GC : GangClauses) {
749
749
if (cast<OpenACCGangClause>(GC)->hasExprOfKind (OpenACCGangKind::Num)) {
750
750
SemaRef.Diag (Clause.getBeginLoc (),
751
- diag::err_acc_num_arg_conflict_reverse);
751
+ diag::err_acc_num_arg_conflict_reverse)
752
+ << OpenACCClauseKind::NumGangs << OpenACCClauseKind::Gang
753
+ << /* Num argument*/ 1 ;
752
754
SemaRef.Diag (GC->getBeginLoc (), diag::note_acc_previous_clause_here);
753
755
return nullptr ;
754
756
}
@@ -768,6 +770,25 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitNumWorkersClause(
768
770
if (checkAlreadyHasClauseOfKind (SemaRef, ExistingClauses, Clause))
769
771
return nullptr ;
770
772
773
+ // OpenACC 3.3 Section 2.9.2:
774
+ // An argument is allowed only when the 'num_workers' does not appear on the
775
+ // kernels construct.
776
+ if (Clause.getDirectiveKind () == OpenACCDirectiveKind::KernelsLoop) {
777
+ auto WorkerClauses = llvm::make_filter_range (
778
+ ExistingClauses, llvm::IsaPred<OpenACCWorkerClause>);
779
+
780
+ for (auto *WC : WorkerClauses) {
781
+ if (cast<OpenACCWorkerClause>(WC)->hasIntExpr ()) {
782
+ SemaRef.Diag (Clause.getBeginLoc (),
783
+ diag::err_acc_num_arg_conflict_reverse)
784
+ << OpenACCClauseKind::NumWorkers << OpenACCClauseKind::Worker
785
+ << /* num argument*/ 0 ;
786
+ SemaRef.Diag (WC->getBeginLoc (), diag::note_acc_previous_clause_here);
787
+ return nullptr ;
788
+ }
789
+ }
790
+ }
791
+
771
792
assert (Clause.getIntExprs ().size () == 1 &&
772
793
" Invalid number of expressions for NumWorkers" );
773
794
return OpenACCNumWorkersClause::Create (
@@ -1254,74 +1275,107 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitWorkerClause(
1254
1275
if (DiagIfSeqClause (Clause))
1255
1276
return nullptr ;
1256
1277
1257
- // Restrictions only properly implemented on 'loop' constructs, and it is
1258
- // the only construct that can do anything with this, so skip/treat as
1259
- // unimplemented for the combined constructs.
1260
- if (Clause.getDirectiveKind () != OpenACCDirectiveKind::Loop)
1278
+ // Restrictions only properly implemented on 'loop'/'combined' constructs, and
1279
+ // it is the only construct that can do anything with this, so skip/treat as
1280
+ // unimplemented for the routine constructs.
1281
+ if (Clause.getDirectiveKind () != OpenACCDirectiveKind::Loop &&
1282
+ !isOpenACCCombinedDirectiveKind (Clause.getDirectiveKind ()))
1261
1283
return isNotImplemented ();
1262
1284
1263
1285
Expr *IntExpr =
1264
1286
Clause.getNumIntExprs () != 0 ? Clause.getIntExprs ()[0 ] : nullptr ;
1265
1287
1266
1288
if (IntExpr) {
1267
- switch (SemaRef.getActiveComputeConstructInfo ().Kind ) {
1268
- case OpenACCDirectiveKind::Invalid:
1269
- case OpenACCDirectiveKind::Parallel:
1270
- case OpenACCDirectiveKind::Serial:
1271
- DiagIntArgInvalid (SemaRef, IntExpr, OpenACCGangKind::Num,
1272
- OpenACCClauseKind::Worker, Clause.getDirectiveKind (),
1273
- SemaRef.getActiveComputeConstructInfo ().Kind );
1274
- IntExpr = nullptr ;
1275
- break ;
1276
- case OpenACCDirectiveKind::Kernels: {
1277
- const auto *Itr =
1278
- llvm::find_if (SemaRef.getActiveComputeConstructInfo ().Clauses ,
1279
- llvm::IsaPred<OpenACCNumWorkersClause>);
1280
- if (Itr != SemaRef.getActiveComputeConstructInfo ().Clauses .end ()) {
1281
- SemaRef.Diag (IntExpr->getBeginLoc (), diag::err_acc_num_arg_conflict)
1282
- << OpenACCClauseKind::Worker << Clause.getDirectiveKind ()
1283
- << HasAssocKind (Clause.getDirectiveKind (),
1284
- SemaRef.getActiveComputeConstructInfo ().Kind )
1285
- << SemaRef.getActiveComputeConstructInfo ().Kind
1286
- << OpenACCClauseKind::NumWorkers;
1287
- SemaRef.Diag ((*Itr)->getBeginLoc (),
1288
- diag::note_acc_previous_clause_here);
1289
-
1289
+ if (!isOpenACCCombinedDirectiveKind (Clause.getDirectiveKind ())) {
1290
+ switch (SemaRef.getActiveComputeConstructInfo ().Kind ) {
1291
+ case OpenACCDirectiveKind::Invalid:
1292
+ case OpenACCDirectiveKind::ParallelLoop:
1293
+ case OpenACCDirectiveKind::SerialLoop:
1294
+ case OpenACCDirectiveKind::Parallel:
1295
+ case OpenACCDirectiveKind::Serial:
1296
+ DiagIntArgInvalid (SemaRef, IntExpr, OpenACCGangKind::Num,
1297
+ OpenACCClauseKind::Worker, Clause.getDirectiveKind (),
1298
+ SemaRef.getActiveComputeConstructInfo ().Kind );
1290
1299
IntExpr = nullptr ;
1300
+ break ;
1301
+ case OpenACCDirectiveKind::KernelsLoop:
1302
+ case OpenACCDirectiveKind::Kernels: {
1303
+ const auto *Itr =
1304
+ llvm::find_if (SemaRef.getActiveComputeConstructInfo ().Clauses ,
1305
+ llvm::IsaPred<OpenACCNumWorkersClause>);
1306
+ if (Itr != SemaRef.getActiveComputeConstructInfo ().Clauses .end ()) {
1307
+ SemaRef.Diag (IntExpr->getBeginLoc (), diag::err_acc_num_arg_conflict)
1308
+ << OpenACCClauseKind::Worker << Clause.getDirectiveKind ()
1309
+ << HasAssocKind (Clause.getDirectiveKind (),
1310
+ SemaRef.getActiveComputeConstructInfo ().Kind )
1311
+ << SemaRef.getActiveComputeConstructInfo ().Kind
1312
+ << OpenACCClauseKind::NumWorkers;
1313
+ SemaRef.Diag ((*Itr)->getBeginLoc (),
1314
+ diag::note_acc_previous_clause_here);
1315
+
1316
+ IntExpr = nullptr ;
1317
+ }
1318
+ break ;
1319
+ }
1320
+ default :
1321
+ llvm_unreachable (" Non compute construct in active compute construct" );
1322
+ }
1323
+ } else {
1324
+ if (Clause.getDirectiveKind () == OpenACCDirectiveKind::ParallelLoop ||
1325
+ Clause.getDirectiveKind () == OpenACCDirectiveKind::SerialLoop) {
1326
+ DiagIntArgInvalid (SemaRef, IntExpr, OpenACCGangKind::Num,
1327
+ OpenACCClauseKind::Worker, Clause.getDirectiveKind (),
1328
+ SemaRef.getActiveComputeConstructInfo ().Kind );
1329
+ IntExpr = nullptr ;
1330
+ } else {
1331
+ assert (Clause.getDirectiveKind () == OpenACCDirectiveKind::KernelsLoop &&
1332
+ " Unknown combined directive kind?" );
1333
+ const auto *Itr = llvm::find_if (ExistingClauses,
1334
+ llvm::IsaPred<OpenACCNumWorkersClause>);
1335
+ if (Itr != ExistingClauses.end ()) {
1336
+ SemaRef.Diag (IntExpr->getBeginLoc (), diag::err_acc_num_arg_conflict)
1337
+ << OpenACCClauseKind::Worker << Clause.getDirectiveKind ()
1338
+ << HasAssocKind (Clause.getDirectiveKind (),
1339
+ SemaRef.getActiveComputeConstructInfo ().Kind )
1340
+ << SemaRef.getActiveComputeConstructInfo ().Kind
1341
+ << OpenACCClauseKind::NumWorkers;
1342
+ SemaRef.Diag ((*Itr)->getBeginLoc (),
1343
+ diag::note_acc_previous_clause_here);
1344
+
1345
+ IntExpr = nullptr ;
1346
+ }
1291
1347
}
1292
- break ;
1293
- }
1294
- default :
1295
- llvm_unreachable (" Non compute construct in active compute construct" );
1296
1348
}
1297
1349
}
1298
1350
1299
- // OpenACC 3.3 2.9.3: The region of a loop with a 'worker' clause may not
1300
- // contain a loop with a gang or worker clause unless within a nested compute
1301
- // region.
1302
- if (SemaRef.LoopWorkerClauseLoc .isValid ()) {
1303
- // This handles the 'inner loop' diagnostic, but we cannot set that we're on
1304
- // one of these until we get to the end of the construct.
1305
- SemaRef.Diag (Clause.getBeginLoc (), diag::err_acc_clause_in_clause_region)
1306
- << OpenACCClauseKind::Worker << OpenACCClauseKind::Worker
1307
- << /* skip kernels construct info*/ 0 ;
1308
- SemaRef.Diag (SemaRef.LoopWorkerClauseLoc ,
1309
- diag::note_acc_previous_clause_here);
1310
- return nullptr ;
1311
- }
1351
+ if (!isOpenACCCombinedDirectiveKind (Clause.getDirectiveKind ())) {
1352
+ // OpenACC 3.3 2.9.3: The region of a loop with a 'worker' clause may not
1353
+ // contain a loop with a gang or worker clause unless within a nested
1354
+ // compute region.
1355
+ if (SemaRef.LoopWorkerClauseLoc .isValid ()) {
1356
+ // This handles the 'inner loop' diagnostic, but we cannot set that we're
1357
+ // on one of these until we get to the end of the construct.
1358
+ SemaRef.Diag (Clause.getBeginLoc (), diag::err_acc_clause_in_clause_region)
1359
+ << OpenACCClauseKind::Worker << OpenACCClauseKind::Worker
1360
+ << /* skip kernels construct info*/ 0 ;
1361
+ SemaRef.Diag (SemaRef.LoopWorkerClauseLoc ,
1362
+ diag::note_acc_previous_clause_here);
1363
+ return nullptr ;
1364
+ }
1312
1365
1313
- // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1314
- // contain a loop with a gang, worker, or vector clause unless within a nested
1315
- // compute region.
1316
- if (SemaRef.LoopVectorClauseLoc .isValid ()) {
1317
- // This handles the 'inner loop' diagnostic, but we cannot set that we're on
1318
- // one of these until we get to the end of the construct.
1319
- SemaRef.Diag (Clause.getBeginLoc (), diag::err_acc_clause_in_clause_region)
1320
- << OpenACCClauseKind::Worker << OpenACCClauseKind::Vector
1321
- << /* skip kernels construct info*/ 0 ;
1322
- SemaRef.Diag (SemaRef.LoopVectorClauseLoc ,
1323
- diag::note_acc_previous_clause_here);
1324
- return nullptr ;
1366
+ // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1367
+ // contain a loop with a gang, worker, or vector clause unless within a
1368
+ // nested compute region.
1369
+ if (SemaRef.LoopVectorClauseLoc .isValid ()) {
1370
+ // This handles the 'inner loop' diagnostic, but we cannot set that we're
1371
+ // on one of these until we get to the end of the construct.
1372
+ SemaRef.Diag (Clause.getBeginLoc (), diag::err_acc_clause_in_clause_region)
1373
+ << OpenACCClauseKind::Worker << OpenACCClauseKind::Vector
1374
+ << /* skip kernels construct info*/ 0 ;
1375
+ SemaRef.Diag (SemaRef.LoopVectorClauseLoc ,
1376
+ diag::note_acc_previous_clause_here);
1377
+ return nullptr ;
1378
+ }
1325
1379
}
1326
1380
1327
1381
return OpenACCWorkerClause::Create (Ctx, Clause.getBeginLoc (),
0 commit comments