clang: lib/Sema/SemaOpenACCClause.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
18
19using namespace clang;
20
21namespace {
24 switch (ClauseKind) {
25
26
27 case OpenACCClauseKind::Default:
28 switch (DirectiveKind) {
29 case OpenACCDirectiveKind::Parallel:
30 case OpenACCDirectiveKind::Serial:
31 case OpenACCDirectiveKind::Kernels:
32 case OpenACCDirectiveKind::ParallelLoop:
33 case OpenACCDirectiveKind::SerialLoop:
34 case OpenACCDirectiveKind::KernelsLoop:
35 case OpenACCDirectiveKind::Data:
36 return true;
37 default:
38 return false;
39 }
40 case OpenACCClauseKind::If:
41 switch (DirectiveKind) {
42 case OpenACCDirectiveKind::Parallel:
43 case OpenACCDirectiveKind::Serial:
44 case OpenACCDirectiveKind::Kernels:
45 case OpenACCDirectiveKind::Data:
46 case OpenACCDirectiveKind::EnterData:
47 case OpenACCDirectiveKind::ExitData:
48 case OpenACCDirectiveKind::HostData:
49 case OpenACCDirectiveKind::Init:
50 case OpenACCDirectiveKind::Shutdown:
51 case OpenACCDirectiveKind::Set:
52 case OpenACCDirectiveKind::Update:
53 case OpenACCDirectiveKind::Wait:
54 case OpenACCDirectiveKind::ParallelLoop:
55 case OpenACCDirectiveKind::SerialLoop:
56 case OpenACCDirectiveKind::KernelsLoop:
57 return true;
58 default:
59 return false;
60 }
61 case OpenACCClauseKind::Self:
62 switch (DirectiveKind) {
63 case OpenACCDirectiveKind::Parallel:
64 case OpenACCDirectiveKind::Serial:
65 case OpenACCDirectiveKind::Kernels:
66 case OpenACCDirectiveKind::Update:
67 case OpenACCDirectiveKind::ParallelLoop:
68 case OpenACCDirectiveKind::SerialLoop:
69 case OpenACCDirectiveKind::KernelsLoop:
70 return true;
71 default:
72 return false;
73 }
74 case OpenACCClauseKind::NumGangs:
75 case OpenACCClauseKind::NumWorkers:
76 case OpenACCClauseKind::VectorLength:
77 switch (DirectiveKind) {
78 case OpenACCDirectiveKind::Parallel:
79 case OpenACCDirectiveKind::Kernels:
80 case OpenACCDirectiveKind::ParallelLoop:
81 case OpenACCDirectiveKind::KernelsLoop:
82 return true;
83 default:
84 return false;
85 }
86 case OpenACCClauseKind::FirstPrivate:
87 switch (DirectiveKind) {
88 case OpenACCDirectiveKind::Parallel:
89 case OpenACCDirectiveKind::Serial:
90 case OpenACCDirectiveKind::ParallelLoop:
91 case OpenACCDirectiveKind::SerialLoop:
92 return true;
93 default:
94 return false;
95 }
96 case OpenACCClauseKind::Private:
97 switch (DirectiveKind) {
98 case OpenACCDirectiveKind::Parallel:
99 case OpenACCDirectiveKind::Serial:
100 case OpenACCDirectiveKind::Loop:
101 case OpenACCDirectiveKind::ParallelLoop:
102 case OpenACCDirectiveKind::SerialLoop:
103 case OpenACCDirectiveKind::KernelsLoop:
104 return true;
105 default:
106 return false;
107 }
108 case OpenACCClauseKind::NoCreate:
109 switch (DirectiveKind) {
110 case OpenACCDirectiveKind::Parallel:
111 case OpenACCDirectiveKind::Serial:
112 case OpenACCDirectiveKind::Kernels:
113 case OpenACCDirectiveKind::Data:
114 case OpenACCDirectiveKind::ParallelLoop:
115 case OpenACCDirectiveKind::SerialLoop:
116 case OpenACCDirectiveKind::KernelsLoop:
117 return true;
118 default:
119 return false;
120 }
121 case OpenACCClauseKind::Present:
122 switch (DirectiveKind) {
123 case OpenACCDirectiveKind::Parallel:
124 case OpenACCDirectiveKind::Serial:
125 case OpenACCDirectiveKind::Kernels:
126 case OpenACCDirectiveKind::Data:
127 case OpenACCDirectiveKind::Declare:
128 case OpenACCDirectiveKind::ParallelLoop:
129 case OpenACCDirectiveKind::SerialLoop:
130 case OpenACCDirectiveKind::KernelsLoop:
131 return true;
132 default:
133 return false;
134 }
135
136 case OpenACCClauseKind::Copy:
137 case OpenACCClauseKind::PCopy:
138 case OpenACCClauseKind::PresentOrCopy:
139 switch (DirectiveKind) {
140 case OpenACCDirectiveKind::Parallel:
141 case OpenACCDirectiveKind::Serial:
142 case OpenACCDirectiveKind::Kernels:
143 case OpenACCDirectiveKind::Data:
144 case OpenACCDirectiveKind::Declare:
145 case OpenACCDirectiveKind::ParallelLoop:
146 case OpenACCDirectiveKind::SerialLoop:
147 case OpenACCDirectiveKind::KernelsLoop:
148 return true;
149 default:
150 return false;
151 }
152 case OpenACCClauseKind::CopyIn:
153 case OpenACCClauseKind::PCopyIn:
154 case OpenACCClauseKind::PresentOrCopyIn:
155 switch (DirectiveKind) {
156 case OpenACCDirectiveKind::Parallel:
157 case OpenACCDirectiveKind::Serial:
158 case OpenACCDirectiveKind::Kernels:
159 case OpenACCDirectiveKind::Data:
160 case OpenACCDirectiveKind::EnterData:
161 case OpenACCDirectiveKind::Declare:
162 case OpenACCDirectiveKind::ParallelLoop:
163 case OpenACCDirectiveKind::SerialLoop:
164 case OpenACCDirectiveKind::KernelsLoop:
165 return true;
166 default:
167 return false;
168 }
169 case OpenACCClauseKind::CopyOut:
170 case OpenACCClauseKind::PCopyOut:
171 case OpenACCClauseKind::PresentOrCopyOut:
172 switch (DirectiveKind) {
173 case OpenACCDirectiveKind::Parallel:
174 case OpenACCDirectiveKind::Serial:
175 case OpenACCDirectiveKind::Kernels:
176 case OpenACCDirectiveKind::Data:
177 case OpenACCDirectiveKind::ExitData:
178 case OpenACCDirectiveKind::Declare:
179 case OpenACCDirectiveKind::ParallelLoop:
180 case OpenACCDirectiveKind::SerialLoop:
181 case OpenACCDirectiveKind::KernelsLoop:
182 return true;
183 default:
184 return false;
185 }
186 case OpenACCClauseKind::Create:
187 case OpenACCClauseKind::PCreate:
188 case OpenACCClauseKind::PresentOrCreate:
189 switch (DirectiveKind) {
190 case OpenACCDirectiveKind::Parallel:
191 case OpenACCDirectiveKind::Serial:
192 case OpenACCDirectiveKind::Kernels:
193 case OpenACCDirectiveKind::Data:
194 case OpenACCDirectiveKind::EnterData:
195 case OpenACCDirectiveKind::ParallelLoop:
196 case OpenACCDirectiveKind::SerialLoop:
197 case OpenACCDirectiveKind::KernelsLoop:
198 return true;
199 default:
200 return false;
201 }
202
203 case OpenACCClauseKind::Attach:
204 switch (DirectiveKind) {
205 case OpenACCDirectiveKind::Parallel:
206 case OpenACCDirectiveKind::Serial:
207 case OpenACCDirectiveKind::Kernels:
208 case OpenACCDirectiveKind::Data:
209 case OpenACCDirectiveKind::EnterData:
210 case OpenACCDirectiveKind::ParallelLoop:
211 case OpenACCDirectiveKind::SerialLoop:
212 case OpenACCDirectiveKind::KernelsLoop:
213 return true;
214 default:
215 return false;
216 }
217 case OpenACCClauseKind::DevicePtr:
218 switch (DirectiveKind) {
219 case OpenACCDirectiveKind::Parallel:
220 case OpenACCDirectiveKind::Serial:
221 case OpenACCDirectiveKind::Kernels:
222 case OpenACCDirectiveKind::Data:
223 case OpenACCDirectiveKind::Declare:
224 case OpenACCDirectiveKind::ParallelLoop:
225 case OpenACCDirectiveKind::SerialLoop:
226 case OpenACCDirectiveKind::KernelsLoop:
227 return true;
228 default:
229 return false;
230 }
231 case OpenACCClauseKind::Async:
232 switch (DirectiveKind) {
233 case OpenACCDirectiveKind::Parallel:
234 case OpenACCDirectiveKind::Serial:
235 case OpenACCDirectiveKind::Kernels:
236 case OpenACCDirectiveKind::Data:
237 case OpenACCDirectiveKind::EnterData:
238 case OpenACCDirectiveKind::ExitData:
239 case OpenACCDirectiveKind::Set:
240 case OpenACCDirectiveKind::Update:
241 case OpenACCDirectiveKind::Wait:
242 case OpenACCDirectiveKind::ParallelLoop:
243 case OpenACCDirectiveKind::SerialLoop:
244 case OpenACCDirectiveKind::KernelsLoop:
245 return true;
246 default:
247 return false;
248 }
249 case OpenACCClauseKind::Wait:
250 switch (DirectiveKind) {
251 case OpenACCDirectiveKind::Parallel:
252 case OpenACCDirectiveKind::Serial:
253 case OpenACCDirectiveKind::Kernels:
254 case OpenACCDirectiveKind::Data:
255 case OpenACCDirectiveKind::EnterData:
256 case OpenACCDirectiveKind::ExitData:
257 case OpenACCDirectiveKind::Update:
258 case OpenACCDirectiveKind::ParallelLoop:
259 case OpenACCDirectiveKind::SerialLoop:
260 case OpenACCDirectiveKind::KernelsLoop:
261 return true;
262 default:
263 return false;
264 }
265
266 case OpenACCClauseKind::Seq:
267 switch (DirectiveKind) {
268 case OpenACCDirectiveKind::Loop:
269 case OpenACCDirectiveKind::Routine:
270 case OpenACCDirectiveKind::ParallelLoop:
271 case OpenACCDirectiveKind::SerialLoop:
272 case OpenACCDirectiveKind::KernelsLoop:
273 return true;
274 default:
275 return false;
276 }
277
278 case OpenACCClauseKind::Independent:
279 case OpenACCClauseKind::Auto:
280 switch (DirectiveKind) {
281 case OpenACCDirectiveKind::Loop:
282 case OpenACCDirectiveKind::ParallelLoop:
283 case OpenACCDirectiveKind::SerialLoop:
284 case OpenACCDirectiveKind::KernelsLoop:
285 return true;
286 default:
287 return false;
288 }
289
290 case OpenACCClauseKind::Reduction:
291 switch (DirectiveKind) {
292 case OpenACCDirectiveKind::Parallel:
293 case OpenACCDirectiveKind::Serial:
294 case OpenACCDirectiveKind::Loop:
295 case OpenACCDirectiveKind::ParallelLoop:
296 case OpenACCDirectiveKind::SerialLoop:
297 case OpenACCDirectiveKind::KernelsLoop:
298 return true;
299 default:
300 return false;
301 }
302
303 case OpenACCClauseKind::DeviceType:
304 case OpenACCClauseKind::DType:
305 switch (DirectiveKind) {
306 case OpenACCDirectiveKind::Parallel:
307 case OpenACCDirectiveKind::Serial:
308 case OpenACCDirectiveKind::Kernels:
309 case OpenACCDirectiveKind::Data:
310 case OpenACCDirectiveKind::Init:
311 case OpenACCDirectiveKind::Shutdown:
312 case OpenACCDirectiveKind::Set:
313 case OpenACCDirectiveKind::Update:
314 case OpenACCDirectiveKind::Loop:
315 case OpenACCDirectiveKind::Routine:
316 case OpenACCDirectiveKind::ParallelLoop:
317 case OpenACCDirectiveKind::SerialLoop:
318 case OpenACCDirectiveKind::KernelsLoop:
319 return true;
320 default:
321 return false;
322 }
323
324 case OpenACCClauseKind::Collapse: {
325 switch (DirectiveKind) {
326 case OpenACCDirectiveKind::Loop:
327 case OpenACCDirectiveKind::ParallelLoop:
328 case OpenACCDirectiveKind::SerialLoop:
329 case OpenACCDirectiveKind::KernelsLoop:
330 return true;
331 default:
332 return false;
333 }
334 }
335 case OpenACCClauseKind::Tile: {
336 switch (DirectiveKind) {
337 case OpenACCDirectiveKind::Loop:
338 case OpenACCDirectiveKind::ParallelLoop:
339 case OpenACCDirectiveKind::SerialLoop:
340 case OpenACCDirectiveKind::KernelsLoop:
341 return true;
342 default:
343 return false;
344 }
345 }
346
347 case OpenACCClauseKind::Gang: {
348 switch (DirectiveKind) {
349 case OpenACCDirectiveKind::Loop:
350 case OpenACCDirectiveKind::ParallelLoop:
351 case OpenACCDirectiveKind::SerialLoop:
352 case OpenACCDirectiveKind::KernelsLoop:
353 case OpenACCDirectiveKind::Routine:
354 return true;
355 default:
356 return false;
357 }
358 case OpenACCClauseKind::Worker: {
359 switch (DirectiveKind) {
360 case OpenACCDirectiveKind::Loop:
361 case OpenACCDirectiveKind::ParallelLoop:
362 case OpenACCDirectiveKind::SerialLoop:
363 case OpenACCDirectiveKind::KernelsLoop:
364 case OpenACCDirectiveKind::Routine:
365 return true;
366 default:
367 return false;
368 }
369 }
370 case OpenACCClauseKind::Vector: {
371 switch (DirectiveKind) {
372 case OpenACCDirectiveKind::Loop:
373 case OpenACCDirectiveKind::ParallelLoop:
374 case OpenACCDirectiveKind::SerialLoop:
375 case OpenACCDirectiveKind::KernelsLoop:
376 case OpenACCDirectiveKind::Routine:
377 return true;
378 default:
379 return false;
380 }
381 }
382 case OpenACCClauseKind::Finalize: {
383 switch (DirectiveKind) {
384 case OpenACCDirectiveKind::ExitData:
385 return true;
386 default:
387 return false;
388 }
389 }
390 case OpenACCClauseKind::IfPresent: {
391 switch (DirectiveKind) {
392 case OpenACCDirectiveKind::HostData:
393 case OpenACCDirectiveKind::Update:
394 return true;
395 default:
396 return false;
397 }
398 }
399 case OpenACCClauseKind::Delete: {
400 switch (DirectiveKind) {
401 case OpenACCDirectiveKind::ExitData:
402 return true;
403 default:
404 return false;
405 }
406 }
407
408 case OpenACCClauseKind::Detach: {
409 switch (DirectiveKind) {
410 case OpenACCDirectiveKind::ExitData:
411 return true;
412 default:
413 return false;
414 }
415 }
416
417 case OpenACCClauseKind::DeviceNum: {
418 switch (DirectiveKind) {
419 case OpenACCDirectiveKind::Init:
420 case OpenACCDirectiveKind::Shutdown:
421 case OpenACCDirectiveKind::Set:
422 return true;
423 default:
424 return false;
425 }
426 }
427
428 case OpenACCClauseKind::UseDevice: {
429 switch (DirectiveKind) {
430 case OpenACCDirectiveKind::HostData:
431 return true;
432 default:
433 return false;
434 }
435 }
436 case OpenACCClauseKind::DefaultAsync: {
437 switch (DirectiveKind) {
438 case OpenACCDirectiveKind::Set:
439 return true;
440 default:
441 return false;
442 }
443 }
444 case OpenACCClauseKind::Device: {
445 switch (DirectiveKind) {
446 case OpenACCDirectiveKind::Update:
447 return true;
448 default:
449 return false;
450 }
451 }
452 case OpenACCClauseKind::Host: {
453 switch (DirectiveKind) {
454 case OpenACCDirectiveKind::Update:
455 return true;
456 default:
457 return false;
458 }
459 }
460 }
461
462 default:
463
464 return true;
465 }
466 llvm_unreachable("Invalid clause kind");
467}
468
469bool checkAlreadyHasClauseOfKind(
472 const auto *Itr = llvm::find_if(ExistingClauses, [&](const OpenACCClause *C) {
474 });
475 if (Itr != ExistingClauses.end()) {
476 S.Diag(Clause.getBeginLoc(), diag::err_acc_duplicate_clause_disallowed)
478 S.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
479 return true;
480 }
481 return false;
482}
483bool checkValidAfterDeviceType(
486
487
488 if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Routine)
489 return false;
490
491
492
493
494
495
496
497
498 if (NewClause.getClauseKind() == OpenACCClauseKind::DType ||
499 NewClause.getClauseKind() == OpenACCClauseKind::DeviceType)
500 return false;
501
502
503
504
507 case OpenACCClauseKind::Async:
508 case OpenACCClauseKind::Wait:
509 case OpenACCClauseKind::NumGangs:
510 case OpenACCClauseKind::NumWorkers:
511 case OpenACCClauseKind::VectorLength:
512 return false;
513 default:
514 break;
515 }
516 } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Loop) {
517
518
519
521 case OpenACCClauseKind::Collapse:
522 case OpenACCClauseKind::Gang:
523 case OpenACCClauseKind::Worker:
524 case OpenACCClauseKind::Vector:
525 case OpenACCClauseKind::Seq:
526 case OpenACCClauseKind::Independent:
527 case OpenACCClauseKind::Auto:
528 case OpenACCClauseKind::Tile:
529 return false;
530 default:
531 break;
532 }
534
536 case OpenACCClauseKind::Async:
537 case OpenACCClauseKind::Wait:
538 case OpenACCClauseKind::NumGangs:
539 case OpenACCClauseKind::NumWorkers:
540 case OpenACCClauseKind::VectorLength:
541 case OpenACCClauseKind::Collapse:
542 case OpenACCClauseKind::Gang:
543 case OpenACCClauseKind::Worker:
544 case OpenACCClauseKind::Vector:
545 case OpenACCClauseKind::Seq:
546 case OpenACCClauseKind::Independent:
547 case OpenACCClauseKind::Auto:
548 case OpenACCClauseKind::Tile:
549 return false;
550 default:
551 break;
552 }
553 } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Data) {
554
555
557 case OpenACCClauseKind::Async:
558 case OpenACCClauseKind::Wait:
559 return false;
560 default:
561 break;
562 }
563 } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Set ||
564 NewClause.getDirectiveKind() == OpenACCDirectiveKind::Init ||
565 NewClause.getDirectiveKind() == OpenACCDirectiveKind::Shutdown) {
566
567 return false;
568 } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Update) {
569
570
572 case OpenACCClauseKind::Async:
573 case OpenACCClauseKind::Wait:
574 return false;
575 default:
576 break;
577 }
578 }
579 S.Diag(NewClause.getBeginLoc(), diag::err_acc_clause_after_device_type)
581 << NewClause.getDirectiveKind();
582 S.Diag(DeviceTypeClause.getBeginLoc(), diag::note_acc_previous_clause_here);
583 return true;
584}
585
586
587
588
589
591 return DK != OpenACCDirectiveKind::Declare &&
592 DK != OpenACCDirectiveKind::Atomic &&
593 DK != OpenACCDirectiveKind::Routine;
594}
595
596class SemaOpenACCClauseVisitor {
600 bool NotImplemented = false;
601
603 NotImplemented = true;
604 return nullptr;
605 }
606
607
608
609
611 const auto *Itr =
612 llvm::find_if(ExistingClauses, llvm::IsaPred);
613
614 if (Itr != ExistingClauses.end()) {
615 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine)
616 << Clause.getClauseKind() << (*Itr)->getClauseKind()
618 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
619
620 return true;
621 }
622 return false;
623 }
624
625public:
628 : SemaRef(S), Ctx(S.getASTContext()), ExistingClauses(ExistingClauses) {}
629
630
631
632 bool diagNotImplemented() { return NotImplemented; }
633
636#define VISIT_CLAUSE(CLAUSE_NAME) \
637 case OpenACCClauseKind::CLAUSE_NAME: \
638 return Visit##CLAUSE_NAME##Clause(Clause);
639#define CLAUSE_ALIAS(ALIAS, CLAUSE_NAME, DEPRECATED) \
640 case OpenACCClauseKind::ALIAS: \
641 if (DEPRECATED) \
642 SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name) \
643 << Clause.getClauseKind() << OpenACCClauseKind::CLAUSE_NAME; \
644 return Visit##CLAUSE_NAME##Clause(Clause);
645#include "clang/Basic/OpenACCClauses.def"
646 default:
647 return isNotImplemented();
648 }
649 llvm_unreachable("Invalid clause kind");
650 }
651
652#define VISIT_CLAUSE(CLAUSE_NAME) \
653 OpenACCClause *Visit##CLAUSE_NAME##Clause( \
654 SemaOpenACC::OpenACCParsedClause &Clause);
655#include "clang/Basic/OpenACCClauses.def"
656};
657
658OpenACCClause *SemaOpenACCClauseVisitor::VisitDefaultClause(
660
662 return nullptr;
663
664
665
666
667
668 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
669 return nullptr;
670
674}
675
676OpenACCClause *SemaOpenACCClauseVisitor::VisitTileClause(
678
679
680
681
682
683
684 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
685 return nullptr;
686
688
689
692
694 return nullptr;
695
696 NewSizeExprs.push_back(Res.get());
697 }
698
702}
703
704OpenACCClause *SemaOpenACCClauseVisitor::VisitIfClause(
706
707
708
709
710
711
712 if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Init &&
713 Clause.getDirectiveKind() != OpenACCDirectiveKind::Shutdown &&
714 checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
715 return nullptr;
716
717
718
719
720
721
722 if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Update) {
723 const auto *Itr =
724 llvm::find_if(ExistingClauses, llvm::IsaPred);
725 if (Itr != ExistingClauses.end()) {
726 SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict);
727 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
728 }
729 }
730
734}
735
736OpenACCClause *SemaOpenACCClauseVisitor::VisitSelfClause(
738
739
740
741 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
742 return nullptr;
743
744
745
746 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Update)
750
751 const auto *Itr =
752 llvm::find_if(ExistingClauses, llvm::IsaPred);
753 if (Itr != ExistingClauses.end()) {
754 SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict);
755 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
756 }
760}
761
762OpenACCClause *SemaOpenACCClauseVisitor::VisitNumGangsClause(
764
765
766
767 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
768 return nullptr;
769
770
771
772
774 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args)
775 << 0;
776
777 unsigned MaxArgs =
778 (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel ||
779 Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop)
780 ? 3
781 : 1;
782
783
784 if (Clause.getIntExprs().size() > MaxArgs)
785 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args)
788
789
790
791
794 auto *GangClauseItr =
795 llvm::find_if(ExistingClauses, llvm::IsaPred);
796 auto *ReductionClauseItr =
797 llvm::find_if(ExistingClauses, llvm::IsaPred);
798
799 if (GangClauseItr != ExistingClauses.end() &&
800 ReductionClauseItr != ExistingClauses.end()) {
802 diag::err_acc_gang_reduction_numgangs_conflict)
803 << OpenACCClauseKind::Reduction << OpenACCClauseKind::Gang
804 << Clause.getDirectiveKind() << 1;
805 SemaRef.Diag((*ReductionClauseItr)->getBeginLoc(),
806 diag::note_acc_previous_clause_here);
807 SemaRef.Diag((*GangClauseItr)->getBeginLoc(),
808 diag::note_acc_previous_clause_here);
809 return nullptr;
810 }
811 }
812
813
814
815
816 if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel ||
817 Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop) &&
820 llvm::find_if(ExistingClauses, llvm::IsaPred);
821
822 if (Parallel != ExistingClauses.end()) {
824 diag::err_acc_reduction_num_gangs_conflict)
825 << 1 << Clause.getClauseKind()
826 << Clause.getDirectiveKind() << OpenACCClauseKind::Reduction;
827 SemaRef.Diag((*Parallel)->getBeginLoc(),
828 diag::note_acc_previous_clause_here);
829 return nullptr;
830 }
831 }
832
833
834
835
836 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) {
837 auto GangClauses = llvm::make_filter_range(
838 ExistingClauses, llvm::IsaPred);
839
840 for (auto *GC : GangClauses) {
841 if (cast(GC)->hasExprOfKind(OpenACCGangKind::Num)) {
843 diag::err_acc_num_arg_conflict_reverse)
844 << OpenACCClauseKind::NumGangs << OpenACCClauseKind::Gang
845 << 1;
846 SemaRef.Diag(GC->getBeginLoc(), diag::note_acc_previous_clause_here);
847 return nullptr;
848 }
849 }
850 }
851
855}
856
857OpenACCClause *SemaOpenACCClauseVisitor::VisitNumWorkersClause(
859
860
861
862 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
863 return nullptr;
864
865
866
867
868 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) {
869 auto WorkerClauses = llvm::make_filter_range(
870 ExistingClauses, llvm::IsaPred);
871
872 for (auto *WC : WorkerClauses) {
873 if (cast(WC)->hasIntExpr()) {
875 diag::err_acc_num_arg_conflict_reverse)
876 << OpenACCClauseKind::NumWorkers << OpenACCClauseKind::Worker
877 << 0;
878 SemaRef.Diag(WC->getBeginLoc(), diag::note_acc_previous_clause_here);
879 return nullptr;
880 }
881 }
882 }
883
884 assert(Clause.getIntExprs().size() == 1 &&
885 "Invalid number of expressions for NumWorkers");
889}
890
891OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorLengthClause(
893
894
895
896 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
897 return nullptr;
898
899
900
901
902 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) {
903 auto VectorClauses = llvm::make_filter_range(
904 ExistingClauses, llvm::IsaPred);
905
906 for (auto *VC : VectorClauses) {
907 if (cast(VC)->hasIntExpr()) {
909 diag::err_acc_num_arg_conflict_reverse)
910 << OpenACCClauseKind::VectorLength << OpenACCClauseKind::Vector
911 << 0;
912 SemaRef.Diag(VC->getBeginLoc(), diag::note_acc_previous_clause_here);
913 return nullptr;
914 }
915 }
916 }
917
918 assert(Clause.getIntExprs().size() == 1 &&
919 "Invalid number of expressions for NumWorkers");
923}
924
925OpenACCClause *SemaOpenACCClauseVisitor::VisitAsyncClause(
927
928
929
930 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
931 return nullptr;
932
934 "Invalid number of expressions for Async");
939}
940
941OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceNumClause(
943
944
946 return isNotImplemented();
947
948
949
950 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Set &&
951 checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
952 return nullptr;
953
955 "Invalid number of expressions for device_num");
959}
960
961OpenACCClause *SemaOpenACCClauseVisitor::VisitDefaultAsyncClause(
963
964
965 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
966 return nullptr;
967
969 "Invalid number of expressions for default_async");
973}
974
975OpenACCClause *SemaOpenACCClauseVisitor::VisitPrivateClause(
977
978
979
980
984}
985
986OpenACCClause *SemaOpenACCClauseVisitor::VisitFirstPrivateClause(
988
989
990
991
995}
996
997OpenACCClause *SemaOpenACCClauseVisitor::VisitNoCreateClause(
999
1000
1001
1002
1006}
1007
1008OpenACCClause *SemaOpenACCClauseVisitor::VisitPresentClause(
1010
1011
1012
1013
1015 return isNotImplemented();
1016
1017
1018
1019
1023}
1024
1025OpenACCClause *SemaOpenACCClauseVisitor::VisitHostClause(
1027
1028
1029
1030
1034}
1035
1036OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceClause(
1038
1039
1040
1041
1045}
1046
1047OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyClause(
1049
1050
1051
1052
1054 return isNotImplemented();
1055
1056
1057
1058
1062}
1063
1064OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyInClause(
1066
1067
1068
1069
1071 return isNotImplemented();
1072
1073
1074
1075
1079}
1080
1081OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyOutClause(
1083
1084
1085
1086
1088 return isNotImplemented();
1089
1090
1091
1092
1096}
1097
1098OpenACCClause *SemaOpenACCClauseVisitor::VisitCreateClause(
1100
1101
1102
1103
1107}
1108
1109OpenACCClause *SemaOpenACCClauseVisitor::VisitAttachClause(
1111
1112
1114 llvm::erase_if(VarList, [&](Expr *E) {
1116 });
1118 false, false);
1122}
1123
1124OpenACCClause *SemaOpenACCClauseVisitor::VisitDetachClause(
1126
1127
1129 llvm::erase_if(VarList, [&](Expr *E) {
1131 });
1133 false, false);
1137}
1138
1139OpenACCClause *SemaOpenACCClauseVisitor::VisitDeleteClause(
1141
1142
1143
1147}
1148
1149OpenACCClause *SemaOpenACCClauseVisitor::VisitUseDeviceClause(
1151
1152
1156}
1157
1158OpenACCClause *SemaOpenACCClauseVisitor::VisitDevicePtrClause(
1160
1161
1162
1163
1165 return isNotImplemented();
1166
1167
1168
1170 llvm::erase_if(VarList, [&](Expr *E) {
1172 });
1174 false, false);
1175
1179}
1180
1181OpenACCClause *SemaOpenACCClauseVisitor::VisitWaitClause(
1186}
1187
1188OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceTypeClause(
1190
1191 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Routine)
1192 return isNotImplemented();
1193
1194
1195
1196 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Set &&
1197 checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
1198 return nullptr;
1199
1200
1201
1202
1203
1207}
1208
1209OpenACCClause *SemaOpenACCClauseVisitor::VisitAutoClause(
1211
1212
1213 const auto *Itr =
1214 llvm::find_if(ExistingClauses,
1215 llvm::IsaPred<OpenACCIndependentClause, OpenACCSeqClause>);
1216 if (Itr != ExistingClauses.end()) {
1217 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict)
1219 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1220 return nullptr;
1221 }
1222
1225}
1226
1227OpenACCClause *SemaOpenACCClauseVisitor::VisitIndependentClause(
1229
1230
1231 const auto *Itr = llvm::find_if(
1232 ExistingClauses, llvm::IsaPred<OpenACCAutoClause, OpenACCSeqClause>);
1233 if (Itr != ExistingClauses.end()) {
1234 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict)
1236 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1237 return nullptr;
1238 }
1239
1242}
1243
1245 if (isa(E))
1246 return E;
1247 return S.ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Gang,
1249}
1250
1252 return DK == OpenACCDirectiveKind::Loop &&
1253 AssocKind == OpenACCDirectiveKind::Invalid;
1254}
1255
1257 return DK == OpenACCDirectiveKind::Loop &&
1258 AssocKind != OpenACCDirectiveKind::Invalid;
1259}
1260
1265 << GK << CK << IsOrphanLoop(DK, AssocKind) << DK
1266 << HasAssocKind(DK, AssocKind) << AssocKind;
1268}
1273 << TagKind << CK << IsOrphanLoop(DK, AssocKind) << DK
1274 << HasAssocKind(DK, AssocKind) << AssocKind;
1276}
1277
1281 switch (GK) {
1282 case OpenACCGangKind::Static:
1283 return CheckGangStaticExpr(S, E);
1284 case OpenACCGangKind::Num:
1285
1286
1287
1288 return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind);
1289 case OpenACCGangKind::Dim: {
1290
1291
1292
1293
1294 if ()
1297 S.ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Gang,
1299
1301 return Res;
1302
1304 return Res;
1305
1306 std::optionalllvm::APSInt ICE =
1308
1309 if (!ICE || *ICE <= 0 || ICE > 3) {
1311 << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue();
1313 }
1314
1317 }
1318 }
1319 llvm_unreachable("Unknown gang kind in gang parallel check");
1320}
1321
1327 switch (GK) {
1328
1329
1330
1331 case OpenACCGangKind::Dim:
1332 return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind);
1333 case OpenACCGangKind::Num: {
1334
1335
1336
1337
1338
1339
1340
1341
1342
1344 ? ExistingClauses
1345 : S.getActiveComputeConstructInfo().Clauses;
1346
1347 const auto *Itr =
1348 llvm::find_if(Collection, llvm::IsaPred);
1349
1350 if (Itr != Collection.end()) {
1352 << "num" << OpenACCClauseKind::Gang << DK
1353 << HasAssocKind(DK, AssocKind) << AssocKind
1354 << OpenACCClauseKind::NumGangs;
1355
1356 S.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1358 }
1360 }
1361 case OpenACCGangKind::Static:
1362 return CheckGangStaticExpr(S, E);
1363 }
1364 llvm_unreachable("Unknown gang kind in gang kernels check");
1365}
1366
1370 switch (GK) {
1371
1372
1373 case OpenACCGangKind::Dim:
1374 case OpenACCGangKind::Num:
1375 return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind);
1376 case OpenACCGangKind::Static:
1377 return CheckGangStaticExpr(S, E);
1378 }
1379 llvm_unreachable("Unknown gang kind in gang serial check");
1380}
1381
1382OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorClause(
1384 if (DiagIfSeqClause(Clause))
1385 return nullptr;
1386
1387
1388
1389
1391 return isNotImplemented();
1392
1393 Expr *IntExpr =
1395 if (IntExpr) {
1398 case OpenACCDirectiveKind::Invalid:
1399 case OpenACCDirectiveKind::Parallel:
1400
1401 break;
1402 case OpenACCDirectiveKind::Serial:
1403
1404
1405 DiagIntArgInvalid(SemaRef, IntExpr, "length", OpenACCClauseKind::Vector,
1408 IntExpr = nullptr;
1409 break;
1410 case OpenACCDirectiveKind::Kernels: {
1411 const auto *Itr =
1413 llvm::IsaPred);
1415 SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1416 << "length" << OpenACCClauseKind::Vector
1421 << OpenACCClauseKind::VectorLength;
1422 SemaRef.Diag((*Itr)->getBeginLoc(),
1423 diag::note_acc_previous_clause_here);
1424
1425 IntExpr = nullptr;
1426 }
1427 break;
1428 }
1429 default:
1430 llvm_unreachable("Non compute construct in active compute construct");
1431 }
1432 } else {
1433 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::SerialLoop) {
1434 DiagIntArgInvalid(SemaRef, IntExpr, "length", OpenACCClauseKind::Vector,
1437 IntExpr = nullptr;
1439 OpenACCDirectiveKind::KernelsLoop) {
1440 const auto *Itr = llvm::find_if(
1441 ExistingClauses, llvm::IsaPred);
1442 if (Itr != ExistingClauses.end()) {
1443 SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1444 << "length" << OpenACCClauseKind::Vector
1449 << OpenACCClauseKind::VectorLength;
1450 SemaRef.Diag((*Itr)->getBeginLoc(),
1451 diag::note_acc_previous_clause_here);
1452
1453 IntExpr = nullptr;
1454 }
1455 }
1456 }
1457 }
1458
1460
1461
1462
1464
1465
1466 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1467 << OpenACCClauseKind::Vector << OpenACCClauseKind::Vector
1468 << 0;
1470 diag::note_acc_previous_clause_here);
1471 return nullptr;
1472 }
1473 }
1474
1478}
1479
1480OpenACCClause *SemaOpenACCClauseVisitor::VisitWorkerClause(
1482 if (DiagIfSeqClause(Clause))
1483 return nullptr;
1484
1485
1486
1487
1489 return isNotImplemented();
1490
1491 Expr *IntExpr =
1493
1494 if (IntExpr) {
1497 case OpenACCDirectiveKind::Invalid:
1498 case OpenACCDirectiveKind::ParallelLoop:
1499 case OpenACCDirectiveKind::SerialLoop:
1500 case OpenACCDirectiveKind::Parallel:
1501 case OpenACCDirectiveKind::Serial:
1502 DiagIntArgInvalid(SemaRef, IntExpr, OpenACCGangKind::Num,
1505 IntExpr = nullptr;
1506 break;
1507 case OpenACCDirectiveKind::KernelsLoop:
1508 case OpenACCDirectiveKind::Kernels: {
1509 const auto *Itr =
1511 llvm::IsaPred);
1513 SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1514 << "num" << OpenACCClauseKind::Worker << Clause.getDirectiveKind()
1518 << OpenACCClauseKind::NumWorkers;
1519 SemaRef.Diag((*Itr)->getBeginLoc(),
1520 diag::note_acc_previous_clause_here);
1521
1522 IntExpr = nullptr;
1523 }
1524 break;
1525 }
1526 default:
1527 llvm_unreachable("Non compute construct in active compute construct");
1528 }
1529 } else {
1530 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop ||
1531 Clause.getDirectiveKind() == OpenACCDirectiveKind::SerialLoop) {
1532 DiagIntArgInvalid(SemaRef, IntExpr, OpenACCGangKind::Num,
1535 IntExpr = nullptr;
1536 } else {
1537 assert(Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop &&
1538 "Unknown combined directive kind?");
1539 const auto *Itr = llvm::find_if(ExistingClauses,
1540 llvm::IsaPred);
1541 if (Itr != ExistingClauses.end()) {
1542 SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1543 << "num" << OpenACCClauseKind::Worker << Clause.getDirectiveKind()
1547 << OpenACCClauseKind::NumWorkers;
1548 SemaRef.Diag((*Itr)->getBeginLoc(),
1549 diag::note_acc_previous_clause_here);
1550
1551 IntExpr = nullptr;
1552 }
1553 }
1554 }
1555 }
1556
1558
1559
1560
1562
1563
1564 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1565 << OpenACCClauseKind::Worker << OpenACCClauseKind::Worker
1566 << 0;
1568 diag::note_acc_previous_clause_here);
1569 return nullptr;
1570 }
1571
1572
1573
1574
1576
1577
1578 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1579 << OpenACCClauseKind::Worker << OpenACCClauseKind::Vector
1580 << 0;
1582 diag::note_acc_previous_clause_here);
1583 return nullptr;
1584 }
1585 }
1586
1590}
1591
1592OpenACCClause *SemaOpenACCClauseVisitor::VisitGangClause(
1594 if (DiagIfSeqClause(Clause))
1595 return nullptr;
1596
1597
1598
1599
1601 return isNotImplemented();
1602
1603
1604
1605
1606 if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop &&
1608 OpenACCDirectiveKind::Invalid) ||
1610
1611 auto ActiveComputeConstructContainer =
1613 ? ExistingClauses
1615 auto *NumGangsClauseItr = llvm::find_if(
1616 ActiveComputeConstructContainer, llvm::IsaPred);
1617
1618 if (NumGangsClauseItr != ActiveComputeConstructContainer.end() &&
1619 cast(*NumGangsClauseItr)->getIntExprs().size() >
1620 1) {
1621 auto *ReductionClauseItr =
1622 llvm::find_if(ExistingClauses, llvm::IsaPred);
1623
1624 if (ReductionClauseItr != ExistingClauses.end()) {
1626 diag::err_acc_gang_reduction_numgangs_conflict)
1627 << OpenACCClauseKind::Gang << OpenACCClauseKind::Reduction
1630 SemaRef.Diag((*ReductionClauseItr)->getBeginLoc(),
1631 diag::note_acc_previous_clause_here);
1632 SemaRef.Diag((*NumGangsClauseItr)->getBeginLoc(),
1633 diag::note_acc_previous_clause_here);
1634 return nullptr;
1635 }
1636 }
1637 }
1638
1641
1642
1643
1645
1646 for (unsigned I = 0; I < Clause.getIntExprs().size(); ++I) {
1651
1653 continue;
1654
1655
1656
1657 if (ExistingElemLoc[static_cast<unsigned>(GK)].isValid()) {
1658 SemaRef.Diag(ER.get()->getBeginLoc(), diag::err_acc_gang_multiple_elt)
1659 << static_cast<unsigned>(GK);
1660 SemaRef.Diag(ExistingElemLoc[static_cast<unsigned>(GK)],
1661 diag::note_acc_previous_expr_here);
1662 continue;
1663 }
1664
1665 ExistingElemLoc[static_cast<unsigned>(GK)] = ER.get()->getBeginLoc();
1666 GangKinds.push_back(GK);
1667 IntExprs.push_back(ER.get());
1668 }
1669
1671
1672
1673
1674
1676
1677
1678 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1679 << OpenACCClauseKind::Gang << OpenACCClauseKind::Gang
1680 << 1
1683 diag::note_acc_previous_clause_here);
1684 return nullptr;
1685 }
1686
1687
1688
1689
1691
1692
1693 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1694 << OpenACCClauseKind::Gang << OpenACCClauseKind::Worker
1695 << 0;
1697 diag::note_acc_previous_clause_here);
1698 return nullptr;
1699 }
1700
1701
1702
1703
1705
1706
1707 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1708 << OpenACCClauseKind::Gang << OpenACCClauseKind::Vector
1709 << 0;
1711 diag::note_acc_previous_clause_here);
1712 return nullptr;
1713 }
1714 }
1715
1718 GangKinds, IntExprs, Clause.getEndLoc());
1719}
1720
1721OpenACCClause *SemaOpenACCClauseVisitor::VisitFinalizeClause(
1723
1724
1727}
1728
1729OpenACCClause *SemaOpenACCClauseVisitor::VisitIfPresentClause(
1731
1732
1735}
1736
1737OpenACCClause *SemaOpenACCClauseVisitor::VisitSeqClause(
1739
1740
1741
1743 return isNotImplemented();
1744
1745
1746
1747 const auto *Itr =
1748 llvm::find_if(ExistingClauses,
1749 llvm::IsaPred<OpenACCAutoClause, OpenACCIndependentClause>);
1750 if (Itr != ExistingClauses.end()) {
1751 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict)
1753 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1754 return nullptr;
1755 }
1756
1757
1758
1759
1760 Itr = llvm::find_if(ExistingClauses,
1763
1764 if (Itr != ExistingClauses.end()) {
1765 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine)
1766 << Clause.getClauseKind() << (*Itr)->getClauseKind()
1768 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1769 return nullptr;
1770 }
1771
1774}
1775
1776OpenACCClause *SemaOpenACCClauseVisitor::VisitReductionClause(
1778
1779
1780
1781 if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop &&
1783 OpenACCDirectiveKind::Invalid) ||
1785
1786 auto ActiveComputeConstructContainer =
1788 ? ExistingClauses
1790 auto *NumGangsClauseItr = llvm::find_if(
1791 ActiveComputeConstructContainer, llvm::IsaPred);
1792
1793 if (NumGangsClauseItr != ActiveComputeConstructContainer.end() &&
1794 cast(*NumGangsClauseItr)->getIntExprs().size() >
1795 1) {
1796 auto *GangClauseItr =
1797 llvm::find_if(ExistingClauses, llvm::IsaPred);
1798
1799 if (GangClauseItr != ExistingClauses.end()) {
1801 diag::err_acc_gang_reduction_numgangs_conflict)
1802 << OpenACCClauseKind::Reduction << OpenACCClauseKind::Gang
1805 SemaRef.Diag((*GangClauseItr)->getBeginLoc(),
1806 diag::note_acc_previous_clause_here);
1807 SemaRef.Diag((*NumGangsClauseItr)->getBeginLoc(),
1808 diag::note_acc_previous_clause_here);
1809 return nullptr;
1810 }
1811 }
1812 }
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel ||
1835 Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop) {
1836 auto NumGangsClauses = llvm::make_filter_range(
1837 ExistingClauses, llvm::IsaPred);
1838
1839 for (auto *NGC : NumGangsClauses) {
1840 unsigned NumExprs =
1841 cast(NGC)->getIntExprs().size();
1842
1843 if (NumExprs > 1) {
1845 diag::err_acc_reduction_num_gangs_conflict)
1846 << 0 << Clause.getClauseKind()
1847 << Clause.getDirectiveKind() << OpenACCClauseKind::NumGangs;
1848 SemaRef.Diag(NGC->getBeginLoc(), diag::note_acc_previous_clause_here);
1849 return nullptr;
1850 }
1851 }
1852 }
1853
1855
1859
1861 ValidVars.push_back(Res.get());
1862 }
1863
1868}
1869
1870OpenACCClause *SemaOpenACCClauseVisitor::VisitCollapseClause(
1872
1873
1874
1875
1876
1877 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
1878 return nullptr;
1879
1881
1883 return nullptr;
1884
1888}
1889
1890
1891
1892bool areVarsEqual(Expr *VarExpr1, Expr *VarExpr2) {
1895 return false;
1896
1899
1900
1901
1902
1903
1904 if (isa(VarExpr1)) {
1905 auto *Expr2AS = dyn_cast(VarExpr2);
1906 if (!Expr2AS)
1907 return false;
1908
1909 auto *Expr1AS = cast(VarExpr1);
1910
1911 if (!areVarsEqual(Expr1AS->getBase(), Expr2AS->getBase()))
1912 return false;
1913
1914
1915 return true;
1916 }
1917
1918
1919 if (isa(VarExpr1)) {
1920 auto *Expr2AS = dyn_cast(VarExpr2);
1921 if (!Expr2AS)
1922 return false;
1923
1924 auto *Expr1AS = cast(VarExpr1);
1925
1926 if (!areVarsEqual(Expr1AS->getBase(), Expr2AS->getBase()))
1927 return false;
1928
1929
1930
1931
1932 return true;
1933 }
1934
1935
1936 if (isa(VarExpr1)) {
1937 auto *Expr2DRE = dyn_cast(VarExpr2);
1938 if (!Expr2DRE)
1939 return false;
1940
1941 auto *Expr1DRE = cast(VarExpr1);
1942
1943 return Expr1DRE->getDecl()->getMostRecentDecl() ==
1944 Expr2DRE->getDecl()->getMostRecentDecl();
1945 }
1946
1947 llvm_unreachable("Unknown variable type encountered");
1948}
1949}
1950
1955 return nullptr;
1956
1957
1960 Diag(Clause.getBeginLoc(), diag::err_acc_clause_appertainment)
1962 return nullptr;
1963 }
1964
1965 if (const auto *DevTypeClause =
1966 llvm::find_if(ExistingClauses,
1968 return isa(C);
1969 });
1970 DevTypeClause != ExistingClauses.end()) {
1971 if (checkValidAfterDeviceType(
1972 *this, *cast(*DevTypeClause), Clause))
1973 return nullptr;
1974 }
1975
1976 SemaOpenACCClauseVisitor Visitor{*this, ExistingClauses};
1979 "Created wrong clause?");
1980
1981 if (Visitor.diagNotImplemented())
1982 Diag(Clause.getBeginLoc(), diag::warn_acc_clause_unimplemented)
1984
1986
1987}
1988
1989
1990
1991
1992
1993
1994
1995
1998 Expr *VarExpr) {
2000
2001 auto TypeIsValid = [](QualType Ty) {
2002 return Ty->isDependentType() || Ty->isScalarType();
2003 };
2004
2005 if (isa(VarExpr)) {
2006 Expr *ASExpr = VarExpr;
2009
2010 if (!TypeIsValid(EltTy)) {
2011 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_type)
2012 << EltTy << 1;
2014 }
2016 if (!RD->isStruct() && !RD->isClass()) {
2017 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type)
2018 << 0 << VarExpr->getType();
2020 }
2021
2022 if (!RD->isCompleteDefinition()) {
2023 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type)
2024 << 1 << VarExpr->getType();
2026 }
2027 if (const auto *CXXRD = dyn_cast(RD);
2028 CXXRD && !CXXRD->isAggregate()) {
2029 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type)
2030 << 2 << VarExpr->getType();
2032 }
2033
2034 for (FieldDecl *FD : RD->fields()) {
2035 if (!TypeIsValid(FD->getType())) {
2037 diag::err_acc_reduction_composite_member_type);
2038 Diag(FD->getLocation(), diag::note_acc_reduction_composite_member_loc);
2040 }
2041 }
2042 } else if (!TypeIsValid(VarExpr->getType())) {
2043 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_type)
2044 << VarExpr->getType() << 0;
2046 }
2047
2048
2049
2051
2053 if (RClause->getReductionOp() == ReductionOp)
2054 break;
2055
2056 for (Expr *OldVarExpr : RClause->getVarList()) {
2057 if (OldVarExpr->isInstantiationDependent())
2058 continue;
2059
2060 if (areVarsEqual(VarExpr, OldVarExpr)) {
2061 Diag(VarExpr->getExprLoc(), diag::err_reduction_op_mismatch)
2062 << ReductionOp << RClause->getReductionOp();
2063 Diag(OldVarExpr->getExprLoc(), diag::note_acc_previous_clause_here);
2065 }
2066 }
2067 }
2068 }
2069
2070 return VarExpr;
2071}
2072
2074 if (!SizeExpr)
2076
2079 "size argument non integer?");
2080
2081
2083 isa(SizeExpr))
2085
2086 std::optionalllvm::APSInt ICE =
2088
2089
2090
2091 if (!ICE || *ICE <= 0) {
2092 Diag(SizeExpr->getBeginLoc(), diag::err_acc_size_expr_value)
2093 << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue();
2095 }
2096
2099}
2100
2102 if (!LoopCount)
2104
2107 "Loop argument non integer?");
2108
2109
2112
2113 std::optionalllvm::APSInt ICE =
2115
2116
2117
2118
2119 if (!ICE || *ICE <= 0) {
2120 Diag(LoopCount->getBeginLoc(), diag::err_acc_collapse_loop_count)
2121 << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue();
2123 }
2124
2127}
2128
2133
2134
2135
2136
2137 switch (DK) {
2139 return CheckGangParallelExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK,
2140 E);
2142 return CheckGangSerialExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK,
2143 E);
2145 return CheckGangKernelsExpr(*this, ExistingClauses, DK,
2146 ActiveComputeConstructInfo.Kind, GK, E);
2148 switch (ActiveComputeConstructInfo.Kind) {
2152 return CheckGangParallelExpr(*this, DK, ActiveComputeConstructInfo.Kind,
2153 GK, E);
2156 return CheckGangSerialExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK,
2157 E);
2160 return CheckGangKernelsExpr(*this, ExistingClauses, DK,
2161 ActiveComputeConstructInfo.Kind, GK, E);
2162 default:
2163 llvm_unreachable("Non compute construct in active compute construct?");
2164 }
2165 default:
2166
2167
2168 llvm_unreachable("Invalid directive kind for a Gang clause");
2169 }
2170 llvm_unreachable("Compute construct directive not handled?");
2171}
2172
2179
2180
2181
2182 const auto *ReductionItr =
2183 llvm::find_if(ExistingClauses, llvm::IsaPred);
2184
2185 if (ReductionItr != ExistingClauses.end()) {
2186 const auto GangZip = llvm::zip_equal(GangKinds, IntExprs);
2187 const auto GangItr = llvm::find_if(GangZip, [](const auto &Tuple) {
2189 });
2190
2191 if (GangItr != GangZip.end()) {
2192 const Expr *DimExpr = std::get<1>(*GangItr);
2193
2194 assert(
2196 "Improperly formed gang argument");
2197 if (const auto *DimVal = dyn_cast(DimExpr);
2198 DimVal && DimVal->getResultAsAPSInt() > 1) {
2199 Diag(DimVal->getBeginLoc(), diag::err_acc_gang_reduction_conflict)
2200 << 0 << DirKind;
2201 Diag((*ReductionItr)->getBeginLoc(),
2202 diag::note_acc_previous_clause_here);
2203 return nullptr;
2204 }
2205 }
2206 }
2207
2209 GangKinds, IntExprs, EndLoc);
2210}
2211
2219
2220
2221
2222 const auto GangClauses = llvm::make_filter_range(
2223 ExistingClauses, llvm::IsaPred);
2224
2225 for (auto *GC : GangClauses) {
2226 const auto *GangClause = cast(GC);
2227 for (unsigned I = 0; I < GangClause->getNumExprs(); ++I) {
2228 std::pair<OpenACCGangKind, const Expr *> EPair = GangClause->getExpr(I);
2230 continue;
2231
2232 if (const auto *DimVal = dyn_cast(EPair.second);
2233 DimVal && DimVal->getResultAsAPSInt() > 1) {
2234 Diag(BeginLoc, diag::err_acc_gang_reduction_conflict)
2235 << 1 << DirectiveKind;
2236 Diag(GangClause->getBeginLoc(), diag::note_acc_previous_clause_here);
2237 return nullptr;
2238 }
2239 }
2240 }
2241 }
2242
2244 getASTContext(), BeginLoc, LParenLoc, ReductionOp, Vars, EndLoc);
2245 return Ret;
2246}
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines some OpenACC-specific enums and functions.
This file declares semantic analysis for OpenACC constructs and clauses.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
static ConstantExpr * Create(const ASTContext &Context, Expr *E, const APValue &Result)
This represents one expression.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
Represents a member of a struct/union/class.
static OpenACCAsyncClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static OpenACCAttachClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCAutoClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)
This is the base type for all OpenACC Clauses.
OpenACCClauseKind getClauseKind() const
SourceLocation getBeginLoc() const
static OpenACCCollapseClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, bool HasForce, Expr *LoopCount, SourceLocation EndLoc)
static OpenACCCopyClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCCopyInClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsReadOnly, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCCopyOutClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsZero, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCCreateClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsZero, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCDefaultAsyncClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static OpenACCDefaultClause * Create(const ASTContext &C, OpenACCDefaultClauseKind K, SourceLocation BeginLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
static OpenACCDeleteClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCDetachClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCDeviceClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCDeviceNumClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static OpenACCDevicePtrClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
A 'device_type' or 'dtype' clause, takes a list of either an 'asterisk' or an identifier.
static OpenACCDeviceTypeClause * Create(const ASTContext &C, OpenACCClauseKind K, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< DeviceTypeArgument > Archs, SourceLocation EndLoc)
static OpenACCFinalizeClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)
static OpenACCFirstPrivateClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCGangClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< OpenACCGangKind > GangKinds, ArrayRef< Expr * > IntExprs, SourceLocation EndLoc)
static OpenACCHostClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCIfClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *ConditionExpr, SourceLocation EndLoc)
static OpenACCIfPresentClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)
static OpenACCIndependentClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)
static OpenACCNoCreateClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCNumGangsClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > IntExprs, SourceLocation EndLoc)
static OpenACCNumWorkersClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static OpenACCPresentClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCPrivateClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCReductionClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, OpenACCReductionOperator Operator, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCSelfClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *ConditionExpr, SourceLocation EndLoc)
static OpenACCSeqClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)
static OpenACCTileClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > SizeExprs, SourceLocation EndLoc)
static OpenACCUseDeviceClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCVectorClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static OpenACCVectorLengthClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static OpenACCWaitClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef< Expr * > QueueIdExprs, SourceLocation EndLoc)
static OpenACCWorkerClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
A (possibly-)qualified type.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
ASTContext & getASTContext() const
A type to represent all the data for an OpenACC Clause that has been parsed, but not yet created/sema...
ArrayRef< Expr * > getIntExprs()
ArrayRef< Expr * > getQueueIdExprs() const
OpenACCDirectiveKind getDirectiveKind() const
ArrayRef< OpenACCGangKind > getGangKinds() const
OpenACCReductionOperator getReductionOp() const
SourceLocation getEndLoc() const
OpenACCClauseKind getClauseKind() const
const Expr * getConditionExpr() const
SourceLocation getLParenLoc() const
ArrayRef< DeviceTypeArgument > getDeviceTypeArchitectures() const
SourceLocation getBeginLoc() const
SourceLocation getQueuesLoc() const
void setVarListDetails(ArrayRef< Expr * > VarList, bool IsReadOnly, bool IsZero)
Expr * getDevNumExpr() const
ArrayRef< Expr * > getVarList()
unsigned getNumIntExprs() const
Expr * getLoopCount() const
OpenACCDefaultClauseKind getDefaultClauseKind() const
ComputeConstructInfo & getActiveComputeConstructInfo()
SourceLocation LoopWorkerClauseLoc
If there is a current 'active' loop construct with a 'worker' clause on it (on any sort of construct)...
OpenACCClause * ActOnClause(ArrayRef< const OpenACCClause * > ExistingClauses, OpenACCParsedClause &Clause)
Called after parsing an OpenACC Clause so that it can be checked.
bool CheckVarIsPointerType(OpenACCClauseKind ClauseKind, Expr *VarExpr)
Called to check the 'var' type is a variable of pointer type, necessary for 'deviceptr' and 'attach' ...
struct clang::SemaOpenACC::LoopGangOnKernelTy LoopGangClauseOnKernel
ExprResult CheckReductionVar(OpenACCDirectiveKind DirectiveKind, OpenACCReductionOperator ReductionOp, Expr *VarExpr)
Called while semantically analyzing the reduction clause, ensuring the var is the correct kind of ref...
ExprResult CheckCollapseLoopCount(Expr *LoopCount)
Checks the loop depth value for a collapse clause.
OpenACCClause * CheckReductionClause(ArrayRef< const OpenACCClause * > ExistingClauses, OpenACCDirectiveKind DirectiveKind, SourceLocation BeginLoc, SourceLocation LParenLoc, OpenACCReductionOperator ReductionOp, ArrayRef< Expr * > Vars, SourceLocation EndLoc)
SourceLocation LoopVectorClauseLoc
If there is a current 'active' loop construct with a 'vector' clause on it (on any sort of construct)...
ExprResult CheckGangExpr(ArrayRef< const OpenACCClause * > ExistingClauses, OpenACCDirectiveKind DK, OpenACCGangKind GK, Expr *E)
OpenACCClause * CheckGangClause(OpenACCDirectiveKind DirKind, ArrayRef< const OpenACCClause * > ExistingClauses, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< OpenACCGangKind > GangKinds, ArrayRef< Expr * > IntExprs, SourceLocation EndLoc)
ExprResult CheckTileSizeExpr(Expr *SizeExpr)
Checks a single size expr for a tile clause.
ASTContext & getASTContext() const
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getBeginLoc() const LLVM_READONLY
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
The JSON file list parser is used to communicate input to InstallAPI.
bool isOpenACCComputeDirectiveKind(OpenACCDirectiveKind K)
bool isOpenACCCombinedDirectiveKind(OpenACCDirectiveKind K)
OpenACCClauseKind
Represents the kind of an OpenACC clause.
@ Invalid
Represents an invalid clause, for the purposes of parsing.
@ Result
The result type of a method or function.
OpenACCDirectiveKind DirKind