@@ -389,6 +389,18 @@ bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind,
389389 return false ;
390390 }
391391 }
392+ case OpenACCClauseKind::Vector: {
393+ switch (DirectiveKind) {
394+ case OpenACCDirectiveKind::Loop:
395+ case OpenACCDirectiveKind::ParallelLoop:
396+ case OpenACCDirectiveKind::SerialLoop:
397+ case OpenACCDirectiveKind::KernelsLoop:
398+ case OpenACCDirectiveKind::Routine:
399+ return true ;
400+ default :
401+ return false ;
402+ }
403+ }
392404 }
393405
394406 default :
@@ -512,14 +524,6 @@ class SemaOpenACCClauseVisitor {
512524
513525 OpenACCClause *Visit (SemaOpenACC::OpenACCParsedClause &Clause) {
514526 switch (Clause.getClauseKind ()) {
515- case OpenACCClauseKind::Vector: {
516- // TODO OpenACC: These are only implemented enough for the 'seq'
517- // diagnostic, otherwise treats itself as unimplemented. When we
518- // implement these, we can remove them from here.
519- DiagIfSeqClause (Clause);
520- return isNotImplemented ();
521- }
522-
523527#define VISIT_CLAUSE (CLAUSE_NAME ) \
524528 case OpenACCClauseKind::CLAUSE_NAME: \
525529 return Visit##CLAUSE_NAME##Clause (Clause);
@@ -1035,6 +1039,97 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitIndependentClause(
10351039 Clause.getEndLoc ());
10361040}
10371041
1042+ OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorClause (
1043+ SemaOpenACC::OpenACCParsedClause &Clause) {
1044+ if (DiagIfSeqClause (Clause))
1045+ return nullptr ;
1046+ // Restrictions only properly implemented on 'loop' constructs, and it is
1047+ // the only construct that can do anything with this, so skip/treat as
1048+ // unimplemented for the combined constructs.
1049+ if (Clause.getDirectiveKind () != OpenACCDirectiveKind::Loop)
1050+ return isNotImplemented ();
1051+
1052+ Expr *IntExpr =
1053+ Clause.getNumIntExprs () != 0 ? Clause.getIntExprs ()[0 ] : nullptr ;
1054+ if (IntExpr) {
1055+ switch (SemaRef.getActiveComputeConstructInfo ().Kind ) {
1056+ case OpenACCDirectiveKind::Invalid:
1057+ case OpenACCDirectiveKind::Parallel:
1058+ // No restriction on when 'parallel' can contain an argument.
1059+ break ;
1060+ case OpenACCDirectiveKind::Serial:
1061+ // GCC disallows this, and there is no real good reason for us to permit
1062+ // it, so disallow until we come up with a use case that makes sense.
1063+ SemaRef.Diag (IntExpr->getBeginLoc (), diag::err_acc_int_arg_invalid)
1064+ << OpenACCClauseKind::Vector << " num" << /* serial=*/ 3 ;
1065+ IntExpr = nullptr ;
1066+ break ;
1067+ case OpenACCDirectiveKind::Kernels: {
1068+ const auto *Itr =
1069+ llvm::find_if (SemaRef.getActiveComputeConstructInfo ().Clauses ,
1070+ llvm::IsaPred<OpenACCVectorLengthClause>);
1071+ if (Itr != SemaRef.getActiveComputeConstructInfo ().Clauses .end ()) {
1072+ SemaRef.Diag (IntExpr->getBeginLoc (), diag::err_acc_num_arg_conflict)
1073+ << OpenACCClauseKind::Vector << /* vector_length=*/ 2 ;
1074+ SemaRef.Diag ((*Itr)->getBeginLoc (),
1075+ diag::note_acc_previous_clause_here);
1076+
1077+ IntExpr = nullptr ;
1078+ }
1079+ break ;
1080+ }
1081+ default :
1082+ llvm_unreachable (" Non compute construct in active compute construct" );
1083+ }
1084+ }
1085+
1086+ // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
1087+ // construct, the gang clause behaves as follows. ... The region of a loop
1088+ // with a gang clause may not contain another loop with a gang clause unless
1089+ // within a nested compute region.
1090+ if (SemaRef.LoopGangClauseOnKernelLoc .isValid ()) {
1091+ // This handles the 'inner loop' diagnostic, but we cannot set that we're on
1092+ // one of these until we get to the end of the construct.
1093+ SemaRef.Diag (Clause.getBeginLoc (), diag::err_acc_clause_in_clause_region)
1094+ << OpenACCClauseKind::Vector << OpenACCClauseKind::Gang
1095+ << /* skip kernels construct info*/ 0 ;
1096+ SemaRef.Diag (SemaRef.LoopGangClauseOnKernelLoc ,
1097+ diag::note_acc_previous_clause_here);
1098+ return nullptr ;
1099+ }
1100+
1101+ // OpenACC 3.3 2.9.3: The region of a loop with a 'worker' clause may not
1102+ // contain a loop with a gang or worker clause unless within a nested compute
1103+ // region.
1104+ if (SemaRef.LoopWorkerClauseLoc .isValid ()) {
1105+ // This handles the 'inner loop' diagnostic, but we cannot set that we're on
1106+ // one of these until we get to the end of the construct.
1107+ SemaRef.Diag (Clause.getBeginLoc (), diag::err_acc_clause_in_clause_region)
1108+ << OpenACCClauseKind::Vector << OpenACCClauseKind::Worker
1109+ << /* skip kernels construct info*/ 0 ;
1110+ SemaRef.Diag (SemaRef.LoopWorkerClauseLoc ,
1111+ diag::note_acc_previous_clause_here);
1112+ return nullptr ;
1113+ }
1114+ // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1115+ // contain a loop with a gang, worker, or vector clause unless within a nested
1116+ // compute region.
1117+ if (SemaRef.LoopVectorClauseLoc .isValid ()) {
1118+ // This handles the 'inner loop' diagnostic, but we cannot set that we're on
1119+ // one of these until we get to the end of the construct.
1120+ SemaRef.Diag (Clause.getBeginLoc (), diag::err_acc_clause_in_clause_region)
1121+ << OpenACCClauseKind::Vector << OpenACCClauseKind::Vector
1122+ << /* skip kernels construct info*/ 0 ;
1123+ SemaRef.Diag (SemaRef.LoopVectorClauseLoc ,
1124+ diag::note_acc_previous_clause_here);
1125+ return nullptr ;
1126+ }
1127+
1128+ return OpenACCVectorClause::Create (Ctx, Clause.getBeginLoc (),
1129+ Clause.getLParenLoc (), IntExpr,
1130+ Clause.getEndLoc ());
1131+ }
1132+
10381133OpenACCClause *SemaOpenACCClauseVisitor::VisitWorkerClause (
10391134 SemaOpenACC::OpenACCParsedClause &Clause) {
10401135 if (DiagIfSeqClause (Clause))
@@ -1099,6 +1194,20 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitWorkerClause(
10991194 return nullptr ;
11001195 }
11011196
1197+ // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1198+ // contain a loop with a gang, worker, or vector clause unless within a nested
1199+ // compute region.
1200+ if (SemaRef.LoopVectorClauseLoc .isValid ()) {
1201+ // This handles the 'inner loop' diagnostic, but we cannot set that we're on
1202+ // one of these until we get to the end of the construct.
1203+ SemaRef.Diag (Clause.getBeginLoc (), diag::err_acc_clause_in_clause_region)
1204+ << OpenACCClauseKind::Worker << OpenACCClauseKind::Vector
1205+ << /* skip kernels construct info*/ 0 ;
1206+ SemaRef.Diag (SemaRef.LoopVectorClauseLoc ,
1207+ diag::note_acc_previous_clause_here);
1208+ return nullptr ;
1209+ }
1210+
11021211 return OpenACCWorkerClause::Create (Ctx, Clause.getBeginLoc (),
11031212 Clause.getLParenLoc (), IntExpr,
11041213 Clause.getEndLoc ());
@@ -1193,6 +1302,20 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitGangClause(
11931302 return nullptr ;
11941303 }
11951304
1305+ // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1306+ // contain a loop with a gang, worker, or vector clause unless within a nested
1307+ // compute region.
1308+ if (SemaRef.LoopVectorClauseLoc .isValid ()) {
1309+ // This handles the 'inner loop' diagnostic, but we cannot set that we're on
1310+ // one of these until we get to the end of the construct.
1311+ SemaRef.Diag (Clause.getBeginLoc (), diag::err_acc_clause_in_clause_region)
1312+ << OpenACCClauseKind::Gang << OpenACCClauseKind::Vector
1313+ << /* kernels construct info*/ 1 ;
1314+ SemaRef.Diag (SemaRef.LoopVectorClauseLoc ,
1315+ diag::note_acc_previous_clause_here);
1316+ return nullptr ;
1317+ }
1318+
11961319 return OpenACCGangClause::Create (Ctx, Clause.getBeginLoc (),
11971320 Clause.getLParenLoc (), GangKinds, IntExprs,
11981321 Clause.getEndLoc ());
@@ -1313,6 +1436,7 @@ SemaOpenACC::AssociatedStmtRAII::AssociatedStmtRAII(
13131436 : SemaRef(S), OldActiveComputeConstructInfo(S.ActiveComputeConstructInfo),
13141437 DirKind(DK), OldLoopGangClauseOnKernelLoc(S.LoopGangClauseOnKernelLoc),
13151438 OldLoopWorkerClauseLoc(S.LoopWorkerClauseLoc),
1439+ OldLoopVectorClauseLoc(S.LoopVectorClauseLoc),
13161440 LoopRAII(SemaRef, /* PreserveDepth=*/ false ) {
13171441 // Compute constructs end up taking their 'loop'.
13181442 if (DirKind == OpenACCDirectiveKind::Parallel ||
@@ -1330,6 +1454,7 @@ SemaOpenACC::AssociatedStmtRAII::AssociatedStmtRAII(
13301454 // Implement the 'unless within a nested compute region' part.
13311455 SemaRef.LoopGangClauseOnKernelLoc = {};
13321456 SemaRef.LoopWorkerClauseLoc = {};
1457+ SemaRef.LoopVectorClauseLoc = {};
13331458 } else if (DirKind == OpenACCDirectiveKind::Loop) {
13341459 SetCollapseInfoBeforeAssociatedStmt (UnInstClauses, Clauses);
13351460 SetTileInfoBeforeAssociatedStmt (UnInstClauses, Clauses);
@@ -1355,6 +1480,10 @@ SemaOpenACC::AssociatedStmtRAII::AssociatedStmtRAII(
13551480 auto *Itr = llvm::find_if (Clauses, llvm::IsaPred<OpenACCWorkerClause>);
13561481 if (Itr != Clauses.end ())
13571482 SemaRef.LoopWorkerClauseLoc = (*Itr)->getBeginLoc ();
1483+
1484+ auto *Itr2 = llvm::find_if (Clauses, llvm::IsaPred<OpenACCVectorClause>);
1485+ if (Itr2 != Clauses.end ())
1486+ SemaRef.LoopVectorClauseLoc = (*Itr2)->getBeginLoc ();
13581487 }
13591488 }
13601489}
@@ -1429,6 +1558,7 @@ SemaOpenACC::AssociatedStmtRAII::~AssociatedStmtRAII() {
14291558 SemaRef.ActiveComputeConstructInfo = OldActiveComputeConstructInfo;
14301559 SemaRef.LoopGangClauseOnKernelLoc = OldLoopGangClauseOnKernelLoc;
14311560 SemaRef.LoopWorkerClauseLoc = OldLoopWorkerClauseLoc;
1561+ SemaRef.LoopVectorClauseLoc = OldLoopVectorClauseLoc;
14321562
14331563 if (DirKind == OpenACCDirectiveKind::Parallel ||
14341564 DirKind == OpenACCDirectiveKind::Serial ||
0 commit comments