@@ -69,7 +69,12 @@ static constexpr inline AccClauseSet updateOnlyAllowedAfterDeviceTypeClauses{
69
69
70
70
static constexpr inline AccClauseSet routineOnlyAllowedAfterDeviceTypeClauses{
71
71
llvm::acc::Clause::ACCC_bind, llvm::acc::Clause::ACCC_gang,
72
- llvm::acc::Clause::ACCC_vector, llvm::acc::Clause::ACCC_worker};
72
+ llvm::acc::Clause::ACCC_vector, llvm::acc::Clause::ACCC_worker,
73
+ llvm::acc::Clause::ACCC_seq};
74
+
75
+ static constexpr inline AccClauseSet routineMutuallyExclusiveClauses{
76
+ llvm::acc::Clause::ACCC_gang, llvm::acc::Clause::ACCC_worker,
77
+ llvm::acc::Clause::ACCC_vector, llvm::acc::Clause::ACCC_seq};
73
78
74
79
bool AccStructureChecker::CheckAllowedModifier (llvm::acc::Clause clause) {
75
80
if (GetContext ().directive == llvm::acc::ACCD_enter_data ||
@@ -388,7 +393,6 @@ CHECK_SIMPLE_CLAUSE(NoCreate, ACCC_no_create)
388
393
CHECK_SIMPLE_CLAUSE (Nohost, ACCC_nohost)
389
394
CHECK_SIMPLE_CLAUSE (Private, ACCC_private)
390
395
CHECK_SIMPLE_CLAUSE (Read, ACCC_read)
391
- CHECK_SIMPLE_CLAUSE (Seq, ACCC_seq)
392
396
CHECK_SIMPLE_CLAUSE (UseDevice, ACCC_use_device)
393
397
CHECK_SIMPLE_CLAUSE (Wait, ACCC_wait)
394
398
CHECK_SIMPLE_CLAUSE (Write, ACCC_write)
@@ -532,18 +536,40 @@ void AccStructureChecker::Enter(const parser::AccClause::DeviceType &d) {
532
536
.str ()),
533
537
ContextDirectiveAsFortran ());
534
538
}
539
+ ResetCrtGroup ();
540
+ }
541
+
542
+ void AccStructureChecker::Enter (const parser::AccClause::Seq &g) {
543
+ llvm::acc::Clause crtClause = llvm::acc::Clause::ACCC_seq;
544
+ if (GetContext ().directive == llvm::acc::Directive::ACCD_routine) {
545
+ CheckMutuallyExclusivePerGroup (crtClause,
546
+ llvm::acc::Clause::ACCC_device_type, routineMutuallyExclusiveClauses);
547
+ }
548
+ CheckAllowed (crtClause);
535
549
}
536
550
537
551
void AccStructureChecker::Enter (const parser::AccClause::Vector &g) {
538
- CheckAllowed (llvm::acc::Clause::ACCC_vector);
539
- CheckAllowedOncePerGroup (
540
- llvm::acc::Clause::ACCC_vector, llvm::acc::Clause::ACCC_device_type);
552
+ llvm::acc::Clause crtClause = llvm::acc::Clause::ACCC_vector;
553
+ if (GetContext ().directive == llvm::acc::Directive::ACCD_routine) {
554
+ CheckMutuallyExclusivePerGroup (crtClause,
555
+ llvm::acc::Clause::ACCC_device_type, routineMutuallyExclusiveClauses);
556
+ }
557
+ CheckAllowed (crtClause);
558
+ if (GetContext ().directive != llvm::acc::Directive::ACCD_routine) {
559
+ CheckAllowedOncePerGroup (crtClause, llvm::acc::Clause::ACCC_device_type);
560
+ }
541
561
}
542
562
543
563
void AccStructureChecker::Enter (const parser::AccClause::Worker &g) {
544
- CheckAllowed (llvm::acc::Clause::ACCC_worker);
545
- CheckAllowedOncePerGroup (
546
- llvm::acc::Clause::ACCC_worker, llvm::acc::Clause::ACCC_device_type);
564
+ llvm::acc::Clause crtClause = llvm::acc::Clause::ACCC_worker;
565
+ if (GetContext ().directive == llvm::acc::Directive::ACCD_routine) {
566
+ CheckMutuallyExclusivePerGroup (crtClause,
567
+ llvm::acc::Clause::ACCC_device_type, routineMutuallyExclusiveClauses);
568
+ }
569
+ CheckAllowed (crtClause);
570
+ if (GetContext ().directive != llvm::acc::Directive::ACCD_routine) {
571
+ CheckAllowedOncePerGroup (crtClause, llvm::acc::Clause::ACCC_device_type);
572
+ }
547
573
}
548
574
549
575
void AccStructureChecker::Enter (const parser::AccClause::Tile &g) {
@@ -553,24 +579,32 @@ void AccStructureChecker::Enter(const parser::AccClause::Tile &g) {
553
579
}
554
580
555
581
void AccStructureChecker::Enter (const parser::AccClause::Gang &g) {
556
- CheckAllowed (llvm::acc::Clause::ACCC_gang);
557
- CheckAllowedOncePerGroup (
558
- llvm::acc::Clause::ACCC_gang, llvm::acc::Clause::ACCC_device_type);
582
+ llvm::acc::Clause crtClause = llvm::acc::Clause::ACCC_gang;
583
+ if (GetContext ().directive == llvm::acc::Directive::ACCD_routine) {
584
+ CheckMutuallyExclusivePerGroup (crtClause,
585
+ llvm::acc::Clause::ACCC_device_type, routineMutuallyExclusiveClauses);
586
+ }
587
+ CheckAllowed (crtClause);
588
+ if (GetContext ().directive != llvm::acc::Directive::ACCD_routine) {
589
+ CheckAllowedOncePerGroup (crtClause, llvm::acc::Clause::ACCC_device_type);
590
+ }
559
591
560
592
if (g.v ) {
561
593
bool hasNum = false ;
562
594
bool hasDim = false ;
563
595
const Fortran::parser::AccGangArgList &x = *g.v ;
564
596
for (const Fortran::parser::AccGangArg &gangArg : x.v ) {
565
- if (std::get_if<Fortran::parser::AccGangArg::Num>(&gangArg.u ))
597
+ if (std::get_if<Fortran::parser::AccGangArg::Num>(&gangArg.u )) {
566
598
hasNum = true ;
567
- else if (std::get_if<Fortran::parser::AccGangArg::Dim>(&gangArg.u ))
599
+ } else if (std::get_if<Fortran::parser::AccGangArg::Dim>(&gangArg.u )) {
568
600
hasDim = true ;
601
+ }
569
602
}
570
603
571
- if (hasDim && hasNum)
604
+ if (hasDim && hasNum) {
572
605
context_.Say (GetContext ().clauseSource ,
573
606
" The num argument is not allowed when dim is specified" _err_en_US);
607
+ }
574
608
}
575
609
}
576
610
0 commit comments