[libc] Switch to using the generic `<gpuintrin.h>` implementations (#121810)
[llvm-project.git] / clang / lib / Sema / SemaOpenACC.cpp
blob00cd3a009386e5c025c2a50b69d8f1e31ae0e058
1 //===--- SemaOpenACC.cpp - Semantic Analysis for OpenACC constructs -------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file implements semantic analysis for OpenACC constructs and
10 /// clauses.
11 ///
12 //===----------------------------------------------------------------------===//
14 #include "clang/Sema/SemaOpenACC.h"
15 #include "clang/AST/StmtOpenACC.h"
16 #include "clang/Basic/DiagnosticSema.h"
17 #include "clang/Basic/OpenACCKinds.h"
18 #include "clang/Sema/Sema.h"
19 #include "llvm/ADT/StringExtras.h"
20 #include "llvm/Support/Casting.h"
22 using namespace clang;
24 namespace {
25 bool diagnoseConstructAppertainment(SemaOpenACC &S, OpenACCDirectiveKind K,
26 SourceLocation StartLoc, bool IsStmt) {
27 switch (K) {
28 default:
29 case OpenACCDirectiveKind::Invalid:
30 // Nothing to do here, both invalid and unimplemented don't really need to
31 // do anything.
32 break;
33 case OpenACCDirectiveKind::ParallelLoop:
34 case OpenACCDirectiveKind::SerialLoop:
35 case OpenACCDirectiveKind::KernelsLoop:
36 case OpenACCDirectiveKind::Parallel:
37 case OpenACCDirectiveKind::Serial:
38 case OpenACCDirectiveKind::Kernels:
39 case OpenACCDirectiveKind::Loop:
40 case OpenACCDirectiveKind::Data:
41 case OpenACCDirectiveKind::EnterData:
42 case OpenACCDirectiveKind::ExitData:
43 case OpenACCDirectiveKind::HostData:
44 case OpenACCDirectiveKind::Wait:
45 if (!IsStmt)
46 return S.Diag(StartLoc, diag::err_acc_construct_appertainment) << K;
47 break;
49 return false;
52 bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind,
53 OpenACCClauseKind ClauseKind) {
54 switch (ClauseKind) {
55 // FIXME: For each clause as we implement them, we can add the
56 // 'legalization' list here.
57 case OpenACCClauseKind::Default:
58 switch (DirectiveKind) {
59 case OpenACCDirectiveKind::Parallel:
60 case OpenACCDirectiveKind::Serial:
61 case OpenACCDirectiveKind::Kernels:
62 case OpenACCDirectiveKind::ParallelLoop:
63 case OpenACCDirectiveKind::SerialLoop:
64 case OpenACCDirectiveKind::KernelsLoop:
65 case OpenACCDirectiveKind::Data:
66 return true;
67 default:
68 return false;
70 case OpenACCClauseKind::If:
71 switch (DirectiveKind) {
72 case OpenACCDirectiveKind::Parallel:
73 case OpenACCDirectiveKind::Serial:
74 case OpenACCDirectiveKind::Kernels:
75 case OpenACCDirectiveKind::Data:
76 case OpenACCDirectiveKind::EnterData:
77 case OpenACCDirectiveKind::ExitData:
78 case OpenACCDirectiveKind::HostData:
79 case OpenACCDirectiveKind::Init:
80 case OpenACCDirectiveKind::Shutdown:
81 case OpenACCDirectiveKind::Set:
82 case OpenACCDirectiveKind::Update:
83 case OpenACCDirectiveKind::Wait:
84 case OpenACCDirectiveKind::ParallelLoop:
85 case OpenACCDirectiveKind::SerialLoop:
86 case OpenACCDirectiveKind::KernelsLoop:
87 return true;
88 default:
89 return false;
91 case OpenACCClauseKind::Self:
92 switch (DirectiveKind) {
93 case OpenACCDirectiveKind::Parallel:
94 case OpenACCDirectiveKind::Serial:
95 case OpenACCDirectiveKind::Kernels:
96 case OpenACCDirectiveKind::Update:
97 case OpenACCDirectiveKind::ParallelLoop:
98 case OpenACCDirectiveKind::SerialLoop:
99 case OpenACCDirectiveKind::KernelsLoop:
100 return true;
101 default:
102 return false;
104 case OpenACCClauseKind::NumGangs:
105 case OpenACCClauseKind::NumWorkers:
106 case OpenACCClauseKind::VectorLength:
107 switch (DirectiveKind) {
108 case OpenACCDirectiveKind::Parallel:
109 case OpenACCDirectiveKind::Kernels:
110 case OpenACCDirectiveKind::ParallelLoop:
111 case OpenACCDirectiveKind::KernelsLoop:
112 return true;
113 default:
114 return false;
116 case OpenACCClauseKind::FirstPrivate:
117 switch (DirectiveKind) {
118 case OpenACCDirectiveKind::Parallel:
119 case OpenACCDirectiveKind::Serial:
120 case OpenACCDirectiveKind::ParallelLoop:
121 case OpenACCDirectiveKind::SerialLoop:
122 return true;
123 default:
124 return false;
126 case OpenACCClauseKind::Private:
127 switch (DirectiveKind) {
128 case OpenACCDirectiveKind::Parallel:
129 case OpenACCDirectiveKind::Serial:
130 case OpenACCDirectiveKind::Loop:
131 case OpenACCDirectiveKind::ParallelLoop:
132 case OpenACCDirectiveKind::SerialLoop:
133 case OpenACCDirectiveKind::KernelsLoop:
134 return true;
135 default:
136 return false;
138 case OpenACCClauseKind::NoCreate:
139 switch (DirectiveKind) {
140 case OpenACCDirectiveKind::Parallel:
141 case OpenACCDirectiveKind::Serial:
142 case OpenACCDirectiveKind::Kernels:
143 case OpenACCDirectiveKind::Data:
144 case OpenACCDirectiveKind::ParallelLoop:
145 case OpenACCDirectiveKind::SerialLoop:
146 case OpenACCDirectiveKind::KernelsLoop:
147 return true;
148 default:
149 return false;
151 case OpenACCClauseKind::Present:
152 switch (DirectiveKind) {
153 case OpenACCDirectiveKind::Parallel:
154 case OpenACCDirectiveKind::Serial:
155 case OpenACCDirectiveKind::Kernels:
156 case OpenACCDirectiveKind::Data:
157 case OpenACCDirectiveKind::Declare:
158 case OpenACCDirectiveKind::ParallelLoop:
159 case OpenACCDirectiveKind::SerialLoop:
160 case OpenACCDirectiveKind::KernelsLoop:
161 return true;
162 default:
163 return false;
166 case OpenACCClauseKind::Copy:
167 case OpenACCClauseKind::PCopy:
168 case OpenACCClauseKind::PresentOrCopy:
169 switch (DirectiveKind) {
170 case OpenACCDirectiveKind::Parallel:
171 case OpenACCDirectiveKind::Serial:
172 case OpenACCDirectiveKind::Kernels:
173 case OpenACCDirectiveKind::Data:
174 case OpenACCDirectiveKind::Declare:
175 case OpenACCDirectiveKind::ParallelLoop:
176 case OpenACCDirectiveKind::SerialLoop:
177 case OpenACCDirectiveKind::KernelsLoop:
178 return true;
179 default:
180 return false;
182 case OpenACCClauseKind::CopyIn:
183 case OpenACCClauseKind::PCopyIn:
184 case OpenACCClauseKind::PresentOrCopyIn:
185 switch (DirectiveKind) {
186 case OpenACCDirectiveKind::Parallel:
187 case OpenACCDirectiveKind::Serial:
188 case OpenACCDirectiveKind::Kernels:
189 case OpenACCDirectiveKind::Data:
190 case OpenACCDirectiveKind::EnterData:
191 case OpenACCDirectiveKind::Declare:
192 case OpenACCDirectiveKind::ParallelLoop:
193 case OpenACCDirectiveKind::SerialLoop:
194 case OpenACCDirectiveKind::KernelsLoop:
195 return true;
196 default:
197 return false;
199 case OpenACCClauseKind::CopyOut:
200 case OpenACCClauseKind::PCopyOut:
201 case OpenACCClauseKind::PresentOrCopyOut:
202 switch (DirectiveKind) {
203 case OpenACCDirectiveKind::Parallel:
204 case OpenACCDirectiveKind::Serial:
205 case OpenACCDirectiveKind::Kernels:
206 case OpenACCDirectiveKind::Data:
207 case OpenACCDirectiveKind::ExitData:
208 case OpenACCDirectiveKind::Declare:
209 case OpenACCDirectiveKind::ParallelLoop:
210 case OpenACCDirectiveKind::SerialLoop:
211 case OpenACCDirectiveKind::KernelsLoop:
212 return true;
213 default:
214 return false;
216 case OpenACCClauseKind::Create:
217 case OpenACCClauseKind::PCreate:
218 case OpenACCClauseKind::PresentOrCreate:
219 switch (DirectiveKind) {
220 case OpenACCDirectiveKind::Parallel:
221 case OpenACCDirectiveKind::Serial:
222 case OpenACCDirectiveKind::Kernels:
223 case OpenACCDirectiveKind::Data:
224 case OpenACCDirectiveKind::EnterData:
225 case OpenACCDirectiveKind::ParallelLoop:
226 case OpenACCDirectiveKind::SerialLoop:
227 case OpenACCDirectiveKind::KernelsLoop:
228 return true;
229 default:
230 return false;
233 case OpenACCClauseKind::Attach:
234 switch (DirectiveKind) {
235 case OpenACCDirectiveKind::Parallel:
236 case OpenACCDirectiveKind::Serial:
237 case OpenACCDirectiveKind::Kernels:
238 case OpenACCDirectiveKind::Data:
239 case OpenACCDirectiveKind::EnterData:
240 case OpenACCDirectiveKind::ParallelLoop:
241 case OpenACCDirectiveKind::SerialLoop:
242 case OpenACCDirectiveKind::KernelsLoop:
243 return true;
244 default:
245 return false;
247 case OpenACCClauseKind::DevicePtr:
248 switch (DirectiveKind) {
249 case OpenACCDirectiveKind::Parallel:
250 case OpenACCDirectiveKind::Serial:
251 case OpenACCDirectiveKind::Kernels:
252 case OpenACCDirectiveKind::Data:
253 case OpenACCDirectiveKind::Declare:
254 case OpenACCDirectiveKind::ParallelLoop:
255 case OpenACCDirectiveKind::SerialLoop:
256 case OpenACCDirectiveKind::KernelsLoop:
257 return true;
258 default:
259 return false;
261 case OpenACCClauseKind::Async:
262 switch (DirectiveKind) {
263 case OpenACCDirectiveKind::Parallel:
264 case OpenACCDirectiveKind::Serial:
265 case OpenACCDirectiveKind::Kernels:
266 case OpenACCDirectiveKind::Data:
267 case OpenACCDirectiveKind::EnterData:
268 case OpenACCDirectiveKind::ExitData:
269 case OpenACCDirectiveKind::Set:
270 case OpenACCDirectiveKind::Update:
271 case OpenACCDirectiveKind::Wait:
272 case OpenACCDirectiveKind::ParallelLoop:
273 case OpenACCDirectiveKind::SerialLoop:
274 case OpenACCDirectiveKind::KernelsLoop:
275 return true;
276 default:
277 return false;
279 case OpenACCClauseKind::Wait:
280 switch (DirectiveKind) {
281 case OpenACCDirectiveKind::Parallel:
282 case OpenACCDirectiveKind::Serial:
283 case OpenACCDirectiveKind::Kernels:
284 case OpenACCDirectiveKind::Data:
285 case OpenACCDirectiveKind::EnterData:
286 case OpenACCDirectiveKind::ExitData:
287 case OpenACCDirectiveKind::Update:
288 case OpenACCDirectiveKind::ParallelLoop:
289 case OpenACCDirectiveKind::SerialLoop:
290 case OpenACCDirectiveKind::KernelsLoop:
291 return true;
292 default:
293 return false;
296 case OpenACCClauseKind::Seq:
297 switch (DirectiveKind) {
298 case OpenACCDirectiveKind::Loop:
299 case OpenACCDirectiveKind::Routine:
300 case OpenACCDirectiveKind::ParallelLoop:
301 case OpenACCDirectiveKind::SerialLoop:
302 case OpenACCDirectiveKind::KernelsLoop:
303 return true;
304 default:
305 return false;
308 case OpenACCClauseKind::Independent:
309 case OpenACCClauseKind::Auto:
310 switch (DirectiveKind) {
311 case OpenACCDirectiveKind::Loop:
312 case OpenACCDirectiveKind::ParallelLoop:
313 case OpenACCDirectiveKind::SerialLoop:
314 case OpenACCDirectiveKind::KernelsLoop:
315 return true;
316 default:
317 return false;
320 case OpenACCClauseKind::Reduction:
321 switch (DirectiveKind) {
322 case OpenACCDirectiveKind::Parallel:
323 case OpenACCDirectiveKind::Serial:
324 case OpenACCDirectiveKind::Loop:
325 case OpenACCDirectiveKind::ParallelLoop:
326 case OpenACCDirectiveKind::SerialLoop:
327 case OpenACCDirectiveKind::KernelsLoop:
328 return true;
329 default:
330 return false;
333 case OpenACCClauseKind::DeviceType:
334 case OpenACCClauseKind::DType:
335 switch (DirectiveKind) {
336 case OpenACCDirectiveKind::Parallel:
337 case OpenACCDirectiveKind::Serial:
338 case OpenACCDirectiveKind::Kernels:
339 case OpenACCDirectiveKind::Data:
340 case OpenACCDirectiveKind::Init:
341 case OpenACCDirectiveKind::Shutdown:
342 case OpenACCDirectiveKind::Set:
343 case OpenACCDirectiveKind::Update:
344 case OpenACCDirectiveKind::Loop:
345 case OpenACCDirectiveKind::Routine:
346 case OpenACCDirectiveKind::ParallelLoop:
347 case OpenACCDirectiveKind::SerialLoop:
348 case OpenACCDirectiveKind::KernelsLoop:
349 return true;
350 default:
351 return false;
354 case OpenACCClauseKind::Collapse: {
355 switch (DirectiveKind) {
356 case OpenACCDirectiveKind::Loop:
357 case OpenACCDirectiveKind::ParallelLoop:
358 case OpenACCDirectiveKind::SerialLoop:
359 case OpenACCDirectiveKind::KernelsLoop:
360 return true;
361 default:
362 return false;
365 case OpenACCClauseKind::Tile: {
366 switch (DirectiveKind) {
367 case OpenACCDirectiveKind::Loop:
368 case OpenACCDirectiveKind::ParallelLoop:
369 case OpenACCDirectiveKind::SerialLoop:
370 case OpenACCDirectiveKind::KernelsLoop:
371 return true;
372 default:
373 return false;
377 case OpenACCClauseKind::Gang: {
378 switch (DirectiveKind) {
379 case OpenACCDirectiveKind::Loop:
380 case OpenACCDirectiveKind::ParallelLoop:
381 case OpenACCDirectiveKind::SerialLoop:
382 case OpenACCDirectiveKind::KernelsLoop:
383 case OpenACCDirectiveKind::Routine:
384 return true;
385 default:
386 return false;
388 case OpenACCClauseKind::Worker: {
389 switch (DirectiveKind) {
390 case OpenACCDirectiveKind::Loop:
391 case OpenACCDirectiveKind::ParallelLoop:
392 case OpenACCDirectiveKind::SerialLoop:
393 case OpenACCDirectiveKind::KernelsLoop:
394 case OpenACCDirectiveKind::Routine:
395 return true;
396 default:
397 return false;
400 case OpenACCClauseKind::Vector: {
401 switch (DirectiveKind) {
402 case OpenACCDirectiveKind::Loop:
403 case OpenACCDirectiveKind::ParallelLoop:
404 case OpenACCDirectiveKind::SerialLoop:
405 case OpenACCDirectiveKind::KernelsLoop:
406 case OpenACCDirectiveKind::Routine:
407 return true;
408 default:
409 return false;
412 case OpenACCClauseKind::Finalize: {
413 switch (DirectiveKind) {
414 case OpenACCDirectiveKind::ExitData:
415 return true;
416 default:
417 return false;
420 case OpenACCClauseKind::IfPresent: {
421 switch (DirectiveKind) {
422 case OpenACCDirectiveKind::HostData:
423 case OpenACCDirectiveKind::Update:
424 return true;
425 default:
426 return false;
429 case OpenACCClauseKind::Delete: {
430 switch (DirectiveKind) {
431 case OpenACCDirectiveKind::ExitData:
432 return true;
433 default:
434 return false;
438 case OpenACCClauseKind::Detach: {
439 switch (DirectiveKind) {
440 case OpenACCDirectiveKind::ExitData:
441 return true;
442 default:
443 return false;
447 case OpenACCClauseKind::DeviceNum: {
448 switch (DirectiveKind) {
449 case OpenACCDirectiveKind::Init:
450 case OpenACCDirectiveKind::Shutdown:
451 case OpenACCDirectiveKind::Set:
452 return true;
453 default:
454 return false;
458 case OpenACCClauseKind::UseDevice: {
459 switch (DirectiveKind) {
460 case OpenACCDirectiveKind::HostData:
461 return true;
462 default:
463 return false;
466 case OpenACCClauseKind::DefaultAsync: {
467 switch (DirectiveKind) {
468 case OpenACCDirectiveKind::Set:
469 return true;
470 default:
471 return false;
476 default:
477 // Do nothing so we can go to the 'unimplemented' diagnostic instead.
478 return true;
480 llvm_unreachable("Invalid clause kind");
483 bool checkAlreadyHasClauseOfKind(
484 SemaOpenACC &S, ArrayRef<const OpenACCClause *> ExistingClauses,
485 SemaOpenACC::OpenACCParsedClause &Clause) {
486 const auto *Itr = llvm::find_if(ExistingClauses, [&](const OpenACCClause *C) {
487 return C->getClauseKind() == Clause.getClauseKind();
489 if (Itr != ExistingClauses.end()) {
490 S.Diag(Clause.getBeginLoc(), diag::err_acc_duplicate_clause_disallowed)
491 << Clause.getDirectiveKind() << Clause.getClauseKind();
492 S.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
493 return true;
495 return false;
498 bool checkValidAfterDeviceType(
499 SemaOpenACC &S, const OpenACCDeviceTypeClause &DeviceTypeClause,
500 const SemaOpenACC::OpenACCParsedClause &NewClause) {
501 // This is only a requirement on compute, combined, data and loop constructs
502 // so far, so this is fine otherwise.
503 if (!isOpenACCComputeDirectiveKind(NewClause.getDirectiveKind()) &&
504 !isOpenACCCombinedDirectiveKind(NewClause.getDirectiveKind()) &&
505 NewClause.getDirectiveKind() != OpenACCDirectiveKind::Loop &&
506 NewClause.getDirectiveKind() != OpenACCDirectiveKind::Data)
507 return false;
509 // OpenACC3.3: Section 2.4: Clauses that precede any device_type clause are
510 // default clauses. Clauses that follow a device_type clause up to the end of
511 // the directive or up to the next device_type clause are device-specific
512 // clauses for the device types specified in the device_type argument.
514 // The above implies that despite what the individual text says, these are
515 // valid.
516 if (NewClause.getClauseKind() == OpenACCClauseKind::DType ||
517 NewClause.getClauseKind() == OpenACCClauseKind::DeviceType)
518 return false;
520 // Implement check from OpenACC3.3: section 2.5.4:
521 // Only the async, wait, num_gangs, num_workers, and vector_length clauses may
522 // follow a device_type clause.
523 if (isOpenACCComputeDirectiveKind(NewClause.getDirectiveKind())) {
524 switch (NewClause.getClauseKind()) {
525 case OpenACCClauseKind::Async:
526 case OpenACCClauseKind::Wait:
527 case OpenACCClauseKind::NumGangs:
528 case OpenACCClauseKind::NumWorkers:
529 case OpenACCClauseKind::VectorLength:
530 return false;
531 default:
532 break;
534 } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Loop) {
535 // Implement check from OpenACC3.3: section 2.9:
536 // Only the collapse, gang, worker, vector, seq, independent, auto, and tile
537 // clauses may follow a device_type clause.
538 switch (NewClause.getClauseKind()) {
539 case OpenACCClauseKind::Collapse:
540 case OpenACCClauseKind::Gang:
541 case OpenACCClauseKind::Worker:
542 case OpenACCClauseKind::Vector:
543 case OpenACCClauseKind::Seq:
544 case OpenACCClauseKind::Independent:
545 case OpenACCClauseKind::Auto:
546 case OpenACCClauseKind::Tile:
547 return false;
548 default:
549 break;
551 } else if (isOpenACCCombinedDirectiveKind(NewClause.getDirectiveKind())) {
552 // This seems like it should be the union of 2.9 and 2.5.4 from above.
553 switch (NewClause.getClauseKind()) {
554 case OpenACCClauseKind::Async:
555 case OpenACCClauseKind::Wait:
556 case OpenACCClauseKind::NumGangs:
557 case OpenACCClauseKind::NumWorkers:
558 case OpenACCClauseKind::VectorLength:
559 case OpenACCClauseKind::Collapse:
560 case OpenACCClauseKind::Gang:
561 case OpenACCClauseKind::Worker:
562 case OpenACCClauseKind::Vector:
563 case OpenACCClauseKind::Seq:
564 case OpenACCClauseKind::Independent:
565 case OpenACCClauseKind::Auto:
566 case OpenACCClauseKind::Tile:
567 return false;
568 default:
569 break;
571 } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Data) {
572 // OpenACC3.3 section 2.6.5: Only the async and wait clauses may follow a
573 // device_type clause.
574 switch (NewClause.getClauseKind()) {
575 case OpenACCClauseKind::Async:
576 case OpenACCClauseKind::Wait:
577 return false;
578 default:
579 break;
582 S.Diag(NewClause.getBeginLoc(), diag::err_acc_clause_after_device_type)
583 << NewClause.getClauseKind() << DeviceTypeClause.getClauseKind()
584 << NewClause.getDirectiveKind();
585 S.Diag(DeviceTypeClause.getBeginLoc(), diag::note_acc_previous_clause_here);
586 return true;
589 // A temporary function that helps implement the 'not implemented' check at the
590 // top of each clause checking function. This should only be used in conjunction
591 // with the one being currently implemented/only updated after the entire
592 // construct has been implemented.
593 bool isDirectiveKindImplemented(OpenACCDirectiveKind DK) {
594 return isOpenACCComputeDirectiveKind(DK) ||
595 isOpenACCCombinedDirectiveKind(DK) || isOpenACCDataDirectiveKind(DK) ||
596 DK == OpenACCDirectiveKind::Loop || DK == OpenACCDirectiveKind::Wait ||
597 DK == OpenACCDirectiveKind::Init ||
598 DK == OpenACCDirectiveKind::Shutdown ||
599 DK == OpenACCDirectiveKind::Set;
602 class SemaOpenACCClauseVisitor {
603 SemaOpenACC &SemaRef;
604 ASTContext &Ctx;
605 ArrayRef<const OpenACCClause *> ExistingClauses;
606 bool NotImplemented = false;
608 OpenACCClause *isNotImplemented() {
609 NotImplemented = true;
610 return nullptr;
613 // OpenACC 3.3 2.9:
614 // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' clause
615 // appears.
616 bool DiagIfSeqClause(SemaOpenACC::OpenACCParsedClause &Clause) {
617 const auto *Itr =
618 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSeqClause>);
620 if (Itr != ExistingClauses.end()) {
621 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine)
622 << Clause.getClauseKind() << (*Itr)->getClauseKind()
623 << Clause.getDirectiveKind();
624 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
626 return true;
628 return false;
631 public:
632 SemaOpenACCClauseVisitor(SemaOpenACC &S,
633 ArrayRef<const OpenACCClause *> ExistingClauses)
634 : SemaRef(S), Ctx(S.getASTContext()), ExistingClauses(ExistingClauses) {}
635 // Once we've implemented everything, we shouldn't need this infrastructure.
636 // But in the meantime, we use this to help decide whether the clause was
637 // handled for this directive.
638 bool diagNotImplemented() { return NotImplemented; }
640 OpenACCClause *Visit(SemaOpenACC::OpenACCParsedClause &Clause) {
641 switch (Clause.getClauseKind()) {
642 #define VISIT_CLAUSE(CLAUSE_NAME) \
643 case OpenACCClauseKind::CLAUSE_NAME: \
644 return Visit##CLAUSE_NAME##Clause(Clause);
645 #define CLAUSE_ALIAS(ALIAS, CLAUSE_NAME, DEPRECATED) \
646 case OpenACCClauseKind::ALIAS: \
647 if (DEPRECATED) \
648 SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name) \
649 << Clause.getClauseKind() << OpenACCClauseKind::CLAUSE_NAME; \
650 return Visit##CLAUSE_NAME##Clause(Clause);
651 #include "clang/Basic/OpenACCClauses.def"
652 default:
653 return isNotImplemented();
655 llvm_unreachable("Invalid clause kind");
658 #define VISIT_CLAUSE(CLAUSE_NAME) \
659 OpenACCClause *Visit##CLAUSE_NAME##Clause( \
660 SemaOpenACC::OpenACCParsedClause &Clause);
661 #include "clang/Basic/OpenACCClauses.def"
664 OpenACCClause *SemaOpenACCClauseVisitor::VisitDefaultClause(
665 SemaOpenACC::OpenACCParsedClause &Clause) {
666 // Don't add an invalid clause to the AST.
667 if (Clause.getDefaultClauseKind() == OpenACCDefaultClauseKind::Invalid)
668 return nullptr;
670 // OpenACC 3.3, Section 2.5.4:
671 // At most one 'default' clause may appear, and it must have a value of
672 // either 'none' or 'present'.
673 // Second half of the sentence is diagnosed during parsing.
674 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
675 return nullptr;
677 return OpenACCDefaultClause::Create(
678 Ctx, Clause.getDefaultClauseKind(), Clause.getBeginLoc(),
679 Clause.getLParenLoc(), Clause.getEndLoc());
682 OpenACCClause *SemaOpenACCClauseVisitor::VisitTileClause(
683 SemaOpenACC::OpenACCParsedClause &Clause) {
685 // Duplicates here are not really sensible. We could possible permit
686 // multiples if they all had the same value, but there isn't really a good
687 // reason to do so. Also, this simplifies the suppression of duplicates, in
688 // that we know if we 'find' one after instantiation, that it is the same
689 // clause, which simplifies instantiation/checking/etc.
690 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
691 return nullptr;
693 llvm::SmallVector<Expr *> NewSizeExprs;
695 // Make sure these are all positive constant expressions or *.
696 for (Expr *E : Clause.getIntExprs()) {
697 ExprResult Res = SemaRef.CheckTileSizeExpr(E);
699 if (!Res.isUsable())
700 return nullptr;
702 NewSizeExprs.push_back(Res.get());
705 return OpenACCTileClause::Create(Ctx, Clause.getBeginLoc(),
706 Clause.getLParenLoc(), NewSizeExprs,
707 Clause.getEndLoc());
710 OpenACCClause *SemaOpenACCClauseVisitor::VisitIfClause(
711 SemaOpenACC::OpenACCParsedClause &Clause) {
712 // There is no prose in the standard that says duplicates aren't allowed,
713 // but this diagnostic is present in other compilers, as well as makes
714 // sense. Prose DOES exist for 'data' and 'host_data', 'set', 'enter data' and
715 // 'exit data' both don't, but other implmementations do this. OpenACC issue
716 // 519 filed for the latter two. Prose also exists for 'update'.
717 // GCC allows this on init/shutdown, presumably for good reason, so we do too.
718 if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Init &&
719 Clause.getDirectiveKind() != OpenACCDirectiveKind::Shutdown &&
720 checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
721 return nullptr;
723 // The parser has ensured that we have a proper condition expr, so there
724 // isn't really much to do here.
726 // If the 'if' clause is true, it makes the 'self' clause have no effect,
727 // diagnose that here.
728 // TODO OpenACC: When we add these two to other constructs, we might not
729 // want to warn on this (for example, 'update').
730 const auto *Itr =
731 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSelfClause>);
732 if (Itr != ExistingClauses.end()) {
733 SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict);
734 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
737 return OpenACCIfClause::Create(Ctx, Clause.getBeginLoc(),
738 Clause.getLParenLoc(),
739 Clause.getConditionExpr(), Clause.getEndLoc());
742 OpenACCClause *SemaOpenACCClauseVisitor::VisitSelfClause(
743 SemaOpenACC::OpenACCParsedClause &Clause) {
744 // Restrictions only properly implemented on 'compute' constructs, and
745 // 'compute' constructs are the only construct that can do anything with
746 // this yet, so skip/treat as unimplemented in this case.
747 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
748 return isNotImplemented();
750 // TODO OpenACC: When we implement this for 'update', this takes a
751 // 'var-list' instead of a condition expression, so semantics/handling has
752 // to happen differently here.
754 // There is no prose in the standard that says duplicates aren't allowed,
755 // but this diagnostic is present in other compilers, as well as makes
756 // sense.
757 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
758 return nullptr;
760 // If the 'if' clause is true, it makes the 'self' clause have no effect,
761 // diagnose that here.
762 // TODO OpenACC: When we add these two to other constructs, we might not
763 // want to warn on this (for example, 'update').
764 const auto *Itr =
765 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCIfClause>);
766 if (Itr != ExistingClauses.end()) {
767 SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict);
768 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
770 return OpenACCSelfClause::Create(
771 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(),
772 Clause.getConditionExpr(), Clause.getEndLoc());
775 OpenACCClause *SemaOpenACCClauseVisitor::VisitNumGangsClause(
776 SemaOpenACC::OpenACCParsedClause &Clause) {
777 // There is no prose in the standard that says duplicates aren't allowed,
778 // but this diagnostic is present in other compilers, as well as makes
779 // sense.
780 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
781 return nullptr;
783 // num_gangs requires at least 1 int expr in all forms. Diagnose here, but
784 // allow us to continue, an empty clause might be useful for future
785 // diagnostics.
786 if (Clause.getIntExprs().empty())
787 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args)
788 << /*NoArgs=*/0;
790 unsigned MaxArgs =
791 (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel ||
792 Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop)
794 : 1;
795 // The max number of args differs between parallel and other constructs.
796 // Again, allow us to continue for the purposes of future diagnostics.
797 if (Clause.getIntExprs().size() > MaxArgs)
798 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args)
799 << /*NoArgs=*/1 << Clause.getDirectiveKind() << MaxArgs
800 << Clause.getIntExprs().size();
802 // OpenACC 3.3 Section 2.9.11: A reduction clause may not appear on a loop
803 // directive that has a gang clause and is within a compute construct that has
804 // a num_gangs clause with more than one explicit argument.
805 if (Clause.getIntExprs().size() > 1 &&
806 isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) {
807 auto *GangClauseItr =
808 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCGangClause>);
809 auto *ReductionClauseItr =
810 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>);
812 if (GangClauseItr != ExistingClauses.end() &&
813 ReductionClauseItr != ExistingClauses.end()) {
814 SemaRef.Diag(Clause.getBeginLoc(),
815 diag::err_acc_gang_reduction_numgangs_conflict)
816 << OpenACCClauseKind::Reduction << OpenACCClauseKind::Gang
817 << Clause.getDirectiveKind() << /*is on combined directive=*/1;
818 SemaRef.Diag((*ReductionClauseItr)->getBeginLoc(),
819 diag::note_acc_previous_clause_here);
820 SemaRef.Diag((*GangClauseItr)->getBeginLoc(),
821 diag::note_acc_previous_clause_here);
822 return nullptr;
826 // OpenACC 3.3 Section 2.5.4:
827 // A reduction clause may not appear on a parallel construct with a
828 // num_gangs clause that has more than one argument.
829 if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel ||
830 Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop) &&
831 Clause.getIntExprs().size() > 1) {
832 auto *Parallel =
833 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>);
835 if (Parallel != ExistingClauses.end()) {
836 SemaRef.Diag(Clause.getBeginLoc(),
837 diag::err_acc_reduction_num_gangs_conflict)
838 << /*>1 arg in first loc=*/1 << Clause.getClauseKind()
839 << Clause.getDirectiveKind() << OpenACCClauseKind::Reduction;
840 SemaRef.Diag((*Parallel)->getBeginLoc(),
841 diag::note_acc_previous_clause_here);
842 return nullptr;
846 // OpenACC 3.3 Section 2.9.2:
847 // An argument with no keyword or with the 'num' keyword is allowed only when
848 // the 'num_gangs' does not appear on the 'kernel' construct.
849 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) {
850 auto GangClauses = llvm::make_filter_range(
851 ExistingClauses, llvm::IsaPred<OpenACCGangClause>);
853 for (auto *GC : GangClauses) {
854 if (cast<OpenACCGangClause>(GC)->hasExprOfKind(OpenACCGangKind::Num)) {
855 SemaRef.Diag(Clause.getBeginLoc(),
856 diag::err_acc_num_arg_conflict_reverse)
857 << OpenACCClauseKind::NumGangs << OpenACCClauseKind::Gang
858 << /*Num argument*/ 1;
859 SemaRef.Diag(GC->getBeginLoc(), diag::note_acc_previous_clause_here);
860 return nullptr;
865 return OpenACCNumGangsClause::Create(
866 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs(),
867 Clause.getEndLoc());
870 OpenACCClause *SemaOpenACCClauseVisitor::VisitNumWorkersClause(
871 SemaOpenACC::OpenACCParsedClause &Clause) {
872 // There is no prose in the standard that says duplicates aren't allowed,
873 // but this diagnostic is present in other compilers, as well as makes
874 // sense.
875 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
876 return nullptr;
878 // OpenACC 3.3 Section 2.9.2:
879 // An argument is allowed only when the 'num_workers' does not appear on the
880 // kernels construct.
881 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) {
882 auto WorkerClauses = llvm::make_filter_range(
883 ExistingClauses, llvm::IsaPred<OpenACCWorkerClause>);
885 for (auto *WC : WorkerClauses) {
886 if (cast<OpenACCWorkerClause>(WC)->hasIntExpr()) {
887 SemaRef.Diag(Clause.getBeginLoc(),
888 diag::err_acc_num_arg_conflict_reverse)
889 << OpenACCClauseKind::NumWorkers << OpenACCClauseKind::Worker
890 << /*num argument*/ 0;
891 SemaRef.Diag(WC->getBeginLoc(), diag::note_acc_previous_clause_here);
892 return nullptr;
897 assert(Clause.getIntExprs().size() == 1 &&
898 "Invalid number of expressions for NumWorkers");
899 return OpenACCNumWorkersClause::Create(
900 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0],
901 Clause.getEndLoc());
904 OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorLengthClause(
905 SemaOpenACC::OpenACCParsedClause &Clause) {
906 // There is no prose in the standard that says duplicates aren't allowed,
907 // but this diagnostic is present in other compilers, as well as makes
908 // sense.
909 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
910 return nullptr;
912 // OpenACC 3.3 Section 2.9.4:
913 // An argument is allowed only when the 'vector_length' does not appear on the
914 // 'kernels' construct.
915 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) {
916 auto VectorClauses = llvm::make_filter_range(
917 ExistingClauses, llvm::IsaPred<OpenACCVectorClause>);
919 for (auto *VC : VectorClauses) {
920 if (cast<OpenACCVectorClause>(VC)->hasIntExpr()) {
921 SemaRef.Diag(Clause.getBeginLoc(),
922 diag::err_acc_num_arg_conflict_reverse)
923 << OpenACCClauseKind::VectorLength << OpenACCClauseKind::Vector
924 << /*num argument*/ 0;
925 SemaRef.Diag(VC->getBeginLoc(), diag::note_acc_previous_clause_here);
926 return nullptr;
931 assert(Clause.getIntExprs().size() == 1 &&
932 "Invalid number of expressions for NumWorkers");
933 return OpenACCVectorLengthClause::Create(
934 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0],
935 Clause.getEndLoc());
938 OpenACCClause *SemaOpenACCClauseVisitor::VisitAsyncClause(
939 SemaOpenACC::OpenACCParsedClause &Clause) {
940 // There is no prose in the standard that says duplicates aren't allowed,
941 // but this diagnostic is present in other compilers, as well as makes
942 // sense.
943 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
944 return nullptr;
946 assert(Clause.getNumIntExprs() < 2 &&
947 "Invalid number of expressions for Async");
948 return OpenACCAsyncClause::Create(
949 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(),
950 Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr,
951 Clause.getEndLoc());
954 OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceNumClause(
955 SemaOpenACC::OpenACCParsedClause &Clause) {
956 // Restrictions only properly implemented on certain constructs, so skip/treat
957 // as unimplemented in those cases.
958 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
959 return isNotImplemented();
961 // OpenACC 3.3 2.14.3: Two instances of the same clause may not appear on the
962 // same directive.
963 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Set &&
964 checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
965 return nullptr;
967 assert(Clause.getNumIntExprs() == 1 &&
968 "Invalid number of expressions for device_num");
969 return OpenACCDeviceNumClause::Create(
970 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0],
971 Clause.getEndLoc());
974 OpenACCClause *SemaOpenACCClauseVisitor::VisitDefaultAsyncClause(
975 SemaOpenACC::OpenACCParsedClause &Clause) {
976 // OpenACC 3.3 2.14.3: Two instances of the same clause may not appear on the
977 // same directive.
978 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
979 return nullptr;
981 assert(Clause.getNumIntExprs() == 1 &&
982 "Invalid number of expressions for default_async");
983 return OpenACCDefaultAsyncClause::Create(
984 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0],
985 Clause.getEndLoc());
988 OpenACCClause *SemaOpenACCClauseVisitor::VisitPrivateClause(
989 SemaOpenACC::OpenACCParsedClause &Clause) {
990 // ActOnVar ensured that everything is a valid variable reference, so there
991 // really isn't anything to do here. GCC does some duplicate-finding, though
992 // it isn't apparent in the standard where this is justified.
994 return OpenACCPrivateClause::Create(Ctx, Clause.getBeginLoc(),
995 Clause.getLParenLoc(),
996 Clause.getVarList(), Clause.getEndLoc());
999 OpenACCClause *SemaOpenACCClauseVisitor::VisitFirstPrivateClause(
1000 SemaOpenACC::OpenACCParsedClause &Clause) {
1001 // ActOnVar ensured that everything is a valid variable reference, so there
1002 // really isn't anything to do here. GCC does some duplicate-finding, though
1003 // it isn't apparent in the standard where this is justified.
1005 return OpenACCFirstPrivateClause::Create(
1006 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(),
1007 Clause.getEndLoc());
1010 OpenACCClause *SemaOpenACCClauseVisitor::VisitNoCreateClause(
1011 SemaOpenACC::OpenACCParsedClause &Clause) {
1012 // ActOnVar ensured that everything is a valid variable reference, so there
1013 // really isn't anything to do here. GCC does some duplicate-finding, though
1014 // it isn't apparent in the standard where this is justified.
1016 return OpenACCNoCreateClause::Create(Ctx, Clause.getBeginLoc(),
1017 Clause.getLParenLoc(),
1018 Clause.getVarList(), Clause.getEndLoc());
1021 OpenACCClause *SemaOpenACCClauseVisitor::VisitPresentClause(
1022 SemaOpenACC::OpenACCParsedClause &Clause) {
1023 // Restrictions only properly implemented on 'compute'/'combined'/'data'
1024 // constructs, and 'compute'/'combined'/'data' constructs are the only
1025 // construct that can do anything with this yet, so skip/treat as
1026 // unimplemented in this case.
1027 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1028 return isNotImplemented();
1029 // ActOnVar ensured that everything is a valid variable reference, so there
1030 // really isn't anything to do here. GCC does some duplicate-finding, though
1031 // it isn't apparent in the standard where this is justified.
1033 return OpenACCPresentClause::Create(Ctx, Clause.getBeginLoc(),
1034 Clause.getLParenLoc(),
1035 Clause.getVarList(), Clause.getEndLoc());
1038 OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyClause(
1039 SemaOpenACC::OpenACCParsedClause &Clause) {
1040 // Restrictions only properly implemented on 'compute'/'combined'/'data'
1041 // constructs, and 'compute'/'combined'/'data' constructs are the only
1042 // construct that can do anything with this yet, so skip/treat as
1043 // unimplemented in this case.
1044 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1045 return isNotImplemented();
1046 // ActOnVar ensured that everything is a valid variable reference, so there
1047 // really isn't anything to do here. GCC does some duplicate-finding, though
1048 // it isn't apparent in the standard where this is justified.
1050 return OpenACCCopyClause::Create(
1051 Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
1052 Clause.getVarList(), Clause.getEndLoc());
1055 OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyInClause(
1056 SemaOpenACC::OpenACCParsedClause &Clause) {
1057 // Restrictions only properly implemented on 'compute'/'combined'/'data'
1058 // constructs, and 'compute'/'combined'/'data' constructs are the only
1059 // construct that can do anything with this yet, so skip/treat as
1060 // unimplemented in this case.
1061 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1062 return isNotImplemented();
1063 // ActOnVar ensured that everything is a valid variable reference, so there
1064 // really isn't anything to do here. GCC does some duplicate-finding, though
1065 // it isn't apparent in the standard where this is justified.
1067 return OpenACCCopyInClause::Create(
1068 Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
1069 Clause.isReadOnly(), Clause.getVarList(), Clause.getEndLoc());
1072 OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyOutClause(
1073 SemaOpenACC::OpenACCParsedClause &Clause) {
1074 // Restrictions only properly implemented on 'compute'/'combined'/'data'
1075 // constructs, and 'compute'/'combined'/'data' constructs are the only
1076 // construct that can do anything with this yet, so skip/treat as
1077 // unimplemented in this case.
1078 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1079 return isNotImplemented();
1080 // ActOnVar ensured that everything is a valid variable reference, so there
1081 // really isn't anything to do here. GCC does some duplicate-finding, though
1082 // it isn't apparent in the standard where this is justified.
1084 return OpenACCCopyOutClause::Create(
1085 Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
1086 Clause.isZero(), Clause.getVarList(), Clause.getEndLoc());
1089 OpenACCClause *SemaOpenACCClauseVisitor::VisitCreateClause(
1090 SemaOpenACC::OpenACCParsedClause &Clause) {
1091 // ActOnVar ensured that everything is a valid variable reference, so there
1092 // really isn't anything to do here. GCC does some duplicate-finding, though
1093 // it isn't apparent in the standard where this is justified.
1095 return OpenACCCreateClause::Create(
1096 Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
1097 Clause.isZero(), Clause.getVarList(), Clause.getEndLoc());
1100 OpenACCClause *SemaOpenACCClauseVisitor::VisitAttachClause(
1101 SemaOpenACC::OpenACCParsedClause &Clause) {
1102 // ActOnVar ensured that everything is a valid variable reference, but we
1103 // still have to make sure it is a pointer type.
1104 llvm::SmallVector<Expr *> VarList{Clause.getVarList()};
1105 llvm::erase_if(VarList, [&](Expr *E) {
1106 return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::Attach, E);
1108 Clause.setVarListDetails(VarList,
1109 /*IsReadOnly=*/false, /*IsZero=*/false);
1110 return OpenACCAttachClause::Create(Ctx, Clause.getBeginLoc(),
1111 Clause.getLParenLoc(), Clause.getVarList(),
1112 Clause.getEndLoc());
1115 OpenACCClause *SemaOpenACCClauseVisitor::VisitDetachClause(
1116 SemaOpenACC::OpenACCParsedClause &Clause) {
1117 // ActOnVar ensured that everything is a valid variable reference, but we
1118 // still have to make sure it is a pointer type.
1119 llvm::SmallVector<Expr *> VarList{Clause.getVarList()};
1120 llvm::erase_if(VarList, [&](Expr *E) {
1121 return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::Detach, E);
1123 Clause.setVarListDetails(VarList,
1124 /*IsReadOnly=*/false, /*IsZero=*/false);
1125 return OpenACCDetachClause::Create(Ctx, Clause.getBeginLoc(),
1126 Clause.getLParenLoc(), Clause.getVarList(),
1127 Clause.getEndLoc());
1130 OpenACCClause *SemaOpenACCClauseVisitor::VisitDeleteClause(
1131 SemaOpenACC::OpenACCParsedClause &Clause) {
1132 // ActOnVar ensured that everything is a valid variable reference, so there
1133 // really isn't anything to do here. GCC does some duplicate-finding, though
1134 // it isn't apparent in the standard where this is justified.
1135 return OpenACCDeleteClause::Create(Ctx, Clause.getBeginLoc(),
1136 Clause.getLParenLoc(), Clause.getVarList(),
1137 Clause.getEndLoc());
1140 OpenACCClause *SemaOpenACCClauseVisitor::VisitUseDeviceClause(
1141 SemaOpenACC::OpenACCParsedClause &Clause) {
1142 // ActOnVar ensured that everything is a valid variable or array, so nothing
1143 // left to do here.
1144 return OpenACCUseDeviceClause::Create(
1145 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(),
1146 Clause.getEndLoc());
1149 OpenACCClause *SemaOpenACCClauseVisitor::VisitDevicePtrClause(
1150 SemaOpenACC::OpenACCParsedClause &Clause) {
1151 // Restrictions only properly implemented on 'compute'/'combined'/'data'
1152 // constructs, and 'compute'/'combined'/'data' constructs are the only
1153 // construct that can do anything with this yet, so skip/treat as
1154 // unimplemented in this case.
1155 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1156 return isNotImplemented();
1158 // ActOnVar ensured that everything is a valid variable reference, but we
1159 // still have to make sure it is a pointer type.
1160 llvm::SmallVector<Expr *> VarList{Clause.getVarList()};
1161 llvm::erase_if(VarList, [&](Expr *E) {
1162 return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::DevicePtr, E);
1164 Clause.setVarListDetails(VarList,
1165 /*IsReadOnly=*/false, /*IsZero=*/false);
1167 return OpenACCDevicePtrClause::Create(
1168 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(),
1169 Clause.getEndLoc());
1172 OpenACCClause *SemaOpenACCClauseVisitor::VisitWaitClause(
1173 SemaOpenACC::OpenACCParsedClause &Clause) {
1174 return OpenACCWaitClause::Create(
1175 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getDevNumExpr(),
1176 Clause.getQueuesLoc(), Clause.getQueueIdExprs(), Clause.getEndLoc());
1179 OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceTypeClause(
1180 SemaOpenACC::OpenACCParsedClause &Clause) {
1181 // Restrictions only properly implemented on 'compute', 'combined', 'data' and
1182 // 'loop' constructs, and 'compute'/'combined'/'data'/'loop' constructs are
1183 // the only construct that can do anything with this yet, so skip/treat as
1184 // unimplemented in this case.
1185 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1186 return isNotImplemented();
1188 // OpenACC 3.3 2.14.3: Two instances of the same clause may not appear on the
1189 // same directive.
1190 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Set &&
1191 checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
1192 return nullptr;
1194 // TODO OpenACC: Once we get enough of the CodeGen implemented that we have
1195 // a source for the list of valid architectures, we need to warn on unknown
1196 // identifiers here.
1198 return OpenACCDeviceTypeClause::Create(
1199 Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
1200 Clause.getDeviceTypeArchitectures(), Clause.getEndLoc());
1203 OpenACCClause *SemaOpenACCClauseVisitor::VisitAutoClause(
1204 SemaOpenACC::OpenACCParsedClause &Clause) {
1205 // OpenACC 3.3 2.9:
1206 // Only one of the seq, independent, and auto clauses may appear.
1207 const auto *Itr =
1208 llvm::find_if(ExistingClauses,
1209 llvm::IsaPred<OpenACCIndependentClause, OpenACCSeqClause>);
1210 if (Itr != ExistingClauses.end()) {
1211 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict)
1212 << Clause.getClauseKind() << Clause.getDirectiveKind();
1213 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1214 return nullptr;
1217 return OpenACCAutoClause::Create(Ctx, Clause.getBeginLoc(),
1218 Clause.getEndLoc());
1221 OpenACCClause *SemaOpenACCClauseVisitor::VisitIndependentClause(
1222 SemaOpenACC::OpenACCParsedClause &Clause) {
1223 // OpenACC 3.3 2.9:
1224 // Only one of the seq, independent, and auto clauses may appear.
1225 const auto *Itr = llvm::find_if(
1226 ExistingClauses, llvm::IsaPred<OpenACCAutoClause, OpenACCSeqClause>);
1227 if (Itr != ExistingClauses.end()) {
1228 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict)
1229 << Clause.getClauseKind() << Clause.getDirectiveKind();
1230 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1231 return nullptr;
1234 return OpenACCIndependentClause::Create(Ctx, Clause.getBeginLoc(),
1235 Clause.getEndLoc());
1238 ExprResult CheckGangStaticExpr(SemaOpenACC &S, Expr *E) {
1239 if (isa<OpenACCAsteriskSizeExpr>(E))
1240 return E;
1241 return S.ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Gang,
1242 E->getBeginLoc(), E);
1245 bool IsOrphanLoop(OpenACCDirectiveKind DK, OpenACCDirectiveKind AssocKind) {
1246 return DK == OpenACCDirectiveKind::Loop &&
1247 AssocKind == OpenACCDirectiveKind::Invalid;
1250 bool HasAssocKind(OpenACCDirectiveKind DK, OpenACCDirectiveKind AssocKind) {
1251 return DK == OpenACCDirectiveKind::Loop &&
1252 AssocKind != OpenACCDirectiveKind::Invalid;
1255 ExprResult DiagIntArgInvalid(SemaOpenACC &S, Expr *E, OpenACCGangKind GK,
1256 OpenACCClauseKind CK, OpenACCDirectiveKind DK,
1257 OpenACCDirectiveKind AssocKind) {
1258 S.Diag(E->getBeginLoc(), diag::err_acc_int_arg_invalid)
1259 << GK << CK << IsOrphanLoop(DK, AssocKind) << DK
1260 << HasAssocKind(DK, AssocKind) << AssocKind;
1261 return ExprError();
1263 ExprResult DiagIntArgInvalid(SemaOpenACC &S, Expr *E, StringRef TagKind,
1264 OpenACCClauseKind CK, OpenACCDirectiveKind DK,
1265 OpenACCDirectiveKind AssocKind) {
1266 S.Diag(E->getBeginLoc(), diag::err_acc_int_arg_invalid)
1267 << TagKind << CK << IsOrphanLoop(DK, AssocKind) << DK
1268 << HasAssocKind(DK, AssocKind) << AssocKind;
1269 return ExprError();
1272 ExprResult CheckGangParallelExpr(SemaOpenACC &S, OpenACCDirectiveKind DK,
1273 OpenACCDirectiveKind AssocKind,
1274 OpenACCGangKind GK, Expr *E) {
1275 switch (GK) {
1276 case OpenACCGangKind::Static:
1277 return CheckGangStaticExpr(S, E);
1278 case OpenACCGangKind::Num:
1279 // OpenACC 3.3 2.9.2: When the parent compute construct is a parallel
1280 // construct, or an orphaned loop construct, the gang clause behaves as
1281 // follows. ... The num argument is not allowed.
1282 return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind);
1283 case OpenACCGangKind::Dim: {
1284 // OpenACC 3.3 2.9.2: When the parent compute construct is a parallel
1285 // construct, or an orphaned loop construct, the gang clause behaves as
1286 // follows. ... The dim argument must be a constant positive integer value
1287 // 1, 2, or 3.
1288 if (!E)
1289 return ExprError();
1290 ExprResult Res =
1291 S.ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Gang,
1292 E->getBeginLoc(), E);
1294 if (!Res.isUsable())
1295 return Res;
1297 if (Res.get()->isInstantiationDependent())
1298 return Res;
1300 std::optional<llvm::APSInt> ICE =
1301 Res.get()->getIntegerConstantExpr(S.getASTContext());
1303 if (!ICE || *ICE <= 0 || ICE > 3) {
1304 S.Diag(Res.get()->getBeginLoc(), diag::err_acc_gang_dim_value)
1305 << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue();
1306 return ExprError();
1309 return ExprResult{
1310 ConstantExpr::Create(S.getASTContext(), Res.get(), APValue{*ICE})};
1313 llvm_unreachable("Unknown gang kind in gang parallel check");
1316 ExprResult CheckGangKernelsExpr(SemaOpenACC &S,
1317 ArrayRef<const OpenACCClause *> ExistingClauses,
1318 OpenACCDirectiveKind DK,
1319 OpenACCDirectiveKind AssocKind,
1320 OpenACCGangKind GK, Expr *E) {
1321 switch (GK) {
1322 // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
1323 // construct, the gang clause behaves as follows. ... The dim argument is
1324 // not allowed.
1325 case OpenACCGangKind::Dim:
1326 return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind);
1327 case OpenACCGangKind::Num: {
1328 // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
1329 // construct, the gang clause behaves as follows. ... An argument with no
1330 // keyword or with num keyword is only allowed when num_gangs does not
1331 // appear on the kernels construct. ... The region of a loop with the gang
1332 // clause may not contain another loop with a gang clause unless within a
1333 // nested compute region.
1335 // If this is a 'combined' construct, search the list of existing clauses.
1336 // Else we need to search the containing 'kernel'.
1337 auto Collection = isOpenACCCombinedDirectiveKind(DK)
1338 ? ExistingClauses
1339 : S.getActiveComputeConstructInfo().Clauses;
1341 const auto *Itr =
1342 llvm::find_if(Collection, llvm::IsaPred<OpenACCNumGangsClause>);
1344 if (Itr != Collection.end()) {
1345 S.Diag(E->getBeginLoc(), diag::err_acc_num_arg_conflict)
1346 << "num" << OpenACCClauseKind::Gang << DK
1347 << HasAssocKind(DK, AssocKind) << AssocKind
1348 << OpenACCClauseKind::NumGangs;
1350 S.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1351 return ExprError();
1353 return ExprResult{E};
1355 case OpenACCGangKind::Static:
1356 return CheckGangStaticExpr(S, E);
1357 return ExprError();
1359 llvm_unreachable("Unknown gang kind in gang kernels check");
1362 ExprResult CheckGangSerialExpr(SemaOpenACC &S, OpenACCDirectiveKind DK,
1363 OpenACCDirectiveKind AssocKind,
1364 OpenACCGangKind GK, Expr *E) {
1365 switch (GK) {
1366 // 'dim' and 'num' don't really make sense on serial, and GCC rejects them
1367 // too, so we disallow them too.
1368 case OpenACCGangKind::Dim:
1369 case OpenACCGangKind::Num:
1370 return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind);
1371 case OpenACCGangKind::Static:
1372 return CheckGangStaticExpr(S, E);
1374 llvm_unreachable("Unknown gang kind in gang serial check");
1377 OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorClause(
1378 SemaOpenACC::OpenACCParsedClause &Clause) {
1379 if (DiagIfSeqClause(Clause))
1380 return nullptr;
1382 // Restrictions only properly implemented on 'loop'/'combined' constructs, and
1383 // it is the only construct that can do anything with this, so skip/treat as
1384 // unimplemented for the routine constructs.
1385 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1386 return isNotImplemented();
1388 Expr *IntExpr =
1389 Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr;
1390 if (IntExpr) {
1391 if (!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) {
1392 switch (SemaRef.getActiveComputeConstructInfo().Kind) {
1393 case OpenACCDirectiveKind::Invalid:
1394 case OpenACCDirectiveKind::Parallel:
1395 // No restriction on when 'parallel' can contain an argument.
1396 break;
1397 case OpenACCDirectiveKind::Serial:
1398 // GCC disallows this, and there is no real good reason for us to permit
1399 // it, so disallow until we come up with a use case that makes sense.
1400 DiagIntArgInvalid(SemaRef, IntExpr, "length", OpenACCClauseKind::Vector,
1401 Clause.getDirectiveKind(),
1402 SemaRef.getActiveComputeConstructInfo().Kind);
1403 IntExpr = nullptr;
1404 break;
1405 case OpenACCDirectiveKind::Kernels: {
1406 const auto *Itr =
1407 llvm::find_if(SemaRef.getActiveComputeConstructInfo().Clauses,
1408 llvm::IsaPred<OpenACCVectorLengthClause>);
1409 if (Itr != SemaRef.getActiveComputeConstructInfo().Clauses.end()) {
1410 SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1411 << "length" << OpenACCClauseKind::Vector
1412 << Clause.getDirectiveKind()
1413 << HasAssocKind(Clause.getDirectiveKind(),
1414 SemaRef.getActiveComputeConstructInfo().Kind)
1415 << SemaRef.getActiveComputeConstructInfo().Kind
1416 << OpenACCClauseKind::VectorLength;
1417 SemaRef.Diag((*Itr)->getBeginLoc(),
1418 diag::note_acc_previous_clause_here);
1420 IntExpr = nullptr;
1422 break;
1424 default:
1425 llvm_unreachable("Non compute construct in active compute construct");
1427 } else {
1428 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::SerialLoop) {
1429 DiagIntArgInvalid(SemaRef, IntExpr, "length", OpenACCClauseKind::Vector,
1430 Clause.getDirectiveKind(),
1431 SemaRef.getActiveComputeConstructInfo().Kind);
1432 IntExpr = nullptr;
1433 } else if (Clause.getDirectiveKind() ==
1434 OpenACCDirectiveKind::KernelsLoop) {
1435 const auto *Itr = llvm::find_if(
1436 ExistingClauses, llvm::IsaPred<OpenACCVectorLengthClause>);
1437 if (Itr != ExistingClauses.end()) {
1438 SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1439 << "length" << OpenACCClauseKind::Vector
1440 << Clause.getDirectiveKind()
1441 << HasAssocKind(Clause.getDirectiveKind(),
1442 SemaRef.getActiveComputeConstructInfo().Kind)
1443 << SemaRef.getActiveComputeConstructInfo().Kind
1444 << OpenACCClauseKind::VectorLength;
1445 SemaRef.Diag((*Itr)->getBeginLoc(),
1446 diag::note_acc_previous_clause_here);
1448 IntExpr = nullptr;
1454 if (!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) {
1455 // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1456 // contain a loop with a gang, worker, or vector clause unless within a
1457 // nested compute region.
1458 if (SemaRef.LoopVectorClauseLoc.isValid()) {
1459 // This handles the 'inner loop' diagnostic, but we cannot set that we're
1460 // on one of these until we get to the end of the construct.
1461 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1462 << OpenACCClauseKind::Vector << OpenACCClauseKind::Vector
1463 << /*skip kernels construct info*/ 0;
1464 SemaRef.Diag(SemaRef.LoopVectorClauseLoc,
1465 diag::note_acc_previous_clause_here);
1466 return nullptr;
1470 return OpenACCVectorClause::Create(Ctx, Clause.getBeginLoc(),
1471 Clause.getLParenLoc(), IntExpr,
1472 Clause.getEndLoc());
1475 OpenACCClause *SemaOpenACCClauseVisitor::VisitWorkerClause(
1476 SemaOpenACC::OpenACCParsedClause &Clause) {
1477 if (DiagIfSeqClause(Clause))
1478 return nullptr;
1480 // Restrictions only properly implemented on 'loop'/'combined' constructs, and
1481 // it is the only construct that can do anything with this, so skip/treat as
1482 // unimplemented for the routine constructs.
1483 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1484 return isNotImplemented();
1486 Expr *IntExpr =
1487 Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr;
1489 if (IntExpr) {
1490 if (!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) {
1491 switch (SemaRef.getActiveComputeConstructInfo().Kind) {
1492 case OpenACCDirectiveKind::Invalid:
1493 case OpenACCDirectiveKind::ParallelLoop:
1494 case OpenACCDirectiveKind::SerialLoop:
1495 case OpenACCDirectiveKind::Parallel:
1496 case OpenACCDirectiveKind::Serial:
1497 DiagIntArgInvalid(SemaRef, IntExpr, OpenACCGangKind::Num,
1498 OpenACCClauseKind::Worker, Clause.getDirectiveKind(),
1499 SemaRef.getActiveComputeConstructInfo().Kind);
1500 IntExpr = nullptr;
1501 break;
1502 case OpenACCDirectiveKind::KernelsLoop:
1503 case OpenACCDirectiveKind::Kernels: {
1504 const auto *Itr =
1505 llvm::find_if(SemaRef.getActiveComputeConstructInfo().Clauses,
1506 llvm::IsaPred<OpenACCNumWorkersClause>);
1507 if (Itr != SemaRef.getActiveComputeConstructInfo().Clauses.end()) {
1508 SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1509 << "num" << OpenACCClauseKind::Worker << Clause.getDirectiveKind()
1510 << HasAssocKind(Clause.getDirectiveKind(),
1511 SemaRef.getActiveComputeConstructInfo().Kind)
1512 << SemaRef.getActiveComputeConstructInfo().Kind
1513 << OpenACCClauseKind::NumWorkers;
1514 SemaRef.Diag((*Itr)->getBeginLoc(),
1515 diag::note_acc_previous_clause_here);
1517 IntExpr = nullptr;
1519 break;
1521 default:
1522 llvm_unreachable("Non compute construct in active compute construct");
1524 } else {
1525 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop ||
1526 Clause.getDirectiveKind() == OpenACCDirectiveKind::SerialLoop) {
1527 DiagIntArgInvalid(SemaRef, IntExpr, OpenACCGangKind::Num,
1528 OpenACCClauseKind::Worker, Clause.getDirectiveKind(),
1529 SemaRef.getActiveComputeConstructInfo().Kind);
1530 IntExpr = nullptr;
1531 } else {
1532 assert(Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop &&
1533 "Unknown combined directive kind?");
1534 const auto *Itr = llvm::find_if(ExistingClauses,
1535 llvm::IsaPred<OpenACCNumWorkersClause>);
1536 if (Itr != ExistingClauses.end()) {
1537 SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1538 << "num" << OpenACCClauseKind::Worker << Clause.getDirectiveKind()
1539 << HasAssocKind(Clause.getDirectiveKind(),
1540 SemaRef.getActiveComputeConstructInfo().Kind)
1541 << SemaRef.getActiveComputeConstructInfo().Kind
1542 << OpenACCClauseKind::NumWorkers;
1543 SemaRef.Diag((*Itr)->getBeginLoc(),
1544 diag::note_acc_previous_clause_here);
1546 IntExpr = nullptr;
1552 if (!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) {
1553 // OpenACC 3.3 2.9.3: The region of a loop with a 'worker' clause may not
1554 // contain a loop with a gang or worker clause unless within a nested
1555 // compute region.
1556 if (SemaRef.LoopWorkerClauseLoc.isValid()) {
1557 // This handles the 'inner loop' diagnostic, but we cannot set that we're
1558 // on one of these until we get to the end of the construct.
1559 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1560 << OpenACCClauseKind::Worker << OpenACCClauseKind::Worker
1561 << /*skip kernels construct info*/ 0;
1562 SemaRef.Diag(SemaRef.LoopWorkerClauseLoc,
1563 diag::note_acc_previous_clause_here);
1564 return nullptr;
1567 // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1568 // contain a loop with a gang, worker, or vector clause unless within a
1569 // nested compute region.
1570 if (SemaRef.LoopVectorClauseLoc.isValid()) {
1571 // This handles the 'inner loop' diagnostic, but we cannot set that we're
1572 // on one of these until we get to the end of the construct.
1573 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1574 << OpenACCClauseKind::Worker << OpenACCClauseKind::Vector
1575 << /*skip kernels construct info*/ 0;
1576 SemaRef.Diag(SemaRef.LoopVectorClauseLoc,
1577 diag::note_acc_previous_clause_here);
1578 return nullptr;
1582 return OpenACCWorkerClause::Create(Ctx, Clause.getBeginLoc(),
1583 Clause.getLParenLoc(), IntExpr,
1584 Clause.getEndLoc());
1587 OpenACCClause *SemaOpenACCClauseVisitor::VisitGangClause(
1588 SemaOpenACC::OpenACCParsedClause &Clause) {
1589 if (DiagIfSeqClause(Clause))
1590 return nullptr;
1592 // Restrictions only properly implemented on 'loop' constructs, and it is
1593 // the only construct that can do anything with this, so skip/treat as
1594 // unimplemented for the combined constructs.
1595 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1596 return isNotImplemented();
1598 // OpenACC 3.3 Section 2.9.11: A reduction clause may not appear on a loop
1599 // directive that has a gang clause and is within a compute construct that has
1600 // a num_gangs clause with more than one explicit argument.
1601 if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop &&
1602 SemaRef.getActiveComputeConstructInfo().Kind !=
1603 OpenACCDirectiveKind::Invalid) ||
1604 isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) {
1605 // num_gangs clause on the active compute construct.
1606 auto ActiveComputeConstructContainer =
1607 isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())
1608 ? ExistingClauses
1609 : SemaRef.getActiveComputeConstructInfo().Clauses;
1610 auto *NumGangsClauseItr = llvm::find_if(
1611 ActiveComputeConstructContainer, llvm::IsaPred<OpenACCNumGangsClause>);
1613 if (NumGangsClauseItr != ActiveComputeConstructContainer.end() &&
1614 cast<OpenACCNumGangsClause>(*NumGangsClauseItr)->getIntExprs().size() >
1615 1) {
1616 auto *ReductionClauseItr =
1617 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>);
1619 if (ReductionClauseItr != ExistingClauses.end()) {
1620 SemaRef.Diag(Clause.getBeginLoc(),
1621 diag::err_acc_gang_reduction_numgangs_conflict)
1622 << OpenACCClauseKind::Gang << OpenACCClauseKind::Reduction
1623 << Clause.getDirectiveKind()
1624 << isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind());
1625 SemaRef.Diag((*ReductionClauseItr)->getBeginLoc(),
1626 diag::note_acc_previous_clause_here);
1627 SemaRef.Diag((*NumGangsClauseItr)->getBeginLoc(),
1628 diag::note_acc_previous_clause_here);
1629 return nullptr;
1634 llvm::SmallVector<OpenACCGangKind> GangKinds;
1635 llvm::SmallVector<Expr *> IntExprs;
1637 // Store the existing locations, so we can do duplicate checking. Index is
1638 // the int-value of the OpenACCGangKind enum.
1639 SourceLocation ExistingElemLoc[3];
1641 for (unsigned I = 0; I < Clause.getIntExprs().size(); ++I) {
1642 OpenACCGangKind GK = Clause.getGangKinds()[I];
1643 ExprResult ER =
1644 SemaRef.CheckGangExpr(ExistingClauses, Clause.getDirectiveKind(), GK,
1645 Clause.getIntExprs()[I]);
1647 if (!ER.isUsable())
1648 continue;
1650 // OpenACC 3.3 2.9: 'gang-arg-list' may have at most one num, one dim, and
1651 // one static argument.
1652 if (ExistingElemLoc[static_cast<unsigned>(GK)].isValid()) {
1653 SemaRef.Diag(ER.get()->getBeginLoc(), diag::err_acc_gang_multiple_elt)
1654 << static_cast<unsigned>(GK);
1655 SemaRef.Diag(ExistingElemLoc[static_cast<unsigned>(GK)],
1656 diag::note_acc_previous_expr_here);
1657 continue;
1660 ExistingElemLoc[static_cast<unsigned>(GK)] = ER.get()->getBeginLoc();
1661 GangKinds.push_back(GK);
1662 IntExprs.push_back(ER.get());
1665 if (!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) {
1666 // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
1667 // construct, the gang clause behaves as follows. ... The region of a loop
1668 // with a gang clause may not contain another loop with a gang clause unless
1669 // within a nested compute region.
1670 if (SemaRef.LoopGangClauseOnKernel.Loc.isValid()) {
1671 // This handles the 'inner loop' diagnostic, but we cannot set that we're
1672 // on one of these until we get to the end of the construct.
1673 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1674 << OpenACCClauseKind::Gang << OpenACCClauseKind::Gang
1675 << /*kernels construct info*/ 1
1676 << SemaRef.LoopGangClauseOnKernel.DirKind;
1677 SemaRef.Diag(SemaRef.LoopGangClauseOnKernel.Loc,
1678 diag::note_acc_previous_clause_here);
1679 return nullptr;
1682 // OpenACC 3.3 2.9.3: The region of a loop with a 'worker' clause may not
1683 // contain a loop with a gang or worker clause unless within a nested
1684 // compute region.
1685 if (SemaRef.LoopWorkerClauseLoc.isValid()) {
1686 // This handles the 'inner loop' diagnostic, but we cannot set that we're
1687 // on one of these until we get to the end of the construct.
1688 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1689 << OpenACCClauseKind::Gang << OpenACCClauseKind::Worker
1690 << /*!kernels construct info*/ 0;
1691 SemaRef.Diag(SemaRef.LoopWorkerClauseLoc,
1692 diag::note_acc_previous_clause_here);
1693 return nullptr;
1696 // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1697 // contain a loop with a gang, worker, or vector clause unless within a
1698 // nested compute region.
1699 if (SemaRef.LoopVectorClauseLoc.isValid()) {
1700 // This handles the 'inner loop' diagnostic, but we cannot set that we're
1701 // on one of these until we get to the end of the construct.
1702 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1703 << OpenACCClauseKind::Gang << OpenACCClauseKind::Vector
1704 << /*!kernels construct info*/ 0;
1705 SemaRef.Diag(SemaRef.LoopVectorClauseLoc,
1706 diag::note_acc_previous_clause_here);
1707 return nullptr;
1711 return SemaRef.CheckGangClause(Clause.getDirectiveKind(), ExistingClauses,
1712 Clause.getBeginLoc(), Clause.getLParenLoc(),
1713 GangKinds, IntExprs, Clause.getEndLoc());
1716 OpenACCClause *SemaOpenACCClauseVisitor::VisitFinalizeClause(
1717 SemaOpenACC::OpenACCParsedClause &Clause) {
1718 // There isn't anything to do here, this is only valid on one construct, and
1719 // has no associated rules.
1720 return OpenACCFinalizeClause::Create(Ctx, Clause.getBeginLoc(),
1721 Clause.getEndLoc());
1724 OpenACCClause *SemaOpenACCClauseVisitor::VisitIfPresentClause(
1725 SemaOpenACC::OpenACCParsedClause &Clause) {
1726 // There isn't anything to do here, this is only valid on one construct, and
1727 // has no associated rules.
1728 return OpenACCIfPresentClause::Create(Ctx, Clause.getBeginLoc(),
1729 Clause.getEndLoc());
1732 OpenACCClause *SemaOpenACCClauseVisitor::VisitSeqClause(
1733 SemaOpenACC::OpenACCParsedClause &Clause) {
1734 // Restrictions only properly implemented on 'loop' constructs and combined ,
1735 // and it is the only construct that can do anything with this, so skip/treat
1736 // as unimplemented for the routine constructs.
1737 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1738 return isNotImplemented();
1740 // OpenACC 3.3 2.9:
1741 // Only one of the seq, independent, and auto clauses may appear.
1742 const auto *Itr =
1743 llvm::find_if(ExistingClauses,
1744 llvm::IsaPred<OpenACCAutoClause, OpenACCIndependentClause>);
1745 if (Itr != ExistingClauses.end()) {
1746 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict)
1747 << Clause.getClauseKind() << Clause.getDirectiveKind();
1748 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1749 return nullptr;
1752 // OpenACC 3.3 2.9:
1753 // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' clause
1754 // appears.
1755 Itr = llvm::find_if(ExistingClauses,
1756 llvm::IsaPred<OpenACCGangClause, OpenACCWorkerClause,
1757 OpenACCVectorClause>);
1759 if (Itr != ExistingClauses.end()) {
1760 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine)
1761 << Clause.getClauseKind() << (*Itr)->getClauseKind()
1762 << Clause.getDirectiveKind();
1763 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1764 return nullptr;
1767 return OpenACCSeqClause::Create(Ctx, Clause.getBeginLoc(),
1768 Clause.getEndLoc());
1771 OpenACCClause *SemaOpenACCClauseVisitor::VisitReductionClause(
1772 SemaOpenACC::OpenACCParsedClause &Clause) {
1773 // OpenACC 3.3 Section 2.9.11: A reduction clause may not appear on a loop
1774 // directive that has a gang clause and is within a compute construct that has
1775 // a num_gangs clause with more than one explicit argument.
1776 if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop &&
1777 SemaRef.getActiveComputeConstructInfo().Kind !=
1778 OpenACCDirectiveKind::Invalid) ||
1779 isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) {
1780 // num_gangs clause on the active compute construct.
1781 auto ActiveComputeConstructContainer =
1782 isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())
1783 ? ExistingClauses
1784 : SemaRef.getActiveComputeConstructInfo().Clauses;
1785 auto *NumGangsClauseItr = llvm::find_if(
1786 ActiveComputeConstructContainer, llvm::IsaPred<OpenACCNumGangsClause>);
1788 if (NumGangsClauseItr != ActiveComputeConstructContainer.end() &&
1789 cast<OpenACCNumGangsClause>(*NumGangsClauseItr)->getIntExprs().size() >
1790 1) {
1791 auto *GangClauseItr =
1792 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCGangClause>);
1794 if (GangClauseItr != ExistingClauses.end()) {
1795 SemaRef.Diag(Clause.getBeginLoc(),
1796 diag::err_acc_gang_reduction_numgangs_conflict)
1797 << OpenACCClauseKind::Reduction << OpenACCClauseKind::Gang
1798 << Clause.getDirectiveKind()
1799 << isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind());
1800 SemaRef.Diag((*GangClauseItr)->getBeginLoc(),
1801 diag::note_acc_previous_clause_here);
1802 SemaRef.Diag((*NumGangsClauseItr)->getBeginLoc(),
1803 diag::note_acc_previous_clause_here);
1804 return nullptr;
1809 // OpenACC3.3 Section 2.9.11: If a variable is involved in a reduction that
1810 // spans multiple nested loops where two or more of those loops have
1811 // associated loop directives, a reduction clause containing that variable
1812 // must appear on each of those loop directives.
1814 // This can't really be implemented in the CFE, as this requires a level of
1815 // rechability/useage analysis that we're not really wanting to get into.
1816 // Additionally, I'm alerted that this restriction is one that the middle-end
1817 // can just 'figure out' as an extension and isn't really necessary.
1819 // OpenACC3.3 Section 2.9.11: Every 'var' in a reduction clause appearing on
1820 // an orphaned loop construct must be private.
1822 // This again is something we cannot really diagnose, as it requires we see
1823 // all the uses/scopes of all variables referenced. The middle end/MLIR might
1824 // be able to diagnose this.
1826 // OpenACC 3.3 Section 2.5.4:
1827 // A reduction clause may not appear on a parallel construct with a
1828 // num_gangs clause that has more than one argument.
1829 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel ||
1830 Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop) {
1831 auto NumGangsClauses = llvm::make_filter_range(
1832 ExistingClauses, llvm::IsaPred<OpenACCNumGangsClause>);
1834 for (auto *NGC : NumGangsClauses) {
1835 unsigned NumExprs =
1836 cast<OpenACCNumGangsClause>(NGC)->getIntExprs().size();
1838 if (NumExprs > 1) {
1839 SemaRef.Diag(Clause.getBeginLoc(),
1840 diag::err_acc_reduction_num_gangs_conflict)
1841 << /*>1 arg in first loc=*/0 << Clause.getClauseKind()
1842 << Clause.getDirectiveKind() << OpenACCClauseKind::NumGangs;
1843 SemaRef.Diag(NGC->getBeginLoc(), diag::note_acc_previous_clause_here);
1844 return nullptr;
1849 SmallVector<Expr *> ValidVars;
1851 for (Expr *Var : Clause.getVarList()) {
1852 ExprResult Res = SemaRef.CheckReductionVar(Clause.getDirectiveKind(),
1853 Clause.getReductionOp(), Var);
1855 if (Res.isUsable())
1856 ValidVars.push_back(Res.get());
1859 return SemaRef.CheckReductionClause(
1860 ExistingClauses, Clause.getDirectiveKind(), Clause.getBeginLoc(),
1861 Clause.getLParenLoc(), Clause.getReductionOp(), ValidVars,
1862 Clause.getEndLoc());
1865 OpenACCClause *SemaOpenACCClauseVisitor::VisitCollapseClause(
1866 SemaOpenACC::OpenACCParsedClause &Clause) {
1867 // Duplicates here are not really sensible. We could possible permit
1868 // multiples if they all had the same value, but there isn't really a good
1869 // reason to do so. Also, this simplifies the suppression of duplicates, in
1870 // that we know if we 'find' one after instantiation, that it is the same
1871 // clause, which simplifies instantiation/checking/etc.
1872 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
1873 return nullptr;
1875 ExprResult LoopCount = SemaRef.CheckCollapseLoopCount(Clause.getLoopCount());
1877 if (!LoopCount.isUsable())
1878 return nullptr;
1880 return OpenACCCollapseClause::Create(Ctx, Clause.getBeginLoc(),
1881 Clause.getLParenLoc(), Clause.isForce(),
1882 LoopCount.get(), Clause.getEndLoc());
1885 void CollectActiveReductionClauses(
1886 llvm::SmallVector<OpenACCReductionClause *> &ActiveClauses,
1887 ArrayRef<OpenACCClause *> CurClauses) {
1888 for (auto *CurClause : CurClauses) {
1889 if (auto *RedClause = dyn_cast<OpenACCReductionClause>(CurClause);
1890 RedClause && !RedClause->getVarList().empty())
1891 ActiveClauses.push_back(RedClause);
1895 // Depth needs to be preserved for all associated statements that aren't
1896 // supposed to modify the compute/combined/loop construct information.
1897 bool PreserveLoopRAIIDepthInAssociatedStmtRAII(OpenACCDirectiveKind DK) {
1898 switch (DK) {
1899 case OpenACCDirectiveKind::Parallel:
1900 case OpenACCDirectiveKind::ParallelLoop:
1901 case OpenACCDirectiveKind::Serial:
1902 case OpenACCDirectiveKind::SerialLoop:
1903 case OpenACCDirectiveKind::Kernels:
1904 case OpenACCDirectiveKind::KernelsLoop:
1905 case OpenACCDirectiveKind::Loop:
1906 return false;
1907 case OpenACCDirectiveKind::Data:
1908 case OpenACCDirectiveKind::HostData:
1909 return true;
1910 case OpenACCDirectiveKind::EnterData:
1911 case OpenACCDirectiveKind::ExitData:
1912 case OpenACCDirectiveKind::Wait:
1913 case OpenACCDirectiveKind::Init:
1914 case OpenACCDirectiveKind::Shutdown:
1915 case OpenACCDirectiveKind::Set:
1916 case OpenACCDirectiveKind::Update:
1917 llvm_unreachable("Doesn't have an associated stmt");
1918 default:
1919 case OpenACCDirectiveKind::Invalid:
1920 llvm_unreachable("Unhandled directive kind?");
1922 llvm_unreachable("Unhandled directive kind?");
1925 } // namespace
1927 SemaOpenACC::SemaOpenACC(Sema &S) : SemaBase(S) {}
1929 SemaOpenACC::AssociatedStmtRAII::AssociatedStmtRAII(
1930 SemaOpenACC &S, OpenACCDirectiveKind DK, SourceLocation DirLoc,
1931 ArrayRef<const OpenACCClause *> UnInstClauses,
1932 ArrayRef<OpenACCClause *> Clauses)
1933 : SemaRef(S), OldActiveComputeConstructInfo(S.ActiveComputeConstructInfo),
1934 DirKind(DK), OldLoopGangClauseOnKernel(S.LoopGangClauseOnKernel),
1935 OldLoopWorkerClauseLoc(S.LoopWorkerClauseLoc),
1936 OldLoopVectorClauseLoc(S.LoopVectorClauseLoc),
1937 OldLoopWithoutSeqInfo(S.LoopWithoutSeqInfo),
1938 ActiveReductionClauses(S.ActiveReductionClauses),
1939 LoopRAII(SemaRef, PreserveLoopRAIIDepthInAssociatedStmtRAII(DirKind)) {
1941 // Compute constructs end up taking their 'loop'.
1942 if (DirKind == OpenACCDirectiveKind::Parallel ||
1943 DirKind == OpenACCDirectiveKind::Serial ||
1944 DirKind == OpenACCDirectiveKind::Kernels) {
1945 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
1946 SemaRef.ActiveComputeConstructInfo.Kind = DirKind;
1947 SemaRef.ActiveComputeConstructInfo.Clauses = Clauses;
1949 // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
1950 // construct, the gang clause behaves as follows. ... The region of a loop
1951 // with a gang clause may not contain another loop with a gang clause unless
1952 // within a nested compute region.
1954 // Implement the 'unless within a nested compute region' part.
1955 SemaRef.LoopGangClauseOnKernel = {};
1956 SemaRef.LoopWorkerClauseLoc = {};
1957 SemaRef.LoopVectorClauseLoc = {};
1958 SemaRef.LoopWithoutSeqInfo = {};
1959 } else if (DirKind == OpenACCDirectiveKind::ParallelLoop ||
1960 DirKind == OpenACCDirectiveKind::SerialLoop ||
1961 DirKind == OpenACCDirectiveKind::KernelsLoop) {
1962 SemaRef.ActiveComputeConstructInfo.Kind = DirKind;
1963 SemaRef.ActiveComputeConstructInfo.Clauses = Clauses;
1965 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
1966 SetCollapseInfoBeforeAssociatedStmt(UnInstClauses, Clauses);
1967 SetTileInfoBeforeAssociatedStmt(UnInstClauses, Clauses);
1969 SemaRef.LoopGangClauseOnKernel = {};
1970 SemaRef.LoopWorkerClauseLoc = {};
1971 SemaRef.LoopVectorClauseLoc = {};
1973 // Set the active 'loop' location if there isn't a 'seq' on it, so we can
1974 // diagnose the for loops.
1975 SemaRef.LoopWithoutSeqInfo = {};
1976 if (Clauses.end() ==
1977 llvm::find_if(Clauses, llvm::IsaPred<OpenACCSeqClause>))
1978 SemaRef.LoopWithoutSeqInfo = {DirKind, DirLoc};
1980 // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
1981 // construct, the gang clause behaves as follows. ... The region of a loop
1982 // with a gang clause may not contain another loop with a gang clause unless
1983 // within a nested compute region.
1985 // We don't bother doing this when this is a template instantiation, as
1986 // there is no reason to do these checks: the existance of a
1987 // gang/kernels/etc cannot be dependent.
1988 if (DirKind == OpenACCDirectiveKind::KernelsLoop && UnInstClauses.empty()) {
1989 // This handles the 'outer loop' part of this.
1990 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCGangClause>);
1991 if (Itr != Clauses.end())
1992 SemaRef.LoopGangClauseOnKernel = {(*Itr)->getBeginLoc(), DirKind};
1995 if (UnInstClauses.empty()) {
1996 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCWorkerClause>);
1997 if (Itr != Clauses.end())
1998 SemaRef.LoopWorkerClauseLoc = (*Itr)->getBeginLoc();
2000 auto *Itr2 = llvm::find_if(Clauses, llvm::IsaPred<OpenACCVectorClause>);
2001 if (Itr2 != Clauses.end())
2002 SemaRef.LoopVectorClauseLoc = (*Itr2)->getBeginLoc();
2004 } else if (DirKind == OpenACCDirectiveKind::Loop) {
2005 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
2006 SetCollapseInfoBeforeAssociatedStmt(UnInstClauses, Clauses);
2007 SetTileInfoBeforeAssociatedStmt(UnInstClauses, Clauses);
2009 // Set the active 'loop' location if there isn't a 'seq' on it, so we can
2010 // diagnose the for loops.
2011 SemaRef.LoopWithoutSeqInfo = {};
2012 if (Clauses.end() ==
2013 llvm::find_if(Clauses, llvm::IsaPred<OpenACCSeqClause>))
2014 SemaRef.LoopWithoutSeqInfo = {DirKind, DirLoc};
2016 // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
2017 // construct, the gang clause behaves as follows. ... The region of a loop
2018 // with a gang clause may not contain another loop with a gang clause unless
2019 // within a nested compute region.
2021 // We don't bother doing this when this is a template instantiation, as
2022 // there is no reason to do these checks: the existance of a
2023 // gang/kernels/etc cannot be dependent.
2024 if (SemaRef.getActiveComputeConstructInfo().Kind ==
2025 OpenACCDirectiveKind::Kernels &&
2026 UnInstClauses.empty()) {
2027 // This handles the 'outer loop' part of this.
2028 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCGangClause>);
2029 if (Itr != Clauses.end())
2030 SemaRef.LoopGangClauseOnKernel = {(*Itr)->getBeginLoc(),
2031 OpenACCDirectiveKind::Kernels};
2034 if (UnInstClauses.empty()) {
2035 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCWorkerClause>);
2036 if (Itr != Clauses.end())
2037 SemaRef.LoopWorkerClauseLoc = (*Itr)->getBeginLoc();
2039 auto *Itr2 = llvm::find_if(Clauses, llvm::IsaPred<OpenACCVectorClause>);
2040 if (Itr2 != Clauses.end())
2041 SemaRef.LoopVectorClauseLoc = (*Itr2)->getBeginLoc();
2046 void SemaOpenACC::AssociatedStmtRAII::SetCollapseInfoBeforeAssociatedStmt(
2047 ArrayRef<const OpenACCClause *> UnInstClauses,
2048 ArrayRef<OpenACCClause *> Clauses) {
2050 // Reset this checking for loops that aren't covered in a RAII object.
2051 SemaRef.LoopInfo.CurLevelHasLoopAlready = false;
2052 SemaRef.CollapseInfo.CollapseDepthSatisfied = true;
2053 SemaRef.TileInfo.TileDepthSatisfied = true;
2055 // We make sure to take an optional list of uninstantiated clauses, so that
2056 // we can check to make sure we don't 'double diagnose' in the event that
2057 // the value of 'N' was not dependent in a template. We also ensure during
2058 // Sema that there is only 1 collapse on each construct, so we can count on
2059 // the fact that if both find a 'collapse', that they are the same one.
2060 auto *CollapseClauseItr =
2061 llvm::find_if(Clauses, llvm::IsaPred<OpenACCCollapseClause>);
2062 auto *UnInstCollapseClauseItr =
2063 llvm::find_if(UnInstClauses, llvm::IsaPred<OpenACCCollapseClause>);
2065 if (Clauses.end() == CollapseClauseItr)
2066 return;
2068 OpenACCCollapseClause *CollapseClause =
2069 cast<OpenACCCollapseClause>(*CollapseClauseItr);
2071 SemaRef.CollapseInfo.ActiveCollapse = CollapseClause;
2072 Expr *LoopCount = CollapseClause->getLoopCount();
2074 // If the loop count is still instantiation dependent, setting the depth
2075 // counter isn't necessary, so return here.
2076 if (!LoopCount || LoopCount->isInstantiationDependent())
2077 return;
2079 // Suppress diagnostics if we've done a 'transform' where the previous version
2080 // wasn't dependent, meaning we already diagnosed it.
2081 if (UnInstCollapseClauseItr != UnInstClauses.end() &&
2082 !cast<OpenACCCollapseClause>(*UnInstCollapseClauseItr)
2083 ->getLoopCount()
2084 ->isInstantiationDependent())
2085 return;
2087 SemaRef.CollapseInfo.CollapseDepthSatisfied = false;
2088 SemaRef.CollapseInfo.CurCollapseCount =
2089 cast<ConstantExpr>(LoopCount)->getResultAsAPSInt();
2090 SemaRef.CollapseInfo.DirectiveKind = DirKind;
2093 void SemaOpenACC::AssociatedStmtRAII::SetTileInfoBeforeAssociatedStmt(
2094 ArrayRef<const OpenACCClause *> UnInstClauses,
2095 ArrayRef<OpenACCClause *> Clauses) {
2096 // We don't diagnose if this is during instantiation, since the only thing we
2097 // care about is the number of arguments, which we can figure out without
2098 // instantiation, so we don't want to double-diagnose.
2099 if (UnInstClauses.size() > 0)
2100 return;
2101 auto *TileClauseItr =
2102 llvm::find_if(Clauses, llvm::IsaPred<OpenACCTileClause>);
2104 if (Clauses.end() == TileClauseItr)
2105 return;
2107 OpenACCTileClause *TileClause = cast<OpenACCTileClause>(*TileClauseItr);
2108 SemaRef.TileInfo.ActiveTile = TileClause;
2109 SemaRef.TileInfo.TileDepthSatisfied = false;
2110 SemaRef.TileInfo.CurTileCount = TileClause->getSizeExprs().size();
2111 SemaRef.TileInfo.DirectiveKind = DirKind;
2114 SemaOpenACC::AssociatedStmtRAII::~AssociatedStmtRAII() {
2115 if (DirKind == OpenACCDirectiveKind::Parallel ||
2116 DirKind == OpenACCDirectiveKind::Serial ||
2117 DirKind == OpenACCDirectiveKind::Kernels ||
2118 DirKind == OpenACCDirectiveKind::Loop ||
2119 DirKind == OpenACCDirectiveKind::ParallelLoop ||
2120 DirKind == OpenACCDirectiveKind::SerialLoop ||
2121 DirKind == OpenACCDirectiveKind::KernelsLoop) {
2122 SemaRef.ActiveComputeConstructInfo = OldActiveComputeConstructInfo;
2123 SemaRef.LoopGangClauseOnKernel = OldLoopGangClauseOnKernel;
2124 SemaRef.LoopWorkerClauseLoc = OldLoopWorkerClauseLoc;
2125 SemaRef.LoopVectorClauseLoc = OldLoopVectorClauseLoc;
2126 SemaRef.LoopWithoutSeqInfo = OldLoopWithoutSeqInfo;
2127 SemaRef.ActiveReductionClauses.swap(ActiveReductionClauses);
2128 } else if (DirKind == OpenACCDirectiveKind::Data ||
2129 DirKind == OpenACCDirectiveKind::HostData) {
2130 // Intentionally doesn't reset the Loop, Compute Construct, or reduction
2131 // effects.
2135 OpenACCClause *
2136 SemaOpenACC::ActOnClause(ArrayRef<const OpenACCClause *> ExistingClauses,
2137 OpenACCParsedClause &Clause) {
2138 if (Clause.getClauseKind() == OpenACCClauseKind::Invalid)
2139 return nullptr;
2141 // Diagnose that we don't support this clause on this directive.
2142 if (!doesClauseApplyToDirective(Clause.getDirectiveKind(),
2143 Clause.getClauseKind())) {
2144 Diag(Clause.getBeginLoc(), diag::err_acc_clause_appertainment)
2145 << Clause.getDirectiveKind() << Clause.getClauseKind();
2146 return nullptr;
2149 if (const auto *DevTypeClause =
2150 llvm::find_if(ExistingClauses,
2151 [&](const OpenACCClause *C) {
2152 return isa<OpenACCDeviceTypeClause>(C);
2154 DevTypeClause != ExistingClauses.end()) {
2155 if (checkValidAfterDeviceType(
2156 *this, *cast<OpenACCDeviceTypeClause>(*DevTypeClause), Clause))
2157 return nullptr;
2160 SemaOpenACCClauseVisitor Visitor{*this, ExistingClauses};
2161 OpenACCClause *Result = Visitor.Visit(Clause);
2162 assert((!Result || Result->getClauseKind() == Clause.getClauseKind()) &&
2163 "Created wrong clause?");
2165 if (Visitor.diagNotImplemented())
2166 Diag(Clause.getBeginLoc(), diag::warn_acc_clause_unimplemented)
2167 << Clause.getClauseKind();
2169 return Result;
2173 namespace {
2174 // Return true if the two vars refer to the same variable, for the purposes of
2175 // equality checking.
2176 bool areVarsEqual(Expr *VarExpr1, Expr *VarExpr2) {
2177 if (VarExpr1->isInstantiationDependent() ||
2178 VarExpr2->isInstantiationDependent())
2179 return false;
2181 VarExpr1 = VarExpr1->IgnoreParenCasts();
2182 VarExpr2 = VarExpr2->IgnoreParenCasts();
2184 // Legal expressions can be: Scalar variable reference, sub-array, array
2185 // element, or composite variable member.
2187 // Sub-array.
2188 if (isa<ArraySectionExpr>(VarExpr1)) {
2189 auto *Expr2AS = dyn_cast<ArraySectionExpr>(VarExpr2);
2190 if (!Expr2AS)
2191 return false;
2193 auto *Expr1AS = cast<ArraySectionExpr>(VarExpr1);
2195 if (!areVarsEqual(Expr1AS->getBase(), Expr2AS->getBase()))
2196 return false;
2197 // We could possibly check to see if the ranges aren't overlapping, but it
2198 // isn't clear that the rules allow this.
2199 return true;
2202 // Array-element.
2203 if (isa<ArraySubscriptExpr>(VarExpr1)) {
2204 auto *Expr2AS = dyn_cast<ArraySubscriptExpr>(VarExpr2);
2205 if (!Expr2AS)
2206 return false;
2208 auto *Expr1AS = cast<ArraySubscriptExpr>(VarExpr1);
2210 if (!areVarsEqual(Expr1AS->getBase(), Expr2AS->getBase()))
2211 return false;
2213 // We could possibly check to see if the elements referenced aren't the
2214 // same, but it isn't clear by reading of the standard that this is allowed
2215 // (and that the 'var' refered to isn't the array).
2216 return true;
2219 // Scalar variable reference, or composite variable.
2220 if (isa<DeclRefExpr>(VarExpr1)) {
2221 auto *Expr2DRE = dyn_cast<DeclRefExpr>(VarExpr2);
2222 if (!Expr2DRE)
2223 return false;
2225 auto *Expr1DRE = cast<DeclRefExpr>(VarExpr1);
2227 return Expr1DRE->getDecl()->getMostRecentDecl() ==
2228 Expr2DRE->getDecl()->getMostRecentDecl();
2231 llvm_unreachable("Unknown variable type encountered");
2233 } // namespace
2235 /// OpenACC 3.3 section 2.5.15:
2236 /// At a mininmum, the supported data types include ... the numerical data types
2237 /// in C, C++, and Fortran.
2239 /// If the reduction var is a composite variable, each
2240 /// member of the composite variable must be a supported datatype for the
2241 /// reduction operation.
2242 ExprResult SemaOpenACC::CheckReductionVar(OpenACCDirectiveKind DirectiveKind,
2243 OpenACCReductionOperator ReductionOp,
2244 Expr *VarExpr) {
2245 VarExpr = VarExpr->IgnoreParenCasts();
2247 auto TypeIsValid = [](QualType Ty) {
2248 return Ty->isDependentType() || Ty->isScalarType();
2251 if (isa<ArraySectionExpr>(VarExpr)) {
2252 Expr *ASExpr = VarExpr;
2253 QualType BaseTy = ArraySectionExpr::getBaseOriginalType(ASExpr);
2254 QualType EltTy = getASTContext().getBaseElementType(BaseTy);
2256 if (!TypeIsValid(EltTy)) {
2257 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_type)
2258 << EltTy << /*Sub array base type*/ 1;
2259 return ExprError();
2261 } else if (auto *RD = VarExpr->getType()->getAsRecordDecl()) {
2262 if (!RD->isStruct() && !RD->isClass()) {
2263 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type)
2264 << /*not class or struct*/ 0 << VarExpr->getType();
2265 return ExprError();
2268 if (!RD->isCompleteDefinition()) {
2269 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type)
2270 << /*incomplete*/ 1 << VarExpr->getType();
2271 return ExprError();
2273 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
2274 CXXRD && !CXXRD->isAggregate()) {
2275 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type)
2276 << /*aggregate*/ 2 << VarExpr->getType();
2277 return ExprError();
2280 for (FieldDecl *FD : RD->fields()) {
2281 if (!TypeIsValid(FD->getType())) {
2282 Diag(VarExpr->getExprLoc(),
2283 diag::err_acc_reduction_composite_member_type);
2284 Diag(FD->getLocation(), diag::note_acc_reduction_composite_member_loc);
2285 return ExprError();
2288 } else if (!TypeIsValid(VarExpr->getType())) {
2289 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_type)
2290 << VarExpr->getType() << /*Sub array base type*/ 0;
2291 return ExprError();
2294 // OpenACC3.3: 2.9.11: Reduction clauses on nested constructs for the same
2295 // reduction 'var' must have the same reduction operator.
2296 if (!VarExpr->isInstantiationDependent()) {
2298 for (const OpenACCReductionClause *RClause : ActiveReductionClauses) {
2299 if (RClause->getReductionOp() == ReductionOp)
2300 break;
2302 for (Expr *OldVarExpr : RClause->getVarList()) {
2303 if (OldVarExpr->isInstantiationDependent())
2304 continue;
2306 if (areVarsEqual(VarExpr, OldVarExpr)) {
2307 Diag(VarExpr->getExprLoc(), diag::err_reduction_op_mismatch)
2308 << ReductionOp << RClause->getReductionOp();
2309 Diag(OldVarExpr->getExprLoc(), diag::note_acc_previous_clause_here);
2310 return ExprError();
2316 return VarExpr;
2319 void SemaOpenACC::ActOnConstruct(OpenACCDirectiveKind K,
2320 SourceLocation DirLoc) {
2321 // Start an evaluation context to parse the clause arguments on.
2322 SemaRef.PushExpressionEvaluationContext(
2323 Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
2325 switch (K) {
2326 case OpenACCDirectiveKind::Invalid:
2327 // Nothing to do here, an invalid kind has nothing we can check here. We
2328 // want to continue parsing clauses as far as we can, so we will just
2329 // ensure that we can still work and don't check any construct-specific
2330 // rules anywhere.
2331 break;
2332 case OpenACCDirectiveKind::Parallel:
2333 case OpenACCDirectiveKind::Serial:
2334 case OpenACCDirectiveKind::Kernels:
2335 case OpenACCDirectiveKind::ParallelLoop:
2336 case OpenACCDirectiveKind::SerialLoop:
2337 case OpenACCDirectiveKind::KernelsLoop:
2338 case OpenACCDirectiveKind::Loop:
2339 case OpenACCDirectiveKind::Data:
2340 case OpenACCDirectiveKind::EnterData:
2341 case OpenACCDirectiveKind::ExitData:
2342 case OpenACCDirectiveKind::HostData:
2343 case OpenACCDirectiveKind::Init:
2344 case OpenACCDirectiveKind::Shutdown:
2345 case OpenACCDirectiveKind::Set:
2346 case OpenACCDirectiveKind::Update:
2347 // Nothing to do here, there is no real legalization that needs to happen
2348 // here as these constructs do not take any arguments.
2349 break;
2350 case OpenACCDirectiveKind::Wait:
2351 // Nothing really to do here, the arguments to the 'wait' should have
2352 // already been handled by the time we get here.
2353 break;
2354 default:
2355 Diag(DirLoc, diag::warn_acc_construct_unimplemented) << K;
2356 break;
2360 ExprResult SemaOpenACC::ActOnIntExpr(OpenACCDirectiveKind DK,
2361 OpenACCClauseKind CK, SourceLocation Loc,
2362 Expr *IntExpr) {
2364 assert(((DK != OpenACCDirectiveKind::Invalid &&
2365 CK == OpenACCClauseKind::Invalid) ||
2366 (DK == OpenACCDirectiveKind::Invalid &&
2367 CK != OpenACCClauseKind::Invalid) ||
2368 (DK == OpenACCDirectiveKind::Invalid &&
2369 CK == OpenACCClauseKind::Invalid)) &&
2370 "Only one of directive or clause kind should be provided");
2372 class IntExprConverter : public Sema::ICEConvertDiagnoser {
2373 OpenACCDirectiveKind DirectiveKind;
2374 OpenACCClauseKind ClauseKind;
2375 Expr *IntExpr;
2377 // gets the index into the diagnostics so we can use this for clauses,
2378 // directives, and sub array.s
2379 unsigned getDiagKind() const {
2380 if (ClauseKind != OpenACCClauseKind::Invalid)
2381 return 0;
2382 if (DirectiveKind != OpenACCDirectiveKind::Invalid)
2383 return 1;
2384 return 2;
2387 public:
2388 IntExprConverter(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
2389 Expr *IntExpr)
2390 : ICEConvertDiagnoser(/*AllowScopedEnumerations=*/false,
2391 /*Suppress=*/false,
2392 /*SuppressConversion=*/true),
2393 DirectiveKind(DK), ClauseKind(CK), IntExpr(IntExpr) {}
2395 bool match(QualType T) override {
2396 // OpenACC spec just calls this 'integer expression' as having an
2397 // 'integer type', so fall back on C99's 'integer type'.
2398 return T->isIntegerType();
2400 SemaBase::SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
2401 QualType T) override {
2402 return S.Diag(Loc, diag::err_acc_int_expr_requires_integer)
2403 << getDiagKind() << ClauseKind << DirectiveKind << T;
2406 SemaBase::SemaDiagnosticBuilder
2407 diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) override {
2408 return S.Diag(Loc, diag::err_acc_int_expr_incomplete_class_type)
2409 << T << IntExpr->getSourceRange();
2412 SemaBase::SemaDiagnosticBuilder
2413 diagnoseExplicitConv(Sema &S, SourceLocation Loc, QualType T,
2414 QualType ConvTy) override {
2415 return S.Diag(Loc, diag::err_acc_int_expr_explicit_conversion)
2416 << T << ConvTy;
2419 SemaBase::SemaDiagnosticBuilder noteExplicitConv(Sema &S,
2420 CXXConversionDecl *Conv,
2421 QualType ConvTy) override {
2422 return S.Diag(Conv->getLocation(), diag::note_acc_int_expr_conversion)
2423 << ConvTy->isEnumeralType() << ConvTy;
2426 SemaBase::SemaDiagnosticBuilder
2427 diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) override {
2428 return S.Diag(Loc, diag::err_acc_int_expr_multiple_conversions) << T;
2431 SemaBase::SemaDiagnosticBuilder
2432 noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
2433 return S.Diag(Conv->getLocation(), diag::note_acc_int_expr_conversion)
2434 << ConvTy->isEnumeralType() << ConvTy;
2437 SemaBase::SemaDiagnosticBuilder
2438 diagnoseConversion(Sema &S, SourceLocation Loc, QualType T,
2439 QualType ConvTy) override {
2440 llvm_unreachable("conversion functions are permitted");
2442 } IntExprDiagnoser(DK, CK, IntExpr);
2444 if (!IntExpr)
2445 return ExprError();
2447 ExprResult IntExprResult = SemaRef.PerformContextualImplicitConversion(
2448 Loc, IntExpr, IntExprDiagnoser);
2449 if (IntExprResult.isInvalid())
2450 return ExprError();
2452 IntExpr = IntExprResult.get();
2453 if (!IntExpr->isTypeDependent() && !IntExpr->getType()->isIntegerType())
2454 return ExprError();
2456 // TODO OpenACC: Do we want to perform usual unary conversions here? When
2457 // doing codegen we might find that is necessary, but skip it for now.
2458 return IntExpr;
2461 bool SemaOpenACC::CheckVarIsPointerType(OpenACCClauseKind ClauseKind,
2462 Expr *VarExpr) {
2463 // We already know that VarExpr is a proper reference to a variable, so we
2464 // should be able to just take the type of the expression to get the type of
2465 // the referenced variable.
2467 // We've already seen an error, don't diagnose anything else.
2468 if (!VarExpr || VarExpr->containsErrors())
2469 return false;
2471 if (isa<ArraySectionExpr>(VarExpr->IgnoreParenImpCasts()) ||
2472 VarExpr->hasPlaceholderType(BuiltinType::ArraySection)) {
2473 Diag(VarExpr->getExprLoc(), diag::err_array_section_use) << /*OpenACC=*/0;
2474 Diag(VarExpr->getExprLoc(), diag::note_acc_expected_pointer_var);
2475 return true;
2478 QualType Ty = VarExpr->getType();
2479 Ty = Ty.getNonReferenceType().getUnqualifiedType();
2481 // Nothing we can do if this is a dependent type.
2482 if (Ty->isDependentType())
2483 return false;
2485 if (!Ty->isPointerType())
2486 return Diag(VarExpr->getExprLoc(), diag::err_acc_var_not_pointer_type)
2487 << ClauseKind << Ty;
2488 return false;
2491 ExprResult SemaOpenACC::ActOnVar(OpenACCClauseKind CK, Expr *VarExpr) {
2492 Expr *CurVarExpr = VarExpr->IgnoreParenImpCasts();
2494 // 'use_device' doesn't allow array subscript or array sections.
2495 // OpenACC3.3 2.8:
2496 // A 'var' in a 'use_device' clause must be the name of a variable or array.
2497 if (CK == OpenACCClauseKind::UseDevice &&
2498 isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
2499 Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref_use_device);
2500 return ExprError();
2503 // Sub-arrays/subscript-exprs are fine as long as the base is a
2504 // VarExpr/MemberExpr. So strip all of those off.
2505 while (isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
2506 if (auto *SubScrpt = dyn_cast<ArraySubscriptExpr>(CurVarExpr))
2507 CurVarExpr = SubScrpt->getBase()->IgnoreParenImpCasts();
2508 else
2509 CurVarExpr =
2510 cast<ArraySectionExpr>(CurVarExpr)->getBase()->IgnoreParenImpCasts();
2513 // References to a VarDecl are fine.
2514 if (const auto *DRE = dyn_cast<DeclRefExpr>(CurVarExpr)) {
2515 if (isa<VarDecl, NonTypeTemplateParmDecl>(
2516 DRE->getFoundDecl()->getCanonicalDecl()))
2517 return VarExpr;
2520 // If CK is a Reduction, this special cases for OpenACC3.3 2.5.15: "A var in a
2521 // reduction clause must be a scalar variable name, an aggregate variable
2522 // name, an array element, or a subarray.
2523 // If CK is a 'use_device', this also isn't valid, as it isn' the name of a
2524 // variable or array.
2525 // A MemberExpr that references a Field is valid for other clauses.
2526 if (CK != OpenACCClauseKind::Reduction &&
2527 CK != OpenACCClauseKind::UseDevice) {
2528 if (const auto *ME = dyn_cast<MemberExpr>(CurVarExpr)) {
2529 if (isa<FieldDecl>(ME->getMemberDecl()->getCanonicalDecl()))
2530 return VarExpr;
2534 // Referring to 'this' is ok for the most part, but for 'use_device' doesn't
2535 // fall into 'variable or array name'
2536 if (CK != OpenACCClauseKind::UseDevice && isa<CXXThisExpr>(CurVarExpr))
2537 return VarExpr;
2539 // Nothing really we can do here, as these are dependent. So just return they
2540 // are valid.
2541 if (isa<DependentScopeDeclRefExpr>(CurVarExpr) ||
2542 (CK != OpenACCClauseKind::Reduction &&
2543 isa<CXXDependentScopeMemberExpr>(CurVarExpr)))
2544 return VarExpr;
2546 // There isn't really anything we can do in the case of a recovery expr, so
2547 // skip the diagnostic rather than produce a confusing diagnostic.
2548 if (isa<RecoveryExpr>(CurVarExpr))
2549 return ExprError();
2551 if (CK == OpenACCClauseKind::UseDevice)
2552 Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref_use_device);
2553 else
2554 Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref)
2555 << (CK != OpenACCClauseKind::Reduction);
2556 return ExprError();
2559 ExprResult SemaOpenACC::ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc,
2560 Expr *LowerBound,
2561 SourceLocation ColonLoc,
2562 Expr *Length,
2563 SourceLocation RBLoc) {
2564 ASTContext &Context = getASTContext();
2566 // Handle placeholders.
2567 if (Base->hasPlaceholderType() &&
2568 !Base->hasPlaceholderType(BuiltinType::ArraySection)) {
2569 ExprResult Result = SemaRef.CheckPlaceholderExpr(Base);
2570 if (Result.isInvalid())
2571 return ExprError();
2572 Base = Result.get();
2574 if (LowerBound && LowerBound->getType()->isNonOverloadPlaceholderType()) {
2575 ExprResult Result = SemaRef.CheckPlaceholderExpr(LowerBound);
2576 if (Result.isInvalid())
2577 return ExprError();
2578 Result = SemaRef.DefaultLvalueConversion(Result.get());
2579 if (Result.isInvalid())
2580 return ExprError();
2581 LowerBound = Result.get();
2583 if (Length && Length->getType()->isNonOverloadPlaceholderType()) {
2584 ExprResult Result = SemaRef.CheckPlaceholderExpr(Length);
2585 if (Result.isInvalid())
2586 return ExprError();
2587 Result = SemaRef.DefaultLvalueConversion(Result.get());
2588 if (Result.isInvalid())
2589 return ExprError();
2590 Length = Result.get();
2593 // Check the 'base' value, it must be an array or pointer type, and not to/of
2594 // a function type.
2595 QualType OriginalBaseTy = ArraySectionExpr::getBaseOriginalType(Base);
2596 QualType ResultTy;
2597 if (!Base->isTypeDependent()) {
2598 if (OriginalBaseTy->isAnyPointerType()) {
2599 ResultTy = OriginalBaseTy->getPointeeType();
2600 } else if (OriginalBaseTy->isArrayType()) {
2601 ResultTy = OriginalBaseTy->getAsArrayTypeUnsafe()->getElementType();
2602 } else {
2603 return ExprError(
2604 Diag(Base->getExprLoc(), diag::err_acc_typecheck_subarray_value)
2605 << Base->getSourceRange());
2608 if (ResultTy->isFunctionType()) {
2609 Diag(Base->getExprLoc(), diag::err_acc_subarray_function_type)
2610 << ResultTy << Base->getSourceRange();
2611 return ExprError();
2614 if (SemaRef.RequireCompleteType(Base->getExprLoc(), ResultTy,
2615 diag::err_acc_subarray_incomplete_type,
2616 Base))
2617 return ExprError();
2619 if (!Base->hasPlaceholderType(BuiltinType::ArraySection)) {
2620 ExprResult Result = SemaRef.DefaultFunctionArrayLvalueConversion(Base);
2621 if (Result.isInvalid())
2622 return ExprError();
2623 Base = Result.get();
2627 auto GetRecovery = [&](Expr *E, QualType Ty) {
2628 ExprResult Recovery =
2629 SemaRef.CreateRecoveryExpr(E->getBeginLoc(), E->getEndLoc(), E, Ty);
2630 return Recovery.isUsable() ? Recovery.get() : nullptr;
2633 // Ensure both of the expressions are int-exprs.
2634 if (LowerBound && !LowerBound->isTypeDependent()) {
2635 ExprResult LBRes =
2636 ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Invalid,
2637 LowerBound->getExprLoc(), LowerBound);
2639 if (LBRes.isUsable())
2640 LBRes = SemaRef.DefaultLvalueConversion(LBRes.get());
2641 LowerBound =
2642 LBRes.isUsable() ? LBRes.get() : GetRecovery(LowerBound, Context.IntTy);
2645 if (Length && !Length->isTypeDependent()) {
2646 ExprResult LenRes =
2647 ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Invalid,
2648 Length->getExprLoc(), Length);
2650 if (LenRes.isUsable())
2651 LenRes = SemaRef.DefaultLvalueConversion(LenRes.get());
2652 Length =
2653 LenRes.isUsable() ? LenRes.get() : GetRecovery(Length, Context.IntTy);
2656 // Length is required if the base type is not an array of known bounds.
2657 if (!Length && (OriginalBaseTy.isNull() ||
2658 (!OriginalBaseTy->isDependentType() &&
2659 !OriginalBaseTy->isConstantArrayType() &&
2660 !OriginalBaseTy->isDependentSizedArrayType()))) {
2661 bool IsArray = !OriginalBaseTy.isNull() && OriginalBaseTy->isArrayType();
2662 Diag(ColonLoc, diag::err_acc_subarray_no_length) << IsArray;
2663 // Fill in a dummy 'length' so that when we instantiate this we don't
2664 // double-diagnose here.
2665 ExprResult Recovery = SemaRef.CreateRecoveryExpr(
2666 ColonLoc, SourceLocation(), ArrayRef<Expr *>(), Context.IntTy);
2667 Length = Recovery.isUsable() ? Recovery.get() : nullptr;
2670 // Check the values of each of the arguments, they cannot be negative(we
2671 // assume), and if the array bound is known, must be within range. As we do
2672 // so, do our best to continue with evaluation, we can set the
2673 // value/expression to nullptr/nullopt if they are invalid, and treat them as
2674 // not present for the rest of evaluation.
2676 // We don't have to check for dependence, because the dependent size is
2677 // represented as a different AST node.
2678 std::optional<llvm::APSInt> BaseSize;
2679 if (!OriginalBaseTy.isNull() && OriginalBaseTy->isConstantArrayType()) {
2680 const auto *ArrayTy = Context.getAsConstantArrayType(OriginalBaseTy);
2681 BaseSize = ArrayTy->getSize();
2684 auto GetBoundValue = [&](Expr *E) -> std::optional<llvm::APSInt> {
2685 if (!E || E->isInstantiationDependent())
2686 return std::nullopt;
2688 Expr::EvalResult Res;
2689 if (!E->EvaluateAsInt(Res, Context))
2690 return std::nullopt;
2691 return Res.Val.getInt();
2694 std::optional<llvm::APSInt> LowerBoundValue = GetBoundValue(LowerBound);
2695 std::optional<llvm::APSInt> LengthValue = GetBoundValue(Length);
2697 // Check lower bound for negative or out of range.
2698 if (LowerBoundValue.has_value()) {
2699 if (LowerBoundValue->isNegative()) {
2700 Diag(LowerBound->getExprLoc(), diag::err_acc_subarray_negative)
2701 << /*LowerBound=*/0 << toString(*LowerBoundValue, /*Radix=*/10);
2702 LowerBoundValue.reset();
2703 LowerBound = GetRecovery(LowerBound, LowerBound->getType());
2704 } else if (BaseSize.has_value() &&
2705 llvm::APSInt::compareValues(*LowerBoundValue, *BaseSize) >= 0) {
2706 // Lower bound (start index) must be less than the size of the array.
2707 Diag(LowerBound->getExprLoc(), diag::err_acc_subarray_out_of_range)
2708 << /*LowerBound=*/0 << toString(*LowerBoundValue, /*Radix=*/10)
2709 << toString(*BaseSize, /*Radix=*/10);
2710 LowerBoundValue.reset();
2711 LowerBound = GetRecovery(LowerBound, LowerBound->getType());
2715 // Check length for negative or out of range.
2716 if (LengthValue.has_value()) {
2717 if (LengthValue->isNegative()) {
2718 Diag(Length->getExprLoc(), diag::err_acc_subarray_negative)
2719 << /*Length=*/1 << toString(*LengthValue, /*Radix=*/10);
2720 LengthValue.reset();
2721 Length = GetRecovery(Length, Length->getType());
2722 } else if (BaseSize.has_value() &&
2723 llvm::APSInt::compareValues(*LengthValue, *BaseSize) > 0) {
2724 // Length must be lessthan or EQUAL to the size of the array.
2725 Diag(Length->getExprLoc(), diag::err_acc_subarray_out_of_range)
2726 << /*Length=*/1 << toString(*LengthValue, /*Radix=*/10)
2727 << toString(*BaseSize, /*Radix=*/10);
2728 LengthValue.reset();
2729 Length = GetRecovery(Length, Length->getType());
2733 // Adding two APSInts requires matching sign, so extract that here.
2734 auto AddAPSInt = [](llvm::APSInt LHS, llvm::APSInt RHS) -> llvm::APSInt {
2735 if (LHS.isSigned() == RHS.isSigned())
2736 return LHS + RHS;
2738 unsigned Width = std::max(LHS.getBitWidth(), RHS.getBitWidth()) + 1;
2739 return llvm::APSInt(LHS.sext(Width) + RHS.sext(Width), /*Signed=*/true);
2742 // If we know all 3 values, we can diagnose that the total value would be out
2743 // of range.
2744 if (BaseSize.has_value() && LowerBoundValue.has_value() &&
2745 LengthValue.has_value() &&
2746 llvm::APSInt::compareValues(AddAPSInt(*LowerBoundValue, *LengthValue),
2747 *BaseSize) > 0) {
2748 Diag(Base->getExprLoc(),
2749 diag::err_acc_subarray_base_plus_length_out_of_range)
2750 << toString(*LowerBoundValue, /*Radix=*/10)
2751 << toString(*LengthValue, /*Radix=*/10)
2752 << toString(*BaseSize, /*Radix=*/10);
2754 LowerBoundValue.reset();
2755 LowerBound = GetRecovery(LowerBound, LowerBound->getType());
2756 LengthValue.reset();
2757 Length = GetRecovery(Length, Length->getType());
2760 // If any part of the expression is dependent, return a dependent sub-array.
2761 QualType ArrayExprTy = Context.ArraySectionTy;
2762 if (Base->isTypeDependent() ||
2763 (LowerBound && LowerBound->isInstantiationDependent()) ||
2764 (Length && Length->isInstantiationDependent()))
2765 ArrayExprTy = Context.DependentTy;
2767 return new (Context)
2768 ArraySectionExpr(Base, LowerBound, Length, ArrayExprTy, VK_LValue,
2769 OK_Ordinary, ColonLoc, RBLoc);
2772 ExprResult SemaOpenACC::CheckCollapseLoopCount(Expr *LoopCount) {
2773 if (!LoopCount)
2774 return ExprError();
2776 assert((LoopCount->isInstantiationDependent() ||
2777 LoopCount->getType()->isIntegerType()) &&
2778 "Loop argument non integer?");
2780 // If this is dependent, there really isn't anything we can check.
2781 if (LoopCount->isInstantiationDependent())
2782 return ExprResult{LoopCount};
2784 std::optional<llvm::APSInt> ICE =
2785 LoopCount->getIntegerConstantExpr(getASTContext());
2787 // OpenACC 3.3: 2.9.1
2788 // The argument to the collapse clause must be a constant positive integer
2789 // expression.
2790 if (!ICE || *ICE <= 0) {
2791 Diag(LoopCount->getBeginLoc(), diag::err_acc_collapse_loop_count)
2792 << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue();
2793 return ExprError();
2796 return ExprResult{
2797 ConstantExpr::Create(getASTContext(), LoopCount, APValue{*ICE})};
2800 ExprResult
2801 SemaOpenACC::CheckGangExpr(ArrayRef<const OpenACCClause *> ExistingClauses,
2802 OpenACCDirectiveKind DK, OpenACCGangKind GK,
2803 Expr *E) {
2804 // There are two cases for the enforcement here: the 'current' directive is a
2805 // 'loop', where we need to check the active compute construct kind, or the
2806 // current directive is a 'combined' construct, where we have to check the
2807 // current one.
2808 switch (DK) {
2809 case OpenACCDirectiveKind::ParallelLoop:
2810 return CheckGangParallelExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK,
2812 case OpenACCDirectiveKind::SerialLoop:
2813 return CheckGangSerialExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK,
2815 case OpenACCDirectiveKind::KernelsLoop:
2816 return CheckGangKernelsExpr(*this, ExistingClauses, DK,
2817 ActiveComputeConstructInfo.Kind, GK, E);
2818 case OpenACCDirectiveKind::Loop:
2819 switch (ActiveComputeConstructInfo.Kind) {
2820 case OpenACCDirectiveKind::Invalid:
2821 case OpenACCDirectiveKind::Parallel:
2822 case OpenACCDirectiveKind::ParallelLoop:
2823 return CheckGangParallelExpr(*this, DK, ActiveComputeConstructInfo.Kind,
2824 GK, E);
2825 case OpenACCDirectiveKind::SerialLoop:
2826 case OpenACCDirectiveKind::Serial:
2827 return CheckGangSerialExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK,
2829 case OpenACCDirectiveKind::KernelsLoop:
2830 case OpenACCDirectiveKind::Kernels:
2831 return CheckGangKernelsExpr(*this, ExistingClauses, DK,
2832 ActiveComputeConstructInfo.Kind, GK, E);
2833 default:
2834 llvm_unreachable("Non compute construct in active compute construct?");
2836 default:
2837 // TODO: OpenACC: when we implement this on 'routine', we'll have to
2838 // implement its checking here.
2839 llvm_unreachable("Invalid directive kind for a Gang clause");
2841 llvm_unreachable("Compute construct directive not handled?");
2844 OpenACCClause *
2845 SemaOpenACC::CheckGangClause(OpenACCDirectiveKind DirKind,
2846 ArrayRef<const OpenACCClause *> ExistingClauses,
2847 SourceLocation BeginLoc, SourceLocation LParenLoc,
2848 ArrayRef<OpenACCGangKind> GangKinds,
2849 ArrayRef<Expr *> IntExprs, SourceLocation EndLoc) {
2850 // OpenACC 3.3 2.9.11: A reduction clause may not appear on a loop directive
2851 // that has a gang clause with a dim: argument whose value is greater than 1.
2853 const auto *ReductionItr =
2854 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>);
2856 if (ReductionItr != ExistingClauses.end()) {
2857 const auto GangZip = llvm::zip_equal(GangKinds, IntExprs);
2858 const auto GangItr = llvm::find_if(GangZip, [](const auto &Tuple) {
2859 return std::get<0>(Tuple) == OpenACCGangKind::Dim;
2862 if (GangItr != GangZip.end()) {
2863 const Expr *DimExpr = std::get<1>(*GangItr);
2865 assert(
2866 (DimExpr->isInstantiationDependent() || isa<ConstantExpr>(DimExpr)) &&
2867 "Improperly formed gang argument");
2868 if (const auto *DimVal = dyn_cast<ConstantExpr>(DimExpr);
2869 DimVal && DimVal->getResultAsAPSInt() > 1) {
2870 Diag(DimVal->getBeginLoc(), diag::err_acc_gang_reduction_conflict)
2871 << /*gang/reduction=*/0 << DirKind;
2872 Diag((*ReductionItr)->getBeginLoc(),
2873 diag::note_acc_previous_clause_here);
2874 return nullptr;
2879 return OpenACCGangClause::Create(getASTContext(), BeginLoc, LParenLoc,
2880 GangKinds, IntExprs, EndLoc);
2883 OpenACCClause *SemaOpenACC::CheckReductionClause(
2884 ArrayRef<const OpenACCClause *> ExistingClauses,
2885 OpenACCDirectiveKind DirectiveKind, SourceLocation BeginLoc,
2886 SourceLocation LParenLoc, OpenACCReductionOperator ReductionOp,
2887 ArrayRef<Expr *> Vars, SourceLocation EndLoc) {
2888 if (DirectiveKind == OpenACCDirectiveKind::Loop ||
2889 isOpenACCCombinedDirectiveKind(DirectiveKind)) {
2890 // OpenACC 3.3 2.9.11: A reduction clause may not appear on a loop directive
2891 // that has a gang clause with a dim: argument whose value is greater
2892 // than 1.
2893 const auto GangClauses = llvm::make_filter_range(
2894 ExistingClauses, llvm::IsaPred<OpenACCGangClause>);
2896 for (auto *GC : GangClauses) {
2897 const auto *GangClause = cast<OpenACCGangClause>(GC);
2898 for (unsigned I = 0; I < GangClause->getNumExprs(); ++I) {
2899 std::pair<OpenACCGangKind, const Expr *> EPair = GangClause->getExpr(I);
2900 if (EPair.first != OpenACCGangKind::Dim)
2901 continue;
2903 if (const auto *DimVal = dyn_cast<ConstantExpr>(EPair.second);
2904 DimVal && DimVal->getResultAsAPSInt() > 1) {
2905 Diag(BeginLoc, diag::err_acc_gang_reduction_conflict)
2906 << /*reduction/gang=*/1 << DirectiveKind;
2907 Diag(GangClause->getBeginLoc(), diag::note_acc_previous_clause_here);
2908 return nullptr;
2914 auto *Ret = OpenACCReductionClause::Create(
2915 getASTContext(), BeginLoc, LParenLoc, ReductionOp, Vars, EndLoc);
2916 return Ret;
2919 ExprResult SemaOpenACC::CheckTileSizeExpr(Expr *SizeExpr) {
2920 if (!SizeExpr)
2921 return ExprError();
2923 assert((SizeExpr->isInstantiationDependent() ||
2924 SizeExpr->getType()->isIntegerType()) &&
2925 "size argument non integer?");
2927 // If dependent, or an asterisk, the expression is fine.
2928 if (SizeExpr->isInstantiationDependent() ||
2929 isa<OpenACCAsteriskSizeExpr>(SizeExpr))
2930 return ExprResult{SizeExpr};
2932 std::optional<llvm::APSInt> ICE =
2933 SizeExpr->getIntegerConstantExpr(getASTContext());
2935 // OpenACC 3.3 2.9.8
2936 // where each tile size is a constant positive integer expression or asterisk.
2937 if (!ICE || *ICE <= 0) {
2938 Diag(SizeExpr->getBeginLoc(), diag::err_acc_size_expr_value)
2939 << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue();
2940 return ExprError();
2943 return ExprResult{
2944 ConstantExpr::Create(getASTContext(), SizeExpr, APValue{*ICE})};
2947 void SemaOpenACC::ActOnWhileStmt(SourceLocation WhileLoc) {
2948 if (!getLangOpts().OpenACC)
2949 return;
2951 if (!LoopInfo.TopLevelLoopSeen)
2952 return;
2954 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
2955 Diag(WhileLoc, diag::err_acc_invalid_in_loop)
2956 << /*while loop*/ 1 << CollapseInfo.DirectiveKind
2957 << OpenACCClauseKind::Collapse;
2958 assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");
2959 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
2960 diag::note_acc_active_clause_here)
2961 << OpenACCClauseKind::Collapse;
2963 // Remove the value so that we don't get cascading errors in the body. The
2964 // caller RAII object will restore this.
2965 CollapseInfo.CurCollapseCount = std::nullopt;
2968 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
2969 Diag(WhileLoc, diag::err_acc_invalid_in_loop)
2970 << /*while loop*/ 1 << TileInfo.DirectiveKind
2971 << OpenACCClauseKind::Tile;
2972 assert(TileInfo.ActiveTile && "tile count without object?");
2973 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
2974 << OpenACCClauseKind::Tile;
2976 // Remove the value so that we don't get cascading errors in the body. The
2977 // caller RAII object will restore this.
2978 TileInfo.CurTileCount = std::nullopt;
2982 void SemaOpenACC::ActOnDoStmt(SourceLocation DoLoc) {
2983 if (!getLangOpts().OpenACC)
2984 return;
2986 if (!LoopInfo.TopLevelLoopSeen)
2987 return;
2989 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
2990 Diag(DoLoc, diag::err_acc_invalid_in_loop)
2991 << /*do loop*/ 2 << CollapseInfo.DirectiveKind
2992 << OpenACCClauseKind::Collapse;
2993 assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");
2994 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
2995 diag::note_acc_active_clause_here)
2996 << OpenACCClauseKind::Collapse;
2998 // Remove the value so that we don't get cascading errors in the body. The
2999 // caller RAII object will restore this.
3000 CollapseInfo.CurCollapseCount = std::nullopt;
3003 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
3004 Diag(DoLoc, diag::err_acc_invalid_in_loop)
3005 << /*do loop*/ 2 << TileInfo.DirectiveKind << OpenACCClauseKind::Tile;
3006 assert(TileInfo.ActiveTile && "tile count without object?");
3007 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
3008 << OpenACCClauseKind::Tile;
3010 // Remove the value so that we don't get cascading errors in the body. The
3011 // caller RAII object will restore this.
3012 TileInfo.CurTileCount = std::nullopt;
3016 void SemaOpenACC::ForStmtBeginHelper(SourceLocation ForLoc,
3017 ForStmtBeginChecker &C) {
3018 assert(getLangOpts().OpenACC && "Check enabled when not OpenACC?");
3020 // Enable the while/do-while checking.
3021 LoopInfo.TopLevelLoopSeen = true;
3023 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
3024 C.check();
3026 // OpenACC 3.3 2.9.1:
3027 // Each associated loop, except the innermost, must contain exactly one loop
3028 // or loop nest.
3029 // This checks for more than 1 loop at the current level, the
3030 // 'depth'-satisifed checking manages the 'not zero' case.
3031 if (LoopInfo.CurLevelHasLoopAlready) {
3032 Diag(ForLoc, diag::err_acc_clause_multiple_loops)
3033 << CollapseInfo.DirectiveKind << OpenACCClauseKind::Collapse;
3034 assert(CollapseInfo.ActiveCollapse && "No collapse object?");
3035 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
3036 diag::note_acc_active_clause_here)
3037 << OpenACCClauseKind::Collapse;
3038 } else {
3039 --(*CollapseInfo.CurCollapseCount);
3041 // Once we've hit zero here, we know we have deep enough 'for' loops to
3042 // get to the bottom.
3043 if (*CollapseInfo.CurCollapseCount == 0)
3044 CollapseInfo.CollapseDepthSatisfied = true;
3048 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
3049 C.check();
3051 if (LoopInfo.CurLevelHasLoopAlready) {
3052 Diag(ForLoc, diag::err_acc_clause_multiple_loops)
3053 << TileInfo.DirectiveKind << OpenACCClauseKind::Tile;
3054 assert(TileInfo.ActiveTile && "No tile object?");
3055 Diag(TileInfo.ActiveTile->getBeginLoc(),
3056 diag::note_acc_active_clause_here)
3057 << OpenACCClauseKind::Tile;
3058 } else {
3059 --(*TileInfo.CurTileCount);
3060 // Once we've hit zero here, we know we have deep enough 'for' loops to
3061 // get to the bottom.
3062 if (*TileInfo.CurTileCount == 0)
3063 TileInfo.TileDepthSatisfied = true;
3067 // Set this to 'false' for the body of this loop, so that the next level
3068 // checks independently.
3069 LoopInfo.CurLevelHasLoopAlready = false;
3072 namespace {
3073 bool isValidLoopVariableType(QualType LoopVarTy) {
3074 // Just skip if it is dependent, it could be any of the below.
3075 if (LoopVarTy->isDependentType())
3076 return true;
3078 // The loop variable must be of integer,
3079 if (LoopVarTy->isIntegerType())
3080 return true;
3082 // C/C++ pointer,
3083 if (LoopVarTy->isPointerType())
3084 return true;
3086 // or C++ random-access iterator type.
3087 if (const auto *RD = LoopVarTy->getAsCXXRecordDecl()) {
3088 // Note: Only do CXXRecordDecl because RecordDecl can't be a random access
3089 // iterator type!
3091 // We could either do a lot of work to see if this matches
3092 // random-access-iterator, but it seems that just checking that the
3093 // 'iterator_category' typedef is more than sufficient. If programmers are
3094 // willing to lie about this, we can let them.
3096 for (const auto *TD :
3097 llvm::make_filter_range(RD->decls(), llvm::IsaPred<TypedefNameDecl>)) {
3098 const auto *TDND = cast<TypedefNameDecl>(TD)->getCanonicalDecl();
3100 if (TDND->getName() != "iterator_category")
3101 continue;
3103 // If there is no type for this decl, return false.
3104 if (TDND->getUnderlyingType().isNull())
3105 return false;
3107 const CXXRecordDecl *ItrCategoryDecl =
3108 TDND->getUnderlyingType()->getAsCXXRecordDecl();
3110 // If the category isn't a record decl, it isn't the tag type.
3111 if (!ItrCategoryDecl)
3112 return false;
3114 auto IsRandomAccessIteratorTag = [](const CXXRecordDecl *RD) {
3115 if (RD->getName() != "random_access_iterator_tag")
3116 return false;
3117 // Checks just for std::random_access_iterator_tag.
3118 return RD->getEnclosingNamespaceContext()->isStdNamespace();
3121 if (IsRandomAccessIteratorTag(ItrCategoryDecl))
3122 return true;
3124 // We can also support types inherited from the
3125 // random_access_iterator_tag.
3126 for (CXXBaseSpecifier BS : ItrCategoryDecl->bases()) {
3128 if (IsRandomAccessIteratorTag(BS.getType()->getAsCXXRecordDecl()))
3129 return true;
3132 return false;
3136 return false;
3139 } // namespace
3141 void SemaOpenACC::ForStmtBeginChecker::check() {
3142 if (SemaRef.LoopWithoutSeqInfo.Kind == OpenACCDirectiveKind::Invalid)
3143 return;
3145 if (AlreadyChecked)
3146 return;
3147 AlreadyChecked = true;
3149 // OpenACC3.3 2.1:
3150 // A loop associated with a loop construct that does not have a seq clause
3151 // must be written to meet all the following conditions:
3152 // - The loop variable must be of integer, C/C++ pointer, or C++ random-access
3153 // iterator type.
3154 // - The loop variable must monotonically increase or decrease in the
3155 // direction of its termination condition.
3156 // - The loop trip count must be computable in constant time when entering the
3157 // loop construct.
3159 // For a C++ range-based for loop, the loop variable
3160 // identified by the above conditions is the internal iterator, such as a
3161 // pointer, that the compiler generates to iterate the range. it is not the
3162 // variable declared by the for loop.
3164 if (IsRangeFor) {
3165 // If the range-for is being instantiated and didn't change, don't
3166 // re-diagnose.
3167 if (!RangeFor.has_value())
3168 return;
3169 // For a range-for, we can assume everything is 'corect' other than the type
3170 // of the iterator, so check that.
3171 const DeclStmt *RangeStmt = (*RangeFor)->getBeginStmt();
3173 // In some dependent contexts, the autogenerated range statement doesn't get
3174 // included until instantiation, so skip for now.
3175 if (!RangeStmt)
3176 return;
3178 const ValueDecl *InitVar = cast<ValueDecl>(RangeStmt->getSingleDecl());
3179 QualType VarType = InitVar->getType().getNonReferenceType();
3180 if (!isValidLoopVariableType(VarType)) {
3181 SemaRef.Diag(InitVar->getBeginLoc(), diag::err_acc_loop_variable_type)
3182 << SemaRef.LoopWithoutSeqInfo.Kind << VarType;
3183 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc,
3184 diag::note_acc_construct_here)
3185 << SemaRef.LoopWithoutSeqInfo.Kind;
3187 return;
3190 // Else we are in normal 'ForStmt', so we can diagnose everything.
3191 // We only have to check cond/inc if they have changed, but 'init' needs to
3192 // just suppress its diagnostics if it hasn't changed.
3193 const ValueDecl *InitVar = checkInit();
3194 if (Cond.has_value())
3195 checkCond();
3196 if (Inc.has_value())
3197 checkInc(InitVar);
3199 const ValueDecl *SemaOpenACC::ForStmtBeginChecker::checkInit() {
3200 if (!Init) {
3201 if (InitChanged) {
3202 SemaRef.Diag(ForLoc, diag::err_acc_loop_variable)
3203 << SemaRef.LoopWithoutSeqInfo.Kind;
3204 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc,
3205 diag::note_acc_construct_here)
3206 << SemaRef.LoopWithoutSeqInfo.Kind;
3208 return nullptr;
3211 auto DiagLoopVar = [&]() {
3212 if (InitChanged) {
3213 SemaRef.Diag(Init->getBeginLoc(), diag::err_acc_loop_variable)
3214 << SemaRef.LoopWithoutSeqInfo.Kind;
3215 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc,
3216 diag::note_acc_construct_here)
3217 << SemaRef.LoopWithoutSeqInfo.Kind;
3219 return nullptr;
3222 if (const auto *ExprTemp = dyn_cast<ExprWithCleanups>(Init))
3223 Init = ExprTemp->getSubExpr();
3224 if (const auto *E = dyn_cast<Expr>(Init))
3225 Init = E->IgnoreParenImpCasts();
3227 const ValueDecl *InitVar = nullptr;
3229 if (const auto *BO = dyn_cast<BinaryOperator>(Init)) {
3230 // Allow assignment operator here.
3232 if (!BO->isAssignmentOp())
3233 return DiagLoopVar();
3235 const Expr *LHS = BO->getLHS()->IgnoreParenImpCasts();
3237 if (const auto *DRE = dyn_cast<DeclRefExpr>(LHS))
3238 InitVar = DRE->getDecl();
3239 } else if (const auto *DS = dyn_cast<DeclStmt>(Init)) {
3240 // Allow T t = <whatever>
3241 if (!DS->isSingleDecl())
3242 return DiagLoopVar();
3244 InitVar = dyn_cast<ValueDecl>(DS->getSingleDecl());
3246 // Ensure we have an initializer, unless this is a record/dependent type.
3248 if (InitVar) {
3249 if (!isa<VarDecl>(InitVar))
3250 return DiagLoopVar();
3252 if (!InitVar->getType()->isRecordType() &&
3253 !InitVar->getType()->isDependentType() &&
3254 !cast<VarDecl>(InitVar)->hasInit())
3255 return DiagLoopVar();
3257 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(Init)) {
3258 // Allow assignment operator call.
3259 if (CE->getOperator() != OO_Equal)
3260 return DiagLoopVar();
3262 const Expr *LHS = CE->getArg(0)->IgnoreParenImpCasts();
3264 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3265 InitVar = DRE->getDecl();
3266 } else if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
3267 if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3268 InitVar = ME->getMemberDecl();
3272 if (!InitVar)
3273 return DiagLoopVar();
3275 InitVar = cast<ValueDecl>(InitVar->getCanonicalDecl());
3276 QualType VarType = InitVar->getType().getNonReferenceType();
3278 // Since we have one, all we need to do is ensure it is the right type.
3279 if (!isValidLoopVariableType(VarType)) {
3280 if (InitChanged) {
3281 SemaRef.Diag(InitVar->getBeginLoc(), diag::err_acc_loop_variable_type)
3282 << SemaRef.LoopWithoutSeqInfo.Kind << VarType;
3283 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc,
3284 diag::note_acc_construct_here)
3285 << SemaRef.LoopWithoutSeqInfo.Kind;
3287 return nullptr;
3290 return InitVar;
3292 void SemaOpenACC::ForStmtBeginChecker::checkCond() {
3293 if (!*Cond) {
3294 SemaRef.Diag(ForLoc, diag::err_acc_loop_terminating_condition)
3295 << SemaRef.LoopWithoutSeqInfo.Kind;
3296 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc, diag::note_acc_construct_here)
3297 << SemaRef.LoopWithoutSeqInfo.Kind;
3299 // Nothing else to do here. we could probably do some additional work to look
3300 // into the termination condition, but that error-prone. For now, we don't
3301 // implement anything other than 'there is a termination condition', and if
3302 // codegen/MLIR comes up with some necessary restrictions, we can implement
3303 // them here.
3306 void SemaOpenACC::ForStmtBeginChecker::checkInc(const ValueDecl *Init) {
3308 if (!*Inc) {
3309 SemaRef.Diag(ForLoc, diag::err_acc_loop_not_monotonic)
3310 << SemaRef.LoopWithoutSeqInfo.Kind;
3311 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc, diag::note_acc_construct_here)
3312 << SemaRef.LoopWithoutSeqInfo.Kind;
3313 return;
3315 auto DiagIncVar = [this] {
3316 SemaRef.Diag((*Inc)->getBeginLoc(), diag::err_acc_loop_not_monotonic)
3317 << SemaRef.LoopWithoutSeqInfo.Kind;
3318 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc, diag::note_acc_construct_here)
3319 << SemaRef.LoopWithoutSeqInfo.Kind;
3320 return;
3323 if (const auto *ExprTemp = dyn_cast<ExprWithCleanups>(*Inc))
3324 Inc = ExprTemp->getSubExpr();
3325 if (const auto *E = dyn_cast<Expr>(*Inc))
3326 Inc = E->IgnoreParenImpCasts();
3328 auto getDeclFromExpr = [](const Expr *E) -> const ValueDecl * {
3329 E = E->IgnoreParenImpCasts();
3330 if (const auto *FE = dyn_cast<FullExpr>(E))
3331 E = FE->getSubExpr();
3333 E = E->IgnoreParenImpCasts();
3335 if (!E)
3336 return nullptr;
3337 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
3338 return dyn_cast<ValueDecl>(DRE->getDecl());
3340 if (const auto *ME = dyn_cast<MemberExpr>(E))
3341 if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3342 return ME->getMemberDecl();
3344 return nullptr;
3347 const ValueDecl *IncVar = nullptr;
3349 // Here we enforce the monotonically increase/decrease:
3350 if (const auto *UO = dyn_cast<UnaryOperator>(*Inc)) {
3351 // Allow increment/decrement ops.
3352 if (!UO->isIncrementDecrementOp())
3353 return DiagIncVar();
3354 IncVar = getDeclFromExpr(UO->getSubExpr());
3355 } else if (const auto *BO = dyn_cast<BinaryOperator>(*Inc)) {
3356 switch (BO->getOpcode()) {
3357 default:
3358 return DiagIncVar();
3359 case BO_AddAssign:
3360 case BO_SubAssign:
3361 case BO_MulAssign:
3362 case BO_DivAssign:
3363 case BO_Assign:
3364 // += -= *= /= should all be fine here, this should be all of the
3365 // 'monotonical' compound-assign ops.
3366 // Assignment we just give up on, we could do better, and ensure that it
3367 // is a binary/operator expr doing more work, but that seems like a lot
3368 // of work for an error prone check.
3369 break;
3371 IncVar = getDeclFromExpr(BO->getLHS());
3372 } else if (const auto *CE = dyn_cast<CXXOperatorCallExpr>(*Inc)) {
3373 switch (CE->getOperator()) {
3374 default:
3375 return DiagIncVar();
3376 case OO_PlusPlus:
3377 case OO_MinusMinus:
3378 case OO_PlusEqual:
3379 case OO_MinusEqual:
3380 case OO_StarEqual:
3381 case OO_SlashEqual:
3382 case OO_Equal:
3383 // += -= *= /= should all be fine here, this should be all of the
3384 // 'monotonical' compound-assign ops.
3385 // Assignment we just give up on, we could do better, and ensure that it
3386 // is a binary/operator expr doing more work, but that seems like a lot
3387 // of work for an error prone check.
3388 break;
3391 IncVar = getDeclFromExpr(CE->getArg(0));
3393 } else if (const auto *ME = dyn_cast<CXXMemberCallExpr>(*Inc)) {
3394 IncVar = getDeclFromExpr(ME->getImplicitObjectArgument());
3395 // We can't really do much for member expressions, other than hope they are
3396 // doing the right thing, so give up here.
3399 if (!IncVar)
3400 return DiagIncVar();
3402 // InitVar shouldn't be null unless there was an error, so don't diagnose if
3403 // that is the case. Else we should ensure that it refers to the loop
3404 // value.
3405 if (Init && IncVar->getCanonicalDecl() != Init->getCanonicalDecl())
3406 return DiagIncVar();
3408 return;
3411 void SemaOpenACC::ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *OldFirst,
3412 const Stmt *First, const Stmt *OldSecond,
3413 const Stmt *Second, const Stmt *OldThird,
3414 const Stmt *Third) {
3415 if (!getLangOpts().OpenACC)
3416 return;
3418 std::optional<const Stmt *> S;
3419 if (OldSecond == Second)
3420 S = std::nullopt;
3421 else
3422 S = Second;
3423 std::optional<const Stmt *> T;
3424 if (OldThird == Third)
3425 S = std::nullopt;
3426 else
3427 S = Third;
3429 bool InitChanged = false;
3430 if (OldFirst != First) {
3431 InitChanged = true;
3433 // VarDecls are always rebuild because they are dependent, so we can do a
3434 // little work to suppress some of the double checking based on whether the
3435 // type is instantiation dependent.
3436 QualType OldVDTy;
3437 QualType NewVDTy;
3438 if (const auto *DS = dyn_cast<DeclStmt>(OldFirst))
3439 if (const VarDecl *VD = dyn_cast_if_present<VarDecl>(
3440 DS->isSingleDecl() ? DS->getSingleDecl() : nullptr))
3441 OldVDTy = VD->getType();
3442 if (const auto *DS = dyn_cast<DeclStmt>(First))
3443 if (const VarDecl *VD = dyn_cast_if_present<VarDecl>(
3444 DS->isSingleDecl() ? DS->getSingleDecl() : nullptr))
3445 NewVDTy = VD->getType();
3447 if (!OldVDTy.isNull() && !NewVDTy.isNull())
3448 InitChanged = OldVDTy->isInstantiationDependentType() !=
3449 NewVDTy->isInstantiationDependentType();
3452 ForStmtBeginChecker FSBC{*this, ForLoc, First, InitChanged, S, T};
3453 if (!LoopInfo.TopLevelLoopSeen) {
3454 FSBC.check();
3457 ForStmtBeginHelper(ForLoc, FSBC);
3460 void SemaOpenACC::ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *First,
3461 const Stmt *Second, const Stmt *Third) {
3462 if (!getLangOpts().OpenACC)
3463 return;
3465 ForStmtBeginChecker FSBC{*this, ForLoc, First, /*InitChanged=*/true,
3466 Second, Third};
3467 if (!LoopInfo.TopLevelLoopSeen) {
3468 FSBC.check();
3471 ForStmtBeginHelper(ForLoc, FSBC);
3474 void SemaOpenACC::ActOnRangeForStmtBegin(SourceLocation ForLoc,
3475 const Stmt *OldRangeFor,
3476 const Stmt *RangeFor) {
3477 if (!getLangOpts().OpenACC)
3478 return;
3480 std::optional<const CXXForRangeStmt *> RF;
3482 if (OldRangeFor == RangeFor)
3483 RF = std::nullopt;
3484 else
3485 RF = cast<CXXForRangeStmt>(RangeFor);
3487 ForStmtBeginChecker FSBC{*this, ForLoc, RF};
3488 if (!LoopInfo.TopLevelLoopSeen) {
3489 FSBC.check();
3491 ForStmtBeginHelper(ForLoc, FSBC);
3494 void SemaOpenACC::ActOnRangeForStmtBegin(SourceLocation ForLoc,
3495 const Stmt *RangeFor) {
3496 if (!getLangOpts().OpenACC)
3497 return;
3499 ForStmtBeginChecker FSBC{*this, ForLoc, cast<CXXForRangeStmt>(RangeFor)};
3500 if (!LoopInfo.TopLevelLoopSeen) {
3501 FSBC.check();
3503 ForStmtBeginHelper(ForLoc, FSBC);
3506 namespace {
3507 SourceLocation FindInterveningCodeInLoop(const Stmt *CurStmt) {
3508 // We should diagnose on anything except `CompoundStmt`, `NullStmt`,
3509 // `ForStmt`, `CXXForRangeStmt`, since those are legal, and `WhileStmt` and
3510 // `DoStmt`, as those are caught as a violation elsewhere.
3511 // For `CompoundStmt` we need to search inside of it.
3512 if (!CurStmt ||
3513 isa<ForStmt, NullStmt, ForStmt, CXXForRangeStmt, WhileStmt, DoStmt>(
3514 CurStmt))
3515 return SourceLocation{};
3517 // Any other construct is an error anyway, so it has already been diagnosed.
3518 if (isa<OpenACCConstructStmt>(CurStmt))
3519 return SourceLocation{};
3521 // Search inside the compound statement, this allows for arbitrary nesting
3522 // of compound statements, as long as there isn't any code inside.
3523 if (const auto *CS = dyn_cast<CompoundStmt>(CurStmt)) {
3524 for (const auto *ChildStmt : CS->children()) {
3525 SourceLocation ChildStmtLoc = FindInterveningCodeInLoop(ChildStmt);
3526 if (ChildStmtLoc.isValid())
3527 return ChildStmtLoc;
3529 // Empty/not invalid compound statements are legal.
3530 return SourceLocation{};
3532 return CurStmt->getBeginLoc();
3534 } // namespace
3536 void SemaOpenACC::ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body) {
3537 if (!getLangOpts().OpenACC)
3538 return;
3540 // Set this to 'true' so if we find another one at this level we can diagnose.
3541 LoopInfo.CurLevelHasLoopAlready = true;
3543 if (!Body.isUsable())
3544 return;
3546 bool IsActiveCollapse = CollapseInfo.CurCollapseCount &&
3547 *CollapseInfo.CurCollapseCount > 0 &&
3548 !CollapseInfo.ActiveCollapse->hasForce();
3549 bool IsActiveTile = TileInfo.CurTileCount && *TileInfo.CurTileCount > 0;
3551 if (IsActiveCollapse || IsActiveTile) {
3552 SourceLocation OtherStmtLoc = FindInterveningCodeInLoop(Body.get());
3554 if (OtherStmtLoc.isValid() && IsActiveCollapse) {
3555 Diag(OtherStmtLoc, diag::err_acc_intervening_code)
3556 << OpenACCClauseKind::Collapse << CollapseInfo.DirectiveKind;
3557 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
3558 diag::note_acc_active_clause_here)
3559 << OpenACCClauseKind::Collapse;
3562 if (OtherStmtLoc.isValid() && IsActiveTile) {
3563 Diag(OtherStmtLoc, diag::err_acc_intervening_code)
3564 << OpenACCClauseKind::Tile << TileInfo.DirectiveKind;
3565 Diag(TileInfo.ActiveTile->getBeginLoc(),
3566 diag::note_acc_active_clause_here)
3567 << OpenACCClauseKind::Tile;
3572 namespace {
3573 // Get a list of clause Kinds for diagnosing a list, joined by a commas and an
3574 // 'or'.
3575 std::string GetListOfClauses(llvm::ArrayRef<OpenACCClauseKind> Clauses) {
3576 assert(!Clauses.empty() && "empty clause list not supported");
3578 std::string Output;
3579 llvm::raw_string_ostream OS{Output};
3581 if (Clauses.size() == 1) {
3582 OS << '\'' << Clauses[0] << '\'';
3583 return Output;
3586 llvm::ArrayRef<OpenACCClauseKind> AllButLast{Clauses.begin(),
3587 Clauses.end() - 1};
3589 llvm::interleave(
3590 AllButLast, [&](OpenACCClauseKind K) { OS << '\'' << K << '\''; },
3591 [&] { OS << ", "; });
3593 OS << " or \'" << Clauses.back() << '\'';
3594 return Output;
3596 } // namespace
3598 bool SemaOpenACC::ActOnStartStmtDirective(
3599 OpenACCDirectiveKind K, SourceLocation StartLoc,
3600 ArrayRef<const OpenACCClause *> Clauses) {
3601 SemaRef.DiscardCleanupsInEvaluationContext();
3602 SemaRef.PopExpressionEvaluationContext();
3604 // OpenACC 3.3 2.9.1:
3605 // Intervening code must not contain other OpenACC directives or calls to API
3606 // routines.
3608 // ALL constructs are ill-formed if there is an active 'collapse'
3609 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
3610 Diag(StartLoc, diag::err_acc_invalid_in_loop)
3611 << /*OpenACC Construct*/ 0 << CollapseInfo.DirectiveKind
3612 << OpenACCClauseKind::Collapse << K;
3613 assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");
3614 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
3615 diag::note_acc_active_clause_here)
3616 << OpenACCClauseKind::Collapse;
3618 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
3619 Diag(StartLoc, diag::err_acc_invalid_in_loop)
3620 << /*OpenACC Construct*/ 0 << TileInfo.DirectiveKind
3621 << OpenACCClauseKind::Tile << K;
3622 assert(TileInfo.ActiveTile && "Tile count without object?");
3623 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
3624 << OpenACCClauseKind::Tile;
3627 // OpenACC3.3 2.6.5: At least one copy, copyin, copyout, create, no_create,
3628 // present, deviceptr, attach, or default clause must appear on a 'data'
3629 // construct.
3630 if (K == OpenACCDirectiveKind::Data &&
3631 llvm::find_if(Clauses,
3632 llvm::IsaPred<OpenACCCopyClause, OpenACCCopyInClause,
3633 OpenACCCopyOutClause, OpenACCCreateClause,
3634 OpenACCNoCreateClause, OpenACCPresentClause,
3635 OpenACCDevicePtrClause, OpenACCAttachClause,
3636 OpenACCDefaultClause>) == Clauses.end())
3637 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
3638 << K
3639 << GetListOfClauses(
3640 {OpenACCClauseKind::Copy, OpenACCClauseKind::CopyIn,
3641 OpenACCClauseKind::CopyOut, OpenACCClauseKind::Create,
3642 OpenACCClauseKind::NoCreate, OpenACCClauseKind::Present,
3643 OpenACCClauseKind::DevicePtr, OpenACCClauseKind::Attach,
3644 OpenACCClauseKind::Default});
3646 // OpenACC3.3 2.6.6: At least one copyin, create, or attach clause must appear
3647 // on an enter data directive.
3648 if (K == OpenACCDirectiveKind::EnterData &&
3649 llvm::find_if(Clauses,
3650 llvm::IsaPred<OpenACCCopyInClause, OpenACCCreateClause,
3651 OpenACCAttachClause>) == Clauses.end())
3652 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
3653 << K
3654 << GetListOfClauses({
3655 OpenACCClauseKind::CopyIn,
3656 OpenACCClauseKind::Create,
3657 OpenACCClauseKind::Attach,
3659 // OpenACC3.3 2.6.6: At least one copyout, delete, or detach clause must
3660 // appear on an exit data directive.
3661 if (K == OpenACCDirectiveKind::ExitData &&
3662 llvm::find_if(Clauses,
3663 llvm::IsaPred<OpenACCCopyOutClause, OpenACCDeleteClause,
3664 OpenACCDetachClause>) == Clauses.end())
3665 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
3666 << K
3667 << GetListOfClauses({
3668 OpenACCClauseKind::CopyOut,
3669 OpenACCClauseKind::Delete,
3670 OpenACCClauseKind::Detach,
3673 // OpenACC3.3 2.8: At least 'one use_device' clause must appear.
3674 if (K == OpenACCDirectiveKind::HostData &&
3675 llvm::find_if(Clauses, llvm::IsaPred<OpenACCUseDeviceClause>) ==
3676 Clauses.end())
3677 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
3678 << K << GetListOfClauses({OpenACCClauseKind::UseDevice});
3680 // OpenACC3.3 2.14.3: At least one default_async, device_num, or device_type
3681 // clause must appear.
3682 if (K == OpenACCDirectiveKind::Set &&
3683 llvm::find_if(
3684 Clauses,
3685 llvm::IsaPred<OpenACCDefaultAsyncClause, OpenACCDeviceNumClause,
3686 OpenACCDeviceTypeClause, OpenACCIfClause>) ==
3687 Clauses.end())
3688 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
3689 << K
3690 << GetListOfClauses({OpenACCClauseKind::DefaultAsync,
3691 OpenACCClauseKind::DeviceNum,
3692 OpenACCClauseKind::DeviceType,
3693 OpenACCClauseKind::If});
3695 // TODO: OpenACC: 'Update' construct needs to have one of 'self', 'host', or
3696 // 'device'. Implement here.
3698 return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/true);
3701 StmtResult SemaOpenACC::ActOnEndStmtDirective(
3702 OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc,
3703 SourceLocation LParenLoc, SourceLocation MiscLoc, ArrayRef<Expr *> Exprs,
3704 SourceLocation RParenLoc, SourceLocation EndLoc,
3705 ArrayRef<OpenACCClause *> Clauses, StmtResult AssocStmt) {
3706 switch (K) {
3707 default:
3708 return StmtEmpty();
3709 case OpenACCDirectiveKind::Invalid:
3710 return StmtError();
3711 case OpenACCDirectiveKind::Parallel:
3712 case OpenACCDirectiveKind::Serial:
3713 case OpenACCDirectiveKind::Kernels: {
3714 return OpenACCComputeConstruct::Create(
3715 getASTContext(), K, StartLoc, DirLoc, EndLoc, Clauses,
3716 AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
3718 case OpenACCDirectiveKind::ParallelLoop:
3719 case OpenACCDirectiveKind::SerialLoop:
3720 case OpenACCDirectiveKind::KernelsLoop: {
3721 return OpenACCCombinedConstruct::Create(
3722 getASTContext(), K, StartLoc, DirLoc, EndLoc, Clauses,
3723 AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
3725 case OpenACCDirectiveKind::Loop: {
3726 return OpenACCLoopConstruct::Create(
3727 getASTContext(), ActiveComputeConstructInfo.Kind, StartLoc, DirLoc,
3728 EndLoc, Clauses, AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
3730 case OpenACCDirectiveKind::Data: {
3731 return OpenACCDataConstruct::Create(
3732 getASTContext(), StartLoc, DirLoc, EndLoc, Clauses,
3733 AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
3735 case OpenACCDirectiveKind::EnterData: {
3736 return OpenACCEnterDataConstruct::Create(getASTContext(), StartLoc, DirLoc,
3737 EndLoc, Clauses);
3739 case OpenACCDirectiveKind::ExitData: {
3740 return OpenACCExitDataConstruct::Create(getASTContext(), StartLoc, DirLoc,
3741 EndLoc, Clauses);
3743 case OpenACCDirectiveKind::HostData: {
3744 return OpenACCHostDataConstruct::Create(
3745 getASTContext(), StartLoc, DirLoc, EndLoc, Clauses,
3746 AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
3748 case OpenACCDirectiveKind::Wait: {
3749 return OpenACCWaitConstruct::Create(
3750 getASTContext(), StartLoc, DirLoc, LParenLoc, Exprs.front(), MiscLoc,
3751 Exprs.drop_front(), RParenLoc, EndLoc, Clauses);
3753 case OpenACCDirectiveKind::Init: {
3754 return OpenACCInitConstruct::Create(getASTContext(), StartLoc, DirLoc,
3755 EndLoc, Clauses);
3757 case OpenACCDirectiveKind::Shutdown: {
3758 return OpenACCShutdownConstruct::Create(getASTContext(), StartLoc, DirLoc,
3759 EndLoc, Clauses);
3761 case OpenACCDirectiveKind::Set: {
3762 return OpenACCSetConstruct::Create(getASTContext(), StartLoc, DirLoc,
3763 EndLoc, Clauses);
3765 case OpenACCDirectiveKind::Update: {
3766 return OpenACCUpdateConstruct::Create(getASTContext(), StartLoc, DirLoc,
3767 EndLoc, Clauses);
3770 llvm_unreachable("Unhandled case in directive handling?");
3773 StmtResult SemaOpenACC::ActOnAssociatedStmt(
3774 SourceLocation DirectiveLoc, OpenACCDirectiveKind K,
3775 ArrayRef<const OpenACCClause *> Clauses, StmtResult AssocStmt) {
3776 switch (K) {
3777 default:
3778 llvm_unreachable("Unimplemented associated statement application");
3779 case OpenACCDirectiveKind::EnterData:
3780 case OpenACCDirectiveKind::ExitData:
3781 case OpenACCDirectiveKind::Wait:
3782 case OpenACCDirectiveKind::Init:
3783 case OpenACCDirectiveKind::Shutdown:
3784 case OpenACCDirectiveKind::Set:
3785 llvm_unreachable(
3786 "these don't have associated statements, so shouldn't get here");
3787 case OpenACCDirectiveKind::Parallel:
3788 case OpenACCDirectiveKind::Serial:
3789 case OpenACCDirectiveKind::Kernels:
3790 case OpenACCDirectiveKind::Data:
3791 case OpenACCDirectiveKind::HostData:
3792 // There really isn't any checking here that could happen. As long as we
3793 // have a statement to associate, this should be fine.
3794 // OpenACC 3.3 Section 6:
3795 // Structured Block: in C or C++, an executable statement, possibly
3796 // compound, with a single entry at the top and a single exit at the
3797 // bottom.
3798 // FIXME: Should we reject DeclStmt's here? The standard isn't clear, and
3799 // an interpretation of it is to allow this and treat the initializer as
3800 // the 'structured block'.
3801 return AssocStmt;
3802 case OpenACCDirectiveKind::Loop:
3803 case OpenACCDirectiveKind::ParallelLoop:
3804 case OpenACCDirectiveKind::SerialLoop:
3805 case OpenACCDirectiveKind::KernelsLoop:
3806 if (!AssocStmt.isUsable())
3807 return StmtError();
3809 if (!isa<CXXForRangeStmt, ForStmt>(AssocStmt.get())) {
3810 Diag(AssocStmt.get()->getBeginLoc(), diag::err_acc_loop_not_for_loop)
3811 << K;
3812 Diag(DirectiveLoc, diag::note_acc_construct_here) << K;
3813 return StmtError();
3816 if (!CollapseInfo.CollapseDepthSatisfied || !TileInfo.TileDepthSatisfied) {
3817 if (!CollapseInfo.CollapseDepthSatisfied) {
3818 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
3819 << OpenACCClauseKind::Collapse;
3820 assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");
3821 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
3822 diag::note_acc_active_clause_here)
3823 << OpenACCClauseKind::Collapse;
3826 if (!TileInfo.TileDepthSatisfied) {
3827 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
3828 << OpenACCClauseKind::Tile;
3829 assert(TileInfo.ActiveTile && "Collapse count without object?");
3830 Diag(TileInfo.ActiveTile->getBeginLoc(),
3831 diag::note_acc_active_clause_here)
3832 << OpenACCClauseKind::Tile;
3834 return StmtError();
3837 return AssocStmt.get();
3839 llvm_unreachable("Invalid associated statement application");
3842 bool SemaOpenACC::ActOnStartDeclDirective(OpenACCDirectiveKind K,
3843 SourceLocation StartLoc) {
3844 // OpenCC3.3 2.1 (line 889)
3845 // A program must not depend on the order of evaluation of expressions in
3846 // clause arguments or on any side effects of the evaluations.
3847 SemaRef.DiscardCleanupsInEvaluationContext();
3848 SemaRef.PopExpressionEvaluationContext();
3849 return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/false);
3852 DeclGroupRef SemaOpenACC::ActOnEndDeclDirective() { return DeclGroupRef{}; }
3854 ExprResult
3855 SemaOpenACC::BuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {
3856 return OpenACCAsteriskSizeExpr::Create(getASTContext(), AsteriskLoc);
3859 ExprResult
3860 SemaOpenACC::ActOnOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {
3861 return BuildOpenACCAsteriskSizeExpr(AsteriskLoc);