@@ -224,29 +224,23 @@ class SemaOpenACCClauseVisitor {
224224 llvm_unreachable (" didn't return from switch above?" );
225225 }
226226
227- // Routine has a pretty complicated set of rules for how device_type and the
228- // gang, worker, vector, and seq clauses work. So diagnose some of it here.
229- bool CheckValidRoutineGangWorkerVectorSeqNewClause (
230- SemaOpenACC::OpenACCParsedClause &Clause) {
227+ // Helper for the 'routine' checks during 'new' clause addition. Precondition
228+ // is that we already know the new clause is one of the prohbiited ones.
229+ template <typename Pred>
230+ bool
231+ CheckValidRoutineNewClauseHelper (Pred HasPredicate,
232+ SemaOpenACC::OpenACCParsedClause &Clause) {
231233 if (Clause.getDirectiveKind () != OpenACCDirectiveKind::Routine)
232234 return false ;
233235
234- if (Clause.getClauseKind () != OpenACCClauseKind::Gang &&
235- Clause.getClauseKind () != OpenACCClauseKind::Vector &&
236- Clause.getClauseKind () != OpenACCClauseKind::Worker &&
237- Clause.getClauseKind () != OpenACCClauseKind::Seq)
238- return false ;
239- auto ProhibitedPred = llvm::IsaPred<OpenACCGangClause, OpenACCWorkerClause,
240- OpenACCVectorClause, OpenACCSeqClause>;
241-
242236 auto *FirstDeviceType =
243237 llvm::find_if (ExistingClauses, llvm::IsaPred<OpenACCDeviceTypeClause>);
244238
245239 if (FirstDeviceType == ExistingClauses.end ()) {
246240 // If there isn't a device type yet, ANY duplicate is wrong.
247241
248242 auto *ExistingProhibitedClause =
249- llvm::find_if (ExistingClauses, ProhibitedPred );
243+ llvm::find_if (ExistingClauses, HasPredicate );
250244
251245 if (ExistingProhibitedClause == ExistingClauses.end ())
252246 return false ;
@@ -265,8 +259,7 @@ class SemaOpenACCClauseVisitor {
265259 // between this and the previous 'device_type'.
266260
267261 auto *BeforeDeviceType =
268- std::find_if (ExistingClauses.begin (), FirstDeviceType, ProhibitedPred);
269-
262+ std::find_if (ExistingClauses.begin (), FirstDeviceType, HasPredicate);
270263 // If there is one before the device_type (and we know we are after a
271264 // device_type), than this is ill-formed.
272265 if (BeforeDeviceType != FirstDeviceType) {
@@ -294,7 +287,7 @@ class SemaOpenACCClauseVisitor {
294287 auto *LastDeviceType = LastDeviceTypeItr.base () - 1 ;
295288
296289 auto *ExistingProhibitedSinceLastDevice =
297- std::find_if (LastDeviceType, ExistingClauses.end (), ProhibitedPred );
290+ std::find_if (LastDeviceType, ExistingClauses.end (), HasPredicate );
298291
299292 // No prohibited ones since the last device-type.
300293 if (ExistingProhibitedSinceLastDevice == ExistingClauses.end ())
@@ -311,6 +304,35 @@ class SemaOpenACCClauseVisitor {
311304 return true ;
312305 }
313306
307+ // Routine has a pretty complicated set of rules for how device_type and the
308+ // gang, worker, vector, and seq clauses work. So diagnose some of it here.
309+ bool CheckValidRoutineGangWorkerVectorSeqNewClause (
310+ SemaOpenACC::OpenACCParsedClause &Clause) {
311+
312+ if (Clause.getClauseKind () != OpenACCClauseKind::Gang &&
313+ Clause.getClauseKind () != OpenACCClauseKind::Vector &&
314+ Clause.getClauseKind () != OpenACCClauseKind::Worker &&
315+ Clause.getClauseKind () != OpenACCClauseKind::Seq)
316+ return false ;
317+ auto ProhibitedPred = llvm::IsaPred<OpenACCGangClause, OpenACCWorkerClause,
318+ OpenACCVectorClause, OpenACCSeqClause>;
319+
320+ return CheckValidRoutineNewClauseHelper (ProhibitedPred, Clause);
321+ }
322+
323+ // Bind should have similar rules on a routine as gang/worker/vector/seq,
324+ // except there is no 'must have 1' rule, so we can get all the checking done
325+ // here.
326+ bool
327+ CheckValidRoutineBindNewClause (SemaOpenACC::OpenACCParsedClause &Clause) {
328+
329+ if (Clause.getClauseKind () != OpenACCClauseKind::Bind)
330+ return false ;
331+
332+ auto HasBindPred = llvm::IsaPred<OpenACCBindClause>;
333+ return CheckValidRoutineNewClauseHelper (HasBindPred, Clause);
334+ }
335+
314336 // For 'tile' and 'collapse', only allow 1 per 'device_type'.
315337 template <typename TheClauseTy>
316338 bool DisallowSinceLastDeviceType (SemaOpenACC::OpenACCParsedClause &Clause) {
@@ -352,7 +374,8 @@ class SemaOpenACCClauseVisitor {
352374 Clause.getClauseKind (),
353375 Clause.getBeginLoc (), ExistingClauses))
354376 return nullptr ;
355- if (CheckValidRoutineGangWorkerVectorSeqNewClause (Clause))
377+ if (CheckValidRoutineGangWorkerVectorSeqNewClause (Clause) ||
378+ CheckValidRoutineBindNewClause (Clause))
356379 return nullptr ;
357380
358381 switch (Clause.getClauseKind ()) {
0 commit comments