clang 20.0.0git
SemaOpenACC.cpp
Go to the documentation of this file.
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//===----------------------------------------------------------------------===//
13
18#include "clang/Sema/Sema.h"
19#include "llvm/ADT/StringExtras.h"
20#include "llvm/Support/Casting.h"
21
22using namespace clang;
23
24namespace {
25bool 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;
48 }
49 return false;
50}
51
52bool 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;
69 }
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;
90 }
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;
103 }
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;
115 }
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;
125 }
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;
137 }
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;
150 }
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;
164 }
165
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;
181 }
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;
198 }
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;
215 }
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;
231 }
232
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;
246 }
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;
260 }
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;
278 }
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;
294 }
295
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;
306 }
307
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;
318 }
319
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;
331 }
332
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;
352 }
353
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;
363 }
364 }
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;
374 }
375 }
376
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;
387 }
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;
398 }
399 }
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;
410 }
411 }
412 case OpenACCClauseKind::Finalize: {
413 switch (DirectiveKind) {
414 case OpenACCDirectiveKind::ExitData:
415 return true;
416 default:
417 return false;
418 }
419 }
420 case OpenACCClauseKind::IfPresent: {
421 switch (DirectiveKind) {
422 case OpenACCDirectiveKind::HostData:
423 case OpenACCDirectiveKind::Update:
424 return true;
425 default:
426 return false;
427 }
428 }
429 case OpenACCClauseKind::Delete: {
430 switch (DirectiveKind) {
431 case OpenACCDirectiveKind::ExitData:
432 return true;
433 default:
434 return false;
435 }
436 }
437
438 case OpenACCClauseKind::Detach: {
439 switch (DirectiveKind) {
440 case OpenACCDirectiveKind::ExitData:
441 return true;
442 default:
443 return false;
444 }
445 }
446
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;
455 }
456 }
457
458 case OpenACCClauseKind::UseDevice: {
459 switch (DirectiveKind) {
460 case OpenACCDirectiveKind::HostData:
461 return true;
462 default:
463 return false;
464 }
465 }
466 case OpenACCClauseKind::DefaultAsync: {
467 switch (DirectiveKind) {
468 case OpenACCDirectiveKind::Set:
469 return true;
470 default:
471 return false;
472 }
473 }
474 case OpenACCClauseKind::Device: {
475 switch (DirectiveKind) {
476 case OpenACCDirectiveKind::Update:
477 return true;
478 default:
479 return false;
480 }
481 }
482 case OpenACCClauseKind::Host: {
483 switch (DirectiveKind) {
484 case OpenACCDirectiveKind::Update:
485 return true;
486 default:
487 return false;
488 }
489 }
490 }
491
492 default:
493 // Do nothing so we can go to the 'unimplemented' diagnostic instead.
494 return true;
495 }
496 llvm_unreachable("Invalid clause kind");
497}
498
499bool checkAlreadyHasClauseOfKind(
502 const auto *Itr = llvm::find_if(ExistingClauses, [&](const OpenACCClause *C) {
503 return C->getClauseKind() == Clause.getClauseKind();
504 });
505 if (Itr != ExistingClauses.end()) {
506 S.Diag(Clause.getBeginLoc(), diag::err_acc_duplicate_clause_disallowed)
507 << Clause.getDirectiveKind() << Clause.getClauseKind();
508 S.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
509 return true;
510 }
511 return false;
512}
513
514bool checkValidAfterDeviceType(
515 SemaOpenACC &S, const OpenACCDeviceTypeClause &DeviceTypeClause,
516 const SemaOpenACC::OpenACCParsedClause &NewClause) {
517 // This is implemented for everything but 'routine', so treat as 'fine' for
518 // that.
519 if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Routine)
520 return false;
521
522 // OpenACC3.3: Section 2.4: Clauses that precede any device_type clause are
523 // default clauses. Clauses that follow a device_type clause up to the end of
524 // the directive or up to the next device_type clause are device-specific
525 // clauses for the device types specified in the device_type argument.
526 //
527 // The above implies that despite what the individual text says, these are
528 // valid.
529 if (NewClause.getClauseKind() == OpenACCClauseKind::DType ||
530 NewClause.getClauseKind() == OpenACCClauseKind::DeviceType)
531 return false;
532
533 // Implement check from OpenACC3.3: section 2.5.4:
534 // Only the async, wait, num_gangs, num_workers, and vector_length clauses may
535 // follow a device_type clause.
536 if (isOpenACCComputeDirectiveKind(NewClause.getDirectiveKind())) {
537 switch (NewClause.getClauseKind()) {
538 case OpenACCClauseKind::Async:
539 case OpenACCClauseKind::Wait:
540 case OpenACCClauseKind::NumGangs:
541 case OpenACCClauseKind::NumWorkers:
542 case OpenACCClauseKind::VectorLength:
543 return false;
544 default:
545 break;
546 }
547 } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Loop) {
548 // Implement check from OpenACC3.3: section 2.9:
549 // Only the collapse, gang, worker, vector, seq, independent, auto, and tile
550 // clauses may follow a device_type clause.
551 switch (NewClause.getClauseKind()) {
552 case OpenACCClauseKind::Collapse:
553 case OpenACCClauseKind::Gang:
554 case OpenACCClauseKind::Worker:
555 case OpenACCClauseKind::Vector:
556 case OpenACCClauseKind::Seq:
557 case OpenACCClauseKind::Independent:
558 case OpenACCClauseKind::Auto:
559 case OpenACCClauseKind::Tile:
560 return false;
561 default:
562 break;
563 }
564 } else if (isOpenACCCombinedDirectiveKind(NewClause.getDirectiveKind())) {
565 // This seems like it should be the union of 2.9 and 2.5.4 from above.
566 switch (NewClause.getClauseKind()) {
567 case OpenACCClauseKind::Async:
568 case OpenACCClauseKind::Wait:
569 case OpenACCClauseKind::NumGangs:
570 case OpenACCClauseKind::NumWorkers:
571 case OpenACCClauseKind::VectorLength:
572 case OpenACCClauseKind::Collapse:
573 case OpenACCClauseKind::Gang:
574 case OpenACCClauseKind::Worker:
575 case OpenACCClauseKind::Vector:
576 case OpenACCClauseKind::Seq:
577 case OpenACCClauseKind::Independent:
578 case OpenACCClauseKind::Auto:
579 case OpenACCClauseKind::Tile:
580 return false;
581 default:
582 break;
583 }
584 } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Data) {
585 // OpenACC3.3 section 2.6.5: Only the async and wait clauses may follow a
586 // device_type clause.
587 switch (NewClause.getClauseKind()) {
588 case OpenACCClauseKind::Async:
589 case OpenACCClauseKind::Wait:
590 return false;
591 default:
592 break;
593 }
594 } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Set ||
595 NewClause.getDirectiveKind() == OpenACCDirectiveKind::Init ||
596 NewClause.getDirectiveKind() == OpenACCDirectiveKind::Shutdown) {
597 // There are no restrictions on 'set', 'init', or 'shutdown'.
598 return false;
599 } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Update) {
600 // OpenACC3.3 section 2.14.4: Only the async and wait clauses may follow a
601 // device_type clause.
602 switch (NewClause.getClauseKind()) {
603 case OpenACCClauseKind::Async:
604 case OpenACCClauseKind::Wait:
605 return false;
606 default:
607 break;
608 }
609 }
610 S.Diag(NewClause.getBeginLoc(), diag::err_acc_clause_after_device_type)
611 << NewClause.getClauseKind() << DeviceTypeClause.getClauseKind()
612 << NewClause.getDirectiveKind();
613 S.Diag(DeviceTypeClause.getBeginLoc(), diag::note_acc_previous_clause_here);
614 return true;
615}
616
617// A temporary function that helps implement the 'not implemented' check at the
618// top of each clause checking function. This should only be used in conjunction
619// with the one being currently implemented/only updated after the entire
620// construct has been implemented.
621bool isDirectiveKindImplemented(OpenACCDirectiveKind DK) {
624 DK == OpenACCDirectiveKind::Loop || DK == OpenACCDirectiveKind::Wait ||
625 DK == OpenACCDirectiveKind::Init ||
626 DK == OpenACCDirectiveKind::Shutdown ||
627 DK == OpenACCDirectiveKind::Set;
628}
629
630class SemaOpenACCClauseVisitor {
631 SemaOpenACC &SemaRef;
632 ASTContext &Ctx;
633 ArrayRef<const OpenACCClause *> ExistingClauses;
634 bool NotImplemented = false;
635
636 OpenACCClause *isNotImplemented() {
637 NotImplemented = true;
638 return nullptr;
639 }
640
641 // OpenACC 3.3 2.9:
642 // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' clause
643 // appears.
644 bool DiagIfSeqClause(SemaOpenACC::OpenACCParsedClause &Clause) {
645 const auto *Itr =
646 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSeqClause>);
647
648 if (Itr != ExistingClauses.end()) {
649 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine)
650 << Clause.getClauseKind() << (*Itr)->getClauseKind()
651 << Clause.getDirectiveKind();
652 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
653
654 return true;
655 }
656 return false;
657 }
658
659public:
660 SemaOpenACCClauseVisitor(SemaOpenACC &S,
661 ArrayRef<const OpenACCClause *> ExistingClauses)
662 : SemaRef(S), Ctx(S.getASTContext()), ExistingClauses(ExistingClauses) {}
663 // Once we've implemented everything, we shouldn't need this infrastructure.
664 // But in the meantime, we use this to help decide whether the clause was
665 // handled for this directive.
666 bool diagNotImplemented() { return NotImplemented; }
667
669 switch (Clause.getClauseKind()) {
670#define VISIT_CLAUSE(CLAUSE_NAME) \
671 case OpenACCClauseKind::CLAUSE_NAME: \
672 return Visit##CLAUSE_NAME##Clause(Clause);
673#define CLAUSE_ALIAS(ALIAS, CLAUSE_NAME, DEPRECATED) \
674 case OpenACCClauseKind::ALIAS: \
675 if (DEPRECATED) \
676 SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name) \
677 << Clause.getClauseKind() << OpenACCClauseKind::CLAUSE_NAME; \
678 return Visit##CLAUSE_NAME##Clause(Clause);
679#include "clang/Basic/OpenACCClauses.def"
680 default:
681 return isNotImplemented();
682 }
683 llvm_unreachable("Invalid clause kind");
684 }
685
686#define VISIT_CLAUSE(CLAUSE_NAME) \
687 OpenACCClause *Visit##CLAUSE_NAME##Clause( \
688 SemaOpenACC::OpenACCParsedClause &Clause);
689#include "clang/Basic/OpenACCClauses.def"
690};
691
692OpenACCClause *SemaOpenACCClauseVisitor::VisitDefaultClause(
694 // Don't add an invalid clause to the AST.
695 if (Clause.getDefaultClauseKind() == OpenACCDefaultClauseKind::Invalid)
696 return nullptr;
697
698 // OpenACC 3.3, Section 2.5.4:
699 // At most one 'default' clause may appear, and it must have a value of
700 // either 'none' or 'present'.
701 // Second half of the sentence is diagnosed during parsing.
702 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
703 return nullptr;
704
706 Ctx, Clause.getDefaultClauseKind(), Clause.getBeginLoc(),
707 Clause.getLParenLoc(), Clause.getEndLoc());
708}
709
710OpenACCClause *SemaOpenACCClauseVisitor::VisitTileClause(
712
713 // Duplicates here are not really sensible. We could possible permit
714 // multiples if they all had the same value, but there isn't really a good
715 // reason to do so. Also, this simplifies the suppression of duplicates, in
716 // that we know if we 'find' one after instantiation, that it is the same
717 // clause, which simplifies instantiation/checking/etc.
718 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
719 return nullptr;
720
721 llvm::SmallVector<Expr *> NewSizeExprs;
722
723 // Make sure these are all positive constant expressions or *.
724 for (Expr *E : Clause.getIntExprs()) {
725 ExprResult Res = SemaRef.CheckTileSizeExpr(E);
726
727 if (!Res.isUsable())
728 return nullptr;
729
730 NewSizeExprs.push_back(Res.get());
731 }
732
733 return OpenACCTileClause::Create(Ctx, Clause.getBeginLoc(),
734 Clause.getLParenLoc(), NewSizeExprs,
735 Clause.getEndLoc());
736}
737
738OpenACCClause *SemaOpenACCClauseVisitor::VisitIfClause(
740 // There is no prose in the standard that says duplicates aren't allowed,
741 // but this diagnostic is present in other compilers, as well as makes
742 // sense. Prose DOES exist for 'data' and 'host_data', 'set', 'enter data' and
743 // 'exit data' both don't, but other implmementations do this. OpenACC issue
744 // 519 filed for the latter two. Prose also exists for 'update'.
745 // GCC allows this on init/shutdown, presumably for good reason, so we do too.
746 if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Init &&
747 Clause.getDirectiveKind() != OpenACCDirectiveKind::Shutdown &&
748 checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
749 return nullptr;
750
751 // The parser has ensured that we have a proper condition expr, so there
752 // isn't really much to do here.
753
754 // If the 'if' clause is true, it makes the 'self' clause have no effect,
755 // diagnose that here. This only applies on compute/combined constructs.
756 if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Update) {
757 const auto *Itr =
758 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSelfClause>);
759 if (Itr != ExistingClauses.end()) {
760 SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict);
761 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
762 }
763 }
764
765 return OpenACCIfClause::Create(Ctx, Clause.getBeginLoc(),
766 Clause.getLParenLoc(),
767 Clause.getConditionExpr(), Clause.getEndLoc());
768}
769
770OpenACCClause *SemaOpenACCClauseVisitor::VisitSelfClause(
772 // There is no prose in the standard that says duplicates aren't allowed,
773 // but this diagnostic is present in other compilers, as well as makes
774 // sense.
775 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
776 return nullptr;
777
778 // If the 'if' clause is true, it makes the 'self' clause have no effect,
779 // diagnose that here. This only applies on compute/combined constructs.
780 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Update)
781 return OpenACCSelfClause::Create(Ctx, Clause.getBeginLoc(),
782 Clause.getLParenLoc(), Clause.getVarList(),
783 Clause.getEndLoc());
784
785 const auto *Itr =
786 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCIfClause>);
787 if (Itr != ExistingClauses.end()) {
788 SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict);
789 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
790 }
792 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(),
793 Clause.getConditionExpr(), Clause.getEndLoc());
794}
795
796OpenACCClause *SemaOpenACCClauseVisitor::VisitNumGangsClause(
798 // There is no prose in the standard that says duplicates aren't allowed,
799 // but this diagnostic is present in other compilers, as well as makes
800 // sense.
801 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
802 return nullptr;
803
804 // num_gangs requires at least 1 int expr in all forms. Diagnose here, but
805 // allow us to continue, an empty clause might be useful for future
806 // diagnostics.
807 if (Clause.getIntExprs().empty())
808 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args)
809 << /*NoArgs=*/0;
810
811 unsigned MaxArgs =
812 (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel ||
813 Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop)
814 ? 3
815 : 1;
816 // The max number of args differs between parallel and other constructs.
817 // Again, allow us to continue for the purposes of future diagnostics.
818 if (Clause.getIntExprs().size() > MaxArgs)
819 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args)
820 << /*NoArgs=*/1 << Clause.getDirectiveKind() << MaxArgs
821 << Clause.getIntExprs().size();
822
823 // OpenACC 3.3 Section 2.9.11: A reduction clause may not appear on a loop
824 // directive that has a gang clause and is within a compute construct that has
825 // a num_gangs clause with more than one explicit argument.
826 if (Clause.getIntExprs().size() > 1 &&
828 auto *GangClauseItr =
829 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCGangClause>);
830 auto *ReductionClauseItr =
831 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>);
832
833 if (GangClauseItr != ExistingClauses.end() &&
834 ReductionClauseItr != ExistingClauses.end()) {
835 SemaRef.Diag(Clause.getBeginLoc(),
836 diag::err_acc_gang_reduction_numgangs_conflict)
837 << OpenACCClauseKind::Reduction << OpenACCClauseKind::Gang
838 << Clause.getDirectiveKind() << /*is on combined directive=*/1;
839 SemaRef.Diag((*ReductionClauseItr)->getBeginLoc(),
840 diag::note_acc_previous_clause_here);
841 SemaRef.Diag((*GangClauseItr)->getBeginLoc(),
842 diag::note_acc_previous_clause_here);
843 return nullptr;
844 }
845 }
846
847 // OpenACC 3.3 Section 2.5.4:
848 // A reduction clause may not appear on a parallel construct with a
849 // num_gangs clause that has more than one argument.
850 if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel ||
851 Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop) &&
852 Clause.getIntExprs().size() > 1) {
853 auto *Parallel =
854 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>);
855
856 if (Parallel != ExistingClauses.end()) {
857 SemaRef.Diag(Clause.getBeginLoc(),
858 diag::err_acc_reduction_num_gangs_conflict)
859 << /*>1 arg in first loc=*/1 << Clause.getClauseKind()
860 << Clause.getDirectiveKind() << OpenACCClauseKind::Reduction;
861 SemaRef.Diag((*Parallel)->getBeginLoc(),
862 diag::note_acc_previous_clause_here);
863 return nullptr;
864 }
865 }
866
867 // OpenACC 3.3 Section 2.9.2:
868 // An argument with no keyword or with the 'num' keyword is allowed only when
869 // the 'num_gangs' does not appear on the 'kernel' construct.
870 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) {
871 auto GangClauses = llvm::make_filter_range(
872 ExistingClauses, llvm::IsaPred<OpenACCGangClause>);
873
874 for (auto *GC : GangClauses) {
875 if (cast<OpenACCGangClause>(GC)->hasExprOfKind(OpenACCGangKind::Num)) {
876 SemaRef.Diag(Clause.getBeginLoc(),
877 diag::err_acc_num_arg_conflict_reverse)
878 << OpenACCClauseKind::NumGangs << OpenACCClauseKind::Gang
879 << /*Num argument*/ 1;
880 SemaRef.Diag(GC->getBeginLoc(), diag::note_acc_previous_clause_here);
881 return nullptr;
882 }
883 }
884 }
885
887 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs(),
888 Clause.getEndLoc());
889}
890
891OpenACCClause *SemaOpenACCClauseVisitor::VisitNumWorkersClause(
893 // There is no prose in the standard that says duplicates aren't allowed,
894 // but this diagnostic is present in other compilers, as well as makes
895 // sense.
896 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
897 return nullptr;
898
899 // OpenACC 3.3 Section 2.9.2:
900 // An argument is allowed only when the 'num_workers' does not appear on the
901 // kernels construct.
902 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) {
903 auto WorkerClauses = llvm::make_filter_range(
904 ExistingClauses, llvm::IsaPred<OpenACCWorkerClause>);
905
906 for (auto *WC : WorkerClauses) {
907 if (cast<OpenACCWorkerClause>(WC)->hasIntExpr()) {
908 SemaRef.Diag(Clause.getBeginLoc(),
909 diag::err_acc_num_arg_conflict_reverse)
910 << OpenACCClauseKind::NumWorkers << OpenACCClauseKind::Worker
911 << /*num argument*/ 0;
912 SemaRef.Diag(WC->getBeginLoc(), diag::note_acc_previous_clause_here);
913 return nullptr;
914 }
915 }
916 }
917
918 assert(Clause.getIntExprs().size() == 1 &&
919 "Invalid number of expressions for NumWorkers");
921 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0],
922 Clause.getEndLoc());
923}
924
925OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorLengthClause(
927 // There is no prose in the standard that says duplicates aren't allowed,
928 // but this diagnostic is present in other compilers, as well as makes
929 // sense.
930 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
931 return nullptr;
932
933 // OpenACC 3.3 Section 2.9.4:
934 // An argument is allowed only when the 'vector_length' does not appear on the
935 // 'kernels' construct.
936 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) {
937 auto VectorClauses = llvm::make_filter_range(
938 ExistingClauses, llvm::IsaPred<OpenACCVectorClause>);
939
940 for (auto *VC : VectorClauses) {
941 if (cast<OpenACCVectorClause>(VC)->hasIntExpr()) {
942 SemaRef.Diag(Clause.getBeginLoc(),
943 diag::err_acc_num_arg_conflict_reverse)
944 << OpenACCClauseKind::VectorLength << OpenACCClauseKind::Vector
945 << /*num argument*/ 0;
946 SemaRef.Diag(VC->getBeginLoc(), diag::note_acc_previous_clause_here);
947 return nullptr;
948 }
949 }
950 }
951
952 assert(Clause.getIntExprs().size() == 1 &&
953 "Invalid number of expressions for NumWorkers");
955 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0],
956 Clause.getEndLoc());
957}
958
959OpenACCClause *SemaOpenACCClauseVisitor::VisitAsyncClause(
961 // There is no prose in the standard that says duplicates aren't allowed,
962 // but this diagnostic is present in other compilers, as well as makes
963 // sense.
964 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
965 return nullptr;
966
967 assert(Clause.getNumIntExprs() < 2 &&
968 "Invalid number of expressions for Async");
970 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(),
971 Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr,
972 Clause.getEndLoc());
973}
974
975OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceNumClause(
977 // Restrictions only properly implemented on certain constructs, so skip/treat
978 // as unimplemented in those cases.
979 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
980 return isNotImplemented();
981
982 // OpenACC 3.3 2.14.3: Two instances of the same clause may not appear on the
983 // same directive.
984 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Set &&
985 checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
986 return nullptr;
987
988 assert(Clause.getNumIntExprs() == 1 &&
989 "Invalid number of expressions for device_num");
991 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0],
992 Clause.getEndLoc());
993}
994
995OpenACCClause *SemaOpenACCClauseVisitor::VisitDefaultAsyncClause(
997 // OpenACC 3.3 2.14.3: Two instances of the same clause may not appear on the
998 // same directive.
999 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
1000 return nullptr;
1001
1002 assert(Clause.getNumIntExprs() == 1 &&
1003 "Invalid number of expressions for default_async");
1005 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0],
1006 Clause.getEndLoc());
1007}
1008
1009OpenACCClause *SemaOpenACCClauseVisitor::VisitPrivateClause(
1011 // ActOnVar ensured that everything is a valid variable reference, so there
1012 // really isn't anything to do here. GCC does some duplicate-finding, though
1013 // it isn't apparent in the standard where this is justified.
1014
1015 return OpenACCPrivateClause::Create(Ctx, Clause.getBeginLoc(),
1016 Clause.getLParenLoc(),
1017 Clause.getVarList(), Clause.getEndLoc());
1018}
1019
1020OpenACCClause *SemaOpenACCClauseVisitor::VisitFirstPrivateClause(
1022 // ActOnVar ensured that everything is a valid variable reference, so there
1023 // really isn't anything to do here. GCC does some duplicate-finding, though
1024 // it isn't apparent in the standard where this is justified.
1025
1027 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(),
1028 Clause.getEndLoc());
1029}
1030
1031OpenACCClause *SemaOpenACCClauseVisitor::VisitNoCreateClause(
1033 // ActOnVar ensured that everything is a valid variable reference, so there
1034 // really isn't anything to do here. GCC does some duplicate-finding, though
1035 // it isn't apparent in the standard where this is justified.
1036
1037 return OpenACCNoCreateClause::Create(Ctx, Clause.getBeginLoc(),
1038 Clause.getLParenLoc(),
1039 Clause.getVarList(), Clause.getEndLoc());
1040}
1041
1042OpenACCClause *SemaOpenACCClauseVisitor::VisitPresentClause(
1044 // Restrictions only properly implemented on 'compute'/'combined'/'data'
1045 // constructs, and 'compute'/'combined'/'data' constructs are the only
1046 // construct that can do anything with this yet, so skip/treat as
1047 // unimplemented in this case.
1048 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1049 return isNotImplemented();
1050 // ActOnVar ensured that everything is a valid variable reference, so there
1051 // really isn't anything to do here. GCC does some duplicate-finding, though
1052 // it isn't apparent in the standard where this is justified.
1053
1054 return OpenACCPresentClause::Create(Ctx, Clause.getBeginLoc(),
1055 Clause.getLParenLoc(),
1056 Clause.getVarList(), Clause.getEndLoc());
1057}
1058
1059OpenACCClause *SemaOpenACCClauseVisitor::VisitHostClause(
1061 // ActOnVar ensured that everything is a valid variable reference, so there
1062 // really isn't anything to do here. GCC does some duplicate-finding, though
1063 // it isn't apparent in the standard where this is justified.
1064
1065 return OpenACCHostClause::Create(Ctx, Clause.getBeginLoc(),
1066 Clause.getLParenLoc(), Clause.getVarList(),
1067 Clause.getEndLoc());
1068}
1069
1070OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceClause(
1072 // ActOnVar ensured that everything is a valid variable reference, so there
1073 // really isn't anything to do here. GCC does some duplicate-finding, though
1074 // it isn't apparent in the standard where this is justified.
1075
1076 return OpenACCDeviceClause::Create(Ctx, Clause.getBeginLoc(),
1077 Clause.getLParenLoc(), Clause.getVarList(),
1078 Clause.getEndLoc());
1079}
1080
1081OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyClause(
1083 // Restrictions only properly implemented on 'compute'/'combined'/'data'
1084 // constructs, and 'compute'/'combined'/'data' constructs are the only
1085 // construct that can do anything with this yet, so skip/treat as
1086 // unimplemented in this case.
1087 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1088 return isNotImplemented();
1089 // ActOnVar ensured that everything is a valid variable reference, so there
1090 // really isn't anything to do here. GCC does some duplicate-finding, though
1091 // it isn't apparent in the standard where this is justified.
1092
1094 Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
1095 Clause.getVarList(), Clause.getEndLoc());
1096}
1097
1098OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyInClause(
1100 // Restrictions only properly implemented on 'compute'/'combined'/'data'
1101 // constructs, and 'compute'/'combined'/'data' constructs are the only
1102 // construct that can do anything with this yet, so skip/treat as
1103 // unimplemented in this case.
1104 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1105 return isNotImplemented();
1106 // ActOnVar ensured that everything is a valid variable reference, so there
1107 // really isn't anything to do here. GCC does some duplicate-finding, though
1108 // it isn't apparent in the standard where this is justified.
1109
1111 Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
1112 Clause.isReadOnly(), Clause.getVarList(), Clause.getEndLoc());
1113}
1114
1115OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyOutClause(
1117 // Restrictions only properly implemented on 'compute'/'combined'/'data'
1118 // constructs, and 'compute'/'combined'/'data' constructs are the only
1119 // construct that can do anything with this yet, so skip/treat as
1120 // unimplemented in this case.
1121 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1122 return isNotImplemented();
1123 // ActOnVar ensured that everything is a valid variable reference, so there
1124 // really isn't anything to do here. GCC does some duplicate-finding, though
1125 // it isn't apparent in the standard where this is justified.
1126
1128 Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
1129 Clause.isZero(), Clause.getVarList(), Clause.getEndLoc());
1130}
1131
1132OpenACCClause *SemaOpenACCClauseVisitor::VisitCreateClause(
1134 // ActOnVar ensured that everything is a valid variable reference, so there
1135 // really isn't anything to do here. GCC does some duplicate-finding, though
1136 // it isn't apparent in the standard where this is justified.
1137
1139 Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
1140 Clause.isZero(), Clause.getVarList(), Clause.getEndLoc());
1141}
1142
1143OpenACCClause *SemaOpenACCClauseVisitor::VisitAttachClause(
1145 // ActOnVar ensured that everything is a valid variable reference, but we
1146 // still have to make sure it is a pointer type.
1147 llvm::SmallVector<Expr *> VarList{Clause.getVarList()};
1148 llvm::erase_if(VarList, [&](Expr *E) {
1149 return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::Attach, E);
1150 });
1151 Clause.setVarListDetails(VarList,
1152 /*IsReadOnly=*/false, /*IsZero=*/false);
1153 return OpenACCAttachClause::Create(Ctx, Clause.getBeginLoc(),
1154 Clause.getLParenLoc(), Clause.getVarList(),
1155 Clause.getEndLoc());
1156}
1157
1158OpenACCClause *SemaOpenACCClauseVisitor::VisitDetachClause(
1160 // ActOnVar ensured that everything is a valid variable reference, but we
1161 // still have to make sure it is a pointer type.
1162 llvm::SmallVector<Expr *> VarList{Clause.getVarList()};
1163 llvm::erase_if(VarList, [&](Expr *E) {
1164 return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::Detach, E);
1165 });
1166 Clause.setVarListDetails(VarList,
1167 /*IsReadOnly=*/false, /*IsZero=*/false);
1168 return OpenACCDetachClause::Create(Ctx, Clause.getBeginLoc(),
1169 Clause.getLParenLoc(), Clause.getVarList(),
1170 Clause.getEndLoc());
1171}
1172
1173OpenACCClause *SemaOpenACCClauseVisitor::VisitDeleteClause(
1175 // ActOnVar ensured that everything is a valid variable reference, so there
1176 // really isn't anything to do here. GCC does some duplicate-finding, though
1177 // it isn't apparent in the standard where this is justified.
1178 return OpenACCDeleteClause::Create(Ctx, Clause.getBeginLoc(),
1179 Clause.getLParenLoc(), Clause.getVarList(),
1180 Clause.getEndLoc());
1181}
1182
1183OpenACCClause *SemaOpenACCClauseVisitor::VisitUseDeviceClause(
1185 // ActOnVar ensured that everything is a valid variable or array, so nothing
1186 // left to do here.
1188 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(),
1189 Clause.getEndLoc());
1190}
1191
1192OpenACCClause *SemaOpenACCClauseVisitor::VisitDevicePtrClause(
1194 // Restrictions only properly implemented on 'compute'/'combined'/'data'
1195 // constructs, and 'compute'/'combined'/'data' constructs are the only
1196 // construct that can do anything with this yet, so skip/treat as
1197 // unimplemented in this case.
1198 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1199 return isNotImplemented();
1200
1201 // ActOnVar ensured that everything is a valid variable reference, but we
1202 // still have to make sure it is a pointer type.
1203 llvm::SmallVector<Expr *> VarList{Clause.getVarList()};
1204 llvm::erase_if(VarList, [&](Expr *E) {
1205 return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::DevicePtr, E);
1206 });
1207 Clause.setVarListDetails(VarList,
1208 /*IsReadOnly=*/false, /*IsZero=*/false);
1209
1211 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(),
1212 Clause.getEndLoc());
1213}
1214
1215OpenACCClause *SemaOpenACCClauseVisitor::VisitWaitClause(
1218 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getDevNumExpr(),
1219 Clause.getQueuesLoc(), Clause.getQueueIdExprs(), Clause.getEndLoc());
1220}
1221
1222OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceTypeClause(
1224 // Restrictions implemented properly on everything except 'routine'.
1225 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Routine)
1226 return isNotImplemented();
1227
1228 // OpenACC 3.3 2.14.3: Two instances of the same clause may not appear on the
1229 // same directive.
1230 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Set &&
1231 checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
1232 return nullptr;
1233
1234 // TODO OpenACC: Once we get enough of the CodeGen implemented that we have
1235 // a source for the list of valid architectures, we need to warn on unknown
1236 // identifiers here.
1237
1239 Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
1240 Clause.getDeviceTypeArchitectures(), Clause.getEndLoc());
1241}
1242
1243OpenACCClause *SemaOpenACCClauseVisitor::VisitAutoClause(
1245 // OpenACC 3.3 2.9:
1246 // Only one of the seq, independent, and auto clauses may appear.
1247 const auto *Itr =
1248 llvm::find_if(ExistingClauses,
1249 llvm::IsaPred<OpenACCIndependentClause, OpenACCSeqClause>);
1250 if (Itr != ExistingClauses.end()) {
1251 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict)
1252 << Clause.getClauseKind() << Clause.getDirectiveKind();
1253 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1254 return nullptr;
1255 }
1256
1257 return OpenACCAutoClause::Create(Ctx, Clause.getBeginLoc(),
1258 Clause.getEndLoc());
1259}
1260
1261OpenACCClause *SemaOpenACCClauseVisitor::VisitIndependentClause(
1263 // OpenACC 3.3 2.9:
1264 // Only one of the seq, independent, and auto clauses may appear.
1265 const auto *Itr = llvm::find_if(
1266 ExistingClauses, llvm::IsaPred<OpenACCAutoClause, OpenACCSeqClause>);
1267 if (Itr != ExistingClauses.end()) {
1268 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict)
1269 << Clause.getClauseKind() << Clause.getDirectiveKind();
1270 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1271 return nullptr;
1272 }
1273
1274 return OpenACCIndependentClause::Create(Ctx, Clause.getBeginLoc(),
1275 Clause.getEndLoc());
1276}
1277
1278ExprResult CheckGangStaticExpr(SemaOpenACC &S, Expr *E) {
1279 if (isa<OpenACCAsteriskSizeExpr>(E))
1280 return E;
1281 return S.ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Gang,
1282 E->getBeginLoc(), E);
1283}
1284
1285bool IsOrphanLoop(OpenACCDirectiveKind DK, OpenACCDirectiveKind AssocKind) {
1286 return DK == OpenACCDirectiveKind::Loop &&
1287 AssocKind == OpenACCDirectiveKind::Invalid;
1288}
1289
1290bool HasAssocKind(OpenACCDirectiveKind DK, OpenACCDirectiveKind AssocKind) {
1291 return DK == OpenACCDirectiveKind::Loop &&
1292 AssocKind != OpenACCDirectiveKind::Invalid;
1293}
1294
1295ExprResult DiagIntArgInvalid(SemaOpenACC &S, Expr *E, OpenACCGangKind GK,
1297 OpenACCDirectiveKind AssocKind) {
1298 S.Diag(E->getBeginLoc(), diag::err_acc_int_arg_invalid)
1299 << GK << CK << IsOrphanLoop(DK, AssocKind) << DK
1300 << HasAssocKind(DK, AssocKind) << AssocKind;
1301 return ExprError();
1302}
1303ExprResult DiagIntArgInvalid(SemaOpenACC &S, Expr *E, StringRef TagKind,
1305 OpenACCDirectiveKind AssocKind) {
1306 S.Diag(E->getBeginLoc(), diag::err_acc_int_arg_invalid)
1307 << TagKind << CK << IsOrphanLoop(DK, AssocKind) << DK
1308 << HasAssocKind(DK, AssocKind) << AssocKind;
1309 return ExprError();
1310}
1311
1312ExprResult CheckGangParallelExpr(SemaOpenACC &S, OpenACCDirectiveKind DK,
1313 OpenACCDirectiveKind AssocKind,
1314 OpenACCGangKind GK, Expr *E) {
1315 switch (GK) {
1316 case OpenACCGangKind::Static:
1317 return CheckGangStaticExpr(S, E);
1318 case OpenACCGangKind::Num:
1319 // OpenACC 3.3 2.9.2: When the parent compute construct is a parallel
1320 // construct, or an orphaned loop construct, the gang clause behaves as
1321 // follows. ... The num argument is not allowed.
1322 return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind);
1323 case OpenACCGangKind::Dim: {
1324 // OpenACC 3.3 2.9.2: When the parent compute construct is a parallel
1325 // construct, or an orphaned loop construct, the gang clause behaves as
1326 // follows. ... The dim argument must be a constant positive integer value
1327 // 1, 2, or 3.
1328 if (!E)
1329 return ExprError();
1330 ExprResult Res =
1331 S.ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Gang,
1332 E->getBeginLoc(), E);
1333
1334 if (!Res.isUsable())
1335 return Res;
1336
1337 if (Res.get()->isInstantiationDependent())
1338 return Res;
1339
1340 std::optional<llvm::APSInt> ICE =
1342
1343 if (!ICE || *ICE <= 0 || ICE > 3) {
1344 S.Diag(Res.get()->getBeginLoc(), diag::err_acc_gang_dim_value)
1345 << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue();
1346 return ExprError();
1347 }
1348
1349 return ExprResult{
1350 ConstantExpr::Create(S.getASTContext(), Res.get(), APValue{*ICE})};
1351 }
1352 }
1353 llvm_unreachable("Unknown gang kind in gang parallel check");
1354}
1355
1356ExprResult CheckGangKernelsExpr(SemaOpenACC &S,
1357 ArrayRef<const OpenACCClause *> ExistingClauses,
1359 OpenACCDirectiveKind AssocKind,
1360 OpenACCGangKind GK, Expr *E) {
1361 switch (GK) {
1362 // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
1363 // construct, the gang clause behaves as follows. ... The dim argument is
1364 // not allowed.
1365 case OpenACCGangKind::Dim:
1366 return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind);
1367 case OpenACCGangKind::Num: {
1368 // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
1369 // construct, the gang clause behaves as follows. ... An argument with no
1370 // keyword or with num keyword is only allowed when num_gangs does not
1371 // appear on the kernels construct. ... The region of a loop with the gang
1372 // clause may not contain another loop with a gang clause unless within a
1373 // nested compute region.
1374
1375 // If this is a 'combined' construct, search the list of existing clauses.
1376 // Else we need to search the containing 'kernel'.
1377 auto Collection = isOpenACCCombinedDirectiveKind(DK)
1378 ? ExistingClauses
1379 : S.getActiveComputeConstructInfo().Clauses;
1380
1381 const auto *Itr =
1382 llvm::find_if(Collection, llvm::IsaPred<OpenACCNumGangsClause>);
1383
1384 if (Itr != Collection.end()) {
1385 S.Diag(E->getBeginLoc(), diag::err_acc_num_arg_conflict)
1386 << "num" << OpenACCClauseKind::Gang << DK
1387 << HasAssocKind(DK, AssocKind) << AssocKind
1388 << OpenACCClauseKind::NumGangs;
1389
1390 S.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1391 return ExprError();
1392 }
1393 return ExprResult{E};
1394 }
1395 case OpenACCGangKind::Static:
1396 return CheckGangStaticExpr(S, E);
1397 return ExprError();
1398 }
1399 llvm_unreachable("Unknown gang kind in gang kernels check");
1400}
1401
1402ExprResult CheckGangSerialExpr(SemaOpenACC &S, OpenACCDirectiveKind DK,
1403 OpenACCDirectiveKind AssocKind,
1404 OpenACCGangKind GK, Expr *E) {
1405 switch (GK) {
1406 // 'dim' and 'num' don't really make sense on serial, and GCC rejects them
1407 // too, so we disallow them too.
1408 case OpenACCGangKind::Dim:
1409 case OpenACCGangKind::Num:
1410 return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind);
1411 case OpenACCGangKind::Static:
1412 return CheckGangStaticExpr(S, E);
1413 }
1414 llvm_unreachable("Unknown gang kind in gang serial check");
1415}
1416
1417OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorClause(
1419 if (DiagIfSeqClause(Clause))
1420 return nullptr;
1421
1422 // Restrictions only properly implemented on 'loop'/'combined' constructs, and
1423 // it is the only construct that can do anything with this, so skip/treat as
1424 // unimplemented for the routine constructs.
1425 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1426 return isNotImplemented();
1427
1428 Expr *IntExpr =
1429 Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr;
1430 if (IntExpr) {
1432 switch (SemaRef.getActiveComputeConstructInfo().Kind) {
1433 case OpenACCDirectiveKind::Invalid:
1434 case OpenACCDirectiveKind::Parallel:
1435 // No restriction on when 'parallel' can contain an argument.
1436 break;
1437 case OpenACCDirectiveKind::Serial:
1438 // GCC disallows this, and there is no real good reason for us to permit
1439 // it, so disallow until we come up with a use case that makes sense.
1440 DiagIntArgInvalid(SemaRef, IntExpr, "length", OpenACCClauseKind::Vector,
1441 Clause.getDirectiveKind(),
1442 SemaRef.getActiveComputeConstructInfo().Kind);
1443 IntExpr = nullptr;
1444 break;
1445 case OpenACCDirectiveKind::Kernels: {
1446 const auto *Itr =
1447 llvm::find_if(SemaRef.getActiveComputeConstructInfo().Clauses,
1448 llvm::IsaPred<OpenACCVectorLengthClause>);
1449 if (Itr != SemaRef.getActiveComputeConstructInfo().Clauses.end()) {
1450 SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1451 << "length" << OpenACCClauseKind::Vector
1452 << Clause.getDirectiveKind()
1453 << HasAssocKind(Clause.getDirectiveKind(),
1454 SemaRef.getActiveComputeConstructInfo().Kind)
1455 << SemaRef.getActiveComputeConstructInfo().Kind
1456 << OpenACCClauseKind::VectorLength;
1457 SemaRef.Diag((*Itr)->getBeginLoc(),
1458 diag::note_acc_previous_clause_here);
1459
1460 IntExpr = nullptr;
1461 }
1462 break;
1463 }
1464 default:
1465 llvm_unreachable("Non compute construct in active compute construct");
1466 }
1467 } else {
1468 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::SerialLoop) {
1469 DiagIntArgInvalid(SemaRef, IntExpr, "length", OpenACCClauseKind::Vector,
1470 Clause.getDirectiveKind(),
1471 SemaRef.getActiveComputeConstructInfo().Kind);
1472 IntExpr = nullptr;
1473 } else if (Clause.getDirectiveKind() ==
1474 OpenACCDirectiveKind::KernelsLoop) {
1475 const auto *Itr = llvm::find_if(
1476 ExistingClauses, llvm::IsaPred<OpenACCVectorLengthClause>);
1477 if (Itr != ExistingClauses.end()) {
1478 SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1479 << "length" << OpenACCClauseKind::Vector
1480 << Clause.getDirectiveKind()
1481 << HasAssocKind(Clause.getDirectiveKind(),
1482 SemaRef.getActiveComputeConstructInfo().Kind)
1483 << SemaRef.getActiveComputeConstructInfo().Kind
1484 << OpenACCClauseKind::VectorLength;
1485 SemaRef.Diag((*Itr)->getBeginLoc(),
1486 diag::note_acc_previous_clause_here);
1487
1488 IntExpr = nullptr;
1489 }
1490 }
1491 }
1492 }
1493
1495 // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1496 // contain a loop with a gang, worker, or vector clause unless within a
1497 // nested compute region.
1498 if (SemaRef.LoopVectorClauseLoc.isValid()) {
1499 // This handles the 'inner loop' diagnostic, but we cannot set that we're
1500 // on one of these until we get to the end of the construct.
1501 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1502 << OpenACCClauseKind::Vector << OpenACCClauseKind::Vector
1503 << /*skip kernels construct info*/ 0;
1504 SemaRef.Diag(SemaRef.LoopVectorClauseLoc,
1505 diag::note_acc_previous_clause_here);
1506 return nullptr;
1507 }
1508 }
1509
1510 return OpenACCVectorClause::Create(Ctx, Clause.getBeginLoc(),
1511 Clause.getLParenLoc(), IntExpr,
1512 Clause.getEndLoc());
1513}
1514
1515OpenACCClause *SemaOpenACCClauseVisitor::VisitWorkerClause(
1517 if (DiagIfSeqClause(Clause))
1518 return nullptr;
1519
1520 // Restrictions only properly implemented on 'loop'/'combined' constructs, and
1521 // it is the only construct that can do anything with this, so skip/treat as
1522 // unimplemented for the routine constructs.
1523 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1524 return isNotImplemented();
1525
1526 Expr *IntExpr =
1527 Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr;
1528
1529 if (IntExpr) {
1531 switch (SemaRef.getActiveComputeConstructInfo().Kind) {
1532 case OpenACCDirectiveKind::Invalid:
1533 case OpenACCDirectiveKind::ParallelLoop:
1534 case OpenACCDirectiveKind::SerialLoop:
1535 case OpenACCDirectiveKind::Parallel:
1536 case OpenACCDirectiveKind::Serial:
1537 DiagIntArgInvalid(SemaRef, IntExpr, OpenACCGangKind::Num,
1538 OpenACCClauseKind::Worker, Clause.getDirectiveKind(),
1539 SemaRef.getActiveComputeConstructInfo().Kind);
1540 IntExpr = nullptr;
1541 break;
1542 case OpenACCDirectiveKind::KernelsLoop:
1543 case OpenACCDirectiveKind::Kernels: {
1544 const auto *Itr =
1545 llvm::find_if(SemaRef.getActiveComputeConstructInfo().Clauses,
1546 llvm::IsaPred<OpenACCNumWorkersClause>);
1547 if (Itr != SemaRef.getActiveComputeConstructInfo().Clauses.end()) {
1548 SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1549 << "num" << OpenACCClauseKind::Worker << Clause.getDirectiveKind()
1550 << HasAssocKind(Clause.getDirectiveKind(),
1551 SemaRef.getActiveComputeConstructInfo().Kind)
1552 << SemaRef.getActiveComputeConstructInfo().Kind
1553 << OpenACCClauseKind::NumWorkers;
1554 SemaRef.Diag((*Itr)->getBeginLoc(),
1555 diag::note_acc_previous_clause_here);
1556
1557 IntExpr = nullptr;
1558 }
1559 break;
1560 }
1561 default:
1562 llvm_unreachable("Non compute construct in active compute construct");
1563 }
1564 } else {
1565 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop ||
1566 Clause.getDirectiveKind() == OpenACCDirectiveKind::SerialLoop) {
1567 DiagIntArgInvalid(SemaRef, IntExpr, OpenACCGangKind::Num,
1568 OpenACCClauseKind::Worker, Clause.getDirectiveKind(),
1569 SemaRef.getActiveComputeConstructInfo().Kind);
1570 IntExpr = nullptr;
1571 } else {
1572 assert(Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop &&
1573 "Unknown combined directive kind?");
1574 const auto *Itr = llvm::find_if(ExistingClauses,
1575 llvm::IsaPred<OpenACCNumWorkersClause>);
1576 if (Itr != ExistingClauses.end()) {
1577 SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1578 << "num" << OpenACCClauseKind::Worker << Clause.getDirectiveKind()
1579 << HasAssocKind(Clause.getDirectiveKind(),
1580 SemaRef.getActiveComputeConstructInfo().Kind)
1581 << SemaRef.getActiveComputeConstructInfo().Kind
1582 << OpenACCClauseKind::NumWorkers;
1583 SemaRef.Diag((*Itr)->getBeginLoc(),
1584 diag::note_acc_previous_clause_here);
1585
1586 IntExpr = nullptr;
1587 }
1588 }
1589 }
1590 }
1591
1593 // OpenACC 3.3 2.9.3: The region of a loop with a 'worker' clause may not
1594 // contain a loop with a gang or worker clause unless within a nested
1595 // compute region.
1596 if (SemaRef.LoopWorkerClauseLoc.isValid()) {
1597 // This handles the 'inner loop' diagnostic, but we cannot set that we're
1598 // on one of these until we get to the end of the construct.
1599 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1600 << OpenACCClauseKind::Worker << OpenACCClauseKind::Worker
1601 << /*skip kernels construct info*/ 0;
1602 SemaRef.Diag(SemaRef.LoopWorkerClauseLoc,
1603 diag::note_acc_previous_clause_here);
1604 return nullptr;
1605 }
1606
1607 // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1608 // contain a loop with a gang, worker, or vector clause unless within a
1609 // nested compute region.
1610 if (SemaRef.LoopVectorClauseLoc.isValid()) {
1611 // This handles the 'inner loop' diagnostic, but we cannot set that we're
1612 // on one of these until we get to the end of the construct.
1613 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1614 << OpenACCClauseKind::Worker << OpenACCClauseKind::Vector
1615 << /*skip kernels construct info*/ 0;
1616 SemaRef.Diag(SemaRef.LoopVectorClauseLoc,
1617 diag::note_acc_previous_clause_here);
1618 return nullptr;
1619 }
1620 }
1621
1622 return OpenACCWorkerClause::Create(Ctx, Clause.getBeginLoc(),
1623 Clause.getLParenLoc(), IntExpr,
1624 Clause.getEndLoc());
1625}
1626
1627OpenACCClause *SemaOpenACCClauseVisitor::VisitGangClause(
1629 if (DiagIfSeqClause(Clause))
1630 return nullptr;
1631
1632 // Restrictions only properly implemented on 'loop' constructs, and it is
1633 // the only construct that can do anything with this, so skip/treat as
1634 // unimplemented for the combined constructs.
1635 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1636 return isNotImplemented();
1637
1638 // OpenACC 3.3 Section 2.9.11: A reduction clause may not appear on a loop
1639 // directive that has a gang clause and is within a compute construct that has
1640 // a num_gangs clause with more than one explicit argument.
1641 if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop &&
1642 SemaRef.getActiveComputeConstructInfo().Kind !=
1643 OpenACCDirectiveKind::Invalid) ||
1645 // num_gangs clause on the active compute construct.
1646 auto ActiveComputeConstructContainer =
1648 ? ExistingClauses
1649 : SemaRef.getActiveComputeConstructInfo().Clauses;
1650 auto *NumGangsClauseItr = llvm::find_if(
1651 ActiveComputeConstructContainer, llvm::IsaPred<OpenACCNumGangsClause>);
1652
1653 if (NumGangsClauseItr != ActiveComputeConstructContainer.end() &&
1654 cast<OpenACCNumGangsClause>(*NumGangsClauseItr)->getIntExprs().size() >
1655 1) {
1656 auto *ReductionClauseItr =
1657 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>);
1658
1659 if (ReductionClauseItr != ExistingClauses.end()) {
1660 SemaRef.Diag(Clause.getBeginLoc(),
1661 diag::err_acc_gang_reduction_numgangs_conflict)
1662 << OpenACCClauseKind::Gang << OpenACCClauseKind::Reduction
1663 << Clause.getDirectiveKind()
1665 SemaRef.Diag((*ReductionClauseItr)->getBeginLoc(),
1666 diag::note_acc_previous_clause_here);
1667 SemaRef.Diag((*NumGangsClauseItr)->getBeginLoc(),
1668 diag::note_acc_previous_clause_here);
1669 return nullptr;
1670 }
1671 }
1672 }
1673
1676
1677 // Store the existing locations, so we can do duplicate checking. Index is
1678 // the int-value of the OpenACCGangKind enum.
1679 SourceLocation ExistingElemLoc[3];
1680
1681 for (unsigned I = 0; I < Clause.getIntExprs().size(); ++I) {
1682 OpenACCGangKind GK = Clause.getGangKinds()[I];
1683 ExprResult ER =
1684 SemaRef.CheckGangExpr(ExistingClauses, Clause.getDirectiveKind(), GK,
1685 Clause.getIntExprs()[I]);
1686
1687 if (!ER.isUsable())
1688 continue;
1689
1690 // OpenACC 3.3 2.9: 'gang-arg-list' may have at most one num, one dim, and
1691 // one static argument.
1692 if (ExistingElemLoc[static_cast<unsigned>(GK)].isValid()) {
1693 SemaRef.Diag(ER.get()->getBeginLoc(), diag::err_acc_gang_multiple_elt)
1694 << static_cast<unsigned>(GK);
1695 SemaRef.Diag(ExistingElemLoc[static_cast<unsigned>(GK)],
1696 diag::note_acc_previous_expr_here);
1697 continue;
1698 }
1699
1700 ExistingElemLoc[static_cast<unsigned>(GK)] = ER.get()->getBeginLoc();
1701 GangKinds.push_back(GK);
1702 IntExprs.push_back(ER.get());
1703 }
1704
1706 // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
1707 // construct, the gang clause behaves as follows. ... The region of a loop
1708 // with a gang clause may not contain another loop with a gang clause unless
1709 // within a nested compute region.
1710 if (SemaRef.LoopGangClauseOnKernel.Loc.isValid()) {
1711 // This handles the 'inner loop' diagnostic, but we cannot set that we're
1712 // on one of these until we get to the end of the construct.
1713 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1714 << OpenACCClauseKind::Gang << OpenACCClauseKind::Gang
1715 << /*kernels construct info*/ 1
1717 SemaRef.Diag(SemaRef.LoopGangClauseOnKernel.Loc,
1718 diag::note_acc_previous_clause_here);
1719 return nullptr;
1720 }
1721
1722 // OpenACC 3.3 2.9.3: The region of a loop with a 'worker' clause may not
1723 // contain a loop with a gang or worker clause unless within a nested
1724 // compute region.
1725 if (SemaRef.LoopWorkerClauseLoc.isValid()) {
1726 // This handles the 'inner loop' diagnostic, but we cannot set that we're
1727 // on one of these until we get to the end of the construct.
1728 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1729 << OpenACCClauseKind::Gang << OpenACCClauseKind::Worker
1730 << /*!kernels construct info*/ 0;
1731 SemaRef.Diag(SemaRef.LoopWorkerClauseLoc,
1732 diag::note_acc_previous_clause_here);
1733 return nullptr;
1734 }
1735
1736 // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1737 // contain a loop with a gang, worker, or vector clause unless within a
1738 // nested compute region.
1739 if (SemaRef.LoopVectorClauseLoc.isValid()) {
1740 // This handles the 'inner loop' diagnostic, but we cannot set that we're
1741 // on one of these until we get to the end of the construct.
1742 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1743 << OpenACCClauseKind::Gang << OpenACCClauseKind::Vector
1744 << /*!kernels construct info*/ 0;
1745 SemaRef.Diag(SemaRef.LoopVectorClauseLoc,
1746 diag::note_acc_previous_clause_here);
1747 return nullptr;
1748 }
1749 }
1750
1751 return SemaRef.CheckGangClause(Clause.getDirectiveKind(), ExistingClauses,
1752 Clause.getBeginLoc(), Clause.getLParenLoc(),
1753 GangKinds, IntExprs, Clause.getEndLoc());
1754}
1755
1756OpenACCClause *SemaOpenACCClauseVisitor::VisitFinalizeClause(
1758 // There isn't anything to do here, this is only valid on one construct, and
1759 // has no associated rules.
1760 return OpenACCFinalizeClause::Create(Ctx, Clause.getBeginLoc(),
1761 Clause.getEndLoc());
1762}
1763
1764OpenACCClause *SemaOpenACCClauseVisitor::VisitIfPresentClause(
1766 // There isn't anything to do here, this is only valid on one construct, and
1767 // has no associated rules.
1768 return OpenACCIfPresentClause::Create(Ctx, Clause.getBeginLoc(),
1769 Clause.getEndLoc());
1770}
1771
1772OpenACCClause *SemaOpenACCClauseVisitor::VisitSeqClause(
1774 // Restrictions only properly implemented on 'loop' constructs and combined ,
1775 // and it is the only construct that can do anything with this, so skip/treat
1776 // as unimplemented for the routine constructs.
1777 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1778 return isNotImplemented();
1779
1780 // OpenACC 3.3 2.9:
1781 // Only one of the seq, independent, and auto clauses may appear.
1782 const auto *Itr =
1783 llvm::find_if(ExistingClauses,
1784 llvm::IsaPred<OpenACCAutoClause, OpenACCIndependentClause>);
1785 if (Itr != ExistingClauses.end()) {
1786 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict)
1787 << Clause.getClauseKind() << Clause.getDirectiveKind();
1788 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1789 return nullptr;
1790 }
1791
1792 // OpenACC 3.3 2.9:
1793 // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' clause
1794 // appears.
1795 Itr = llvm::find_if(ExistingClauses,
1798
1799 if (Itr != ExistingClauses.end()) {
1800 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine)
1801 << Clause.getClauseKind() << (*Itr)->getClauseKind()
1802 << Clause.getDirectiveKind();
1803 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1804 return nullptr;
1805 }
1806
1807 return OpenACCSeqClause::Create(Ctx, Clause.getBeginLoc(),
1808 Clause.getEndLoc());
1809}
1810
1811OpenACCClause *SemaOpenACCClauseVisitor::VisitReductionClause(
1813 // OpenACC 3.3 Section 2.9.11: A reduction clause may not appear on a loop
1814 // directive that has a gang clause and is within a compute construct that has
1815 // a num_gangs clause with more than one explicit argument.
1816 if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop &&
1817 SemaRef.getActiveComputeConstructInfo().Kind !=
1818 OpenACCDirectiveKind::Invalid) ||
1820 // num_gangs clause on the active compute construct.
1821 auto ActiveComputeConstructContainer =
1823 ? ExistingClauses
1824 : SemaRef.getActiveComputeConstructInfo().Clauses;
1825 auto *NumGangsClauseItr = llvm::find_if(
1826 ActiveComputeConstructContainer, llvm::IsaPred<OpenACCNumGangsClause>);
1827
1828 if (NumGangsClauseItr != ActiveComputeConstructContainer.end() &&
1829 cast<OpenACCNumGangsClause>(*NumGangsClauseItr)->getIntExprs().size() >
1830 1) {
1831 auto *GangClauseItr =
1832 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCGangClause>);
1833
1834 if (GangClauseItr != ExistingClauses.end()) {
1835 SemaRef.Diag(Clause.getBeginLoc(),
1836 diag::err_acc_gang_reduction_numgangs_conflict)
1837 << OpenACCClauseKind::Reduction << OpenACCClauseKind::Gang
1838 << Clause.getDirectiveKind()
1840 SemaRef.Diag((*GangClauseItr)->getBeginLoc(),
1841 diag::note_acc_previous_clause_here);
1842 SemaRef.Diag((*NumGangsClauseItr)->getBeginLoc(),
1843 diag::note_acc_previous_clause_here);
1844 return nullptr;
1845 }
1846 }
1847 }
1848
1849 // OpenACC3.3 Section 2.9.11: If a variable is involved in a reduction that
1850 // spans multiple nested loops where two or more of those loops have
1851 // associated loop directives, a reduction clause containing that variable
1852 // must appear on each of those loop directives.
1853 //
1854 // This can't really be implemented in the CFE, as this requires a level of
1855 // rechability/useage analysis that we're not really wanting to get into.
1856 // Additionally, I'm alerted that this restriction is one that the middle-end
1857 // can just 'figure out' as an extension and isn't really necessary.
1858 //
1859 // OpenACC3.3 Section 2.9.11: Every 'var' in a reduction clause appearing on
1860 // an orphaned loop construct must be private.
1861 //
1862 // This again is something we cannot really diagnose, as it requires we see
1863 // all the uses/scopes of all variables referenced. The middle end/MLIR might
1864 // be able to diagnose this.
1865
1866 // OpenACC 3.3 Section 2.5.4:
1867 // A reduction clause may not appear on a parallel construct with a
1868 // num_gangs clause that has more than one argument.
1869 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel ||
1870 Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop) {
1871 auto NumGangsClauses = llvm::make_filter_range(
1872 ExistingClauses, llvm::IsaPred<OpenACCNumGangsClause>);
1873
1874 for (auto *NGC : NumGangsClauses) {
1875 unsigned NumExprs =
1876 cast<OpenACCNumGangsClause>(NGC)->getIntExprs().size();
1877
1878 if (NumExprs > 1) {
1879 SemaRef.Diag(Clause.getBeginLoc(),
1880 diag::err_acc_reduction_num_gangs_conflict)
1881 << /*>1 arg in first loc=*/0 << Clause.getClauseKind()
1882 << Clause.getDirectiveKind() << OpenACCClauseKind::NumGangs;
1883 SemaRef.Diag(NGC->getBeginLoc(), diag::note_acc_previous_clause_here);
1884 return nullptr;
1885 }
1886 }
1887 }
1888
1889 SmallVector<Expr *> ValidVars;
1890
1891 for (Expr *Var : Clause.getVarList()) {
1892 ExprResult Res = SemaRef.CheckReductionVar(Clause.getDirectiveKind(),
1893 Clause.getReductionOp(), Var);
1894
1895 if (Res.isUsable())
1896 ValidVars.push_back(Res.get());
1897 }
1898
1899 return SemaRef.CheckReductionClause(
1900 ExistingClauses, Clause.getDirectiveKind(), Clause.getBeginLoc(),
1901 Clause.getLParenLoc(), Clause.getReductionOp(), ValidVars,
1902 Clause.getEndLoc());
1903}
1904
1905OpenACCClause *SemaOpenACCClauseVisitor::VisitCollapseClause(
1907 // Duplicates here are not really sensible. We could possible permit
1908 // multiples if they all had the same value, but there isn't really a good
1909 // reason to do so. Also, this simplifies the suppression of duplicates, in
1910 // that we know if we 'find' one after instantiation, that it is the same
1911 // clause, which simplifies instantiation/checking/etc.
1912 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
1913 return nullptr;
1914
1915 ExprResult LoopCount = SemaRef.CheckCollapseLoopCount(Clause.getLoopCount());
1916
1917 if (!LoopCount.isUsable())
1918 return nullptr;
1919
1920 return OpenACCCollapseClause::Create(Ctx, Clause.getBeginLoc(),
1921 Clause.getLParenLoc(), Clause.isForce(),
1922 LoopCount.get(), Clause.getEndLoc());
1923}
1924
1925void CollectActiveReductionClauses(
1927 ArrayRef<OpenACCClause *> CurClauses) {
1928 for (auto *CurClause : CurClauses) {
1929 if (auto *RedClause = dyn_cast<OpenACCReductionClause>(CurClause);
1930 RedClause && !RedClause->getVarList().empty())
1931 ActiveClauses.push_back(RedClause);
1932 }
1933}
1934
1935// Depth needs to be preserved for all associated statements that aren't
1936// supposed to modify the compute/combined/loop construct information.
1937bool PreserveLoopRAIIDepthInAssociatedStmtRAII(OpenACCDirectiveKind DK) {
1938 switch (DK) {
1939 case OpenACCDirectiveKind::Parallel:
1940 case OpenACCDirectiveKind::ParallelLoop:
1941 case OpenACCDirectiveKind::Serial:
1942 case OpenACCDirectiveKind::SerialLoop:
1943 case OpenACCDirectiveKind::Kernels:
1944 case OpenACCDirectiveKind::KernelsLoop:
1945 case OpenACCDirectiveKind::Loop:
1946 return false;
1947 case OpenACCDirectiveKind::Data:
1948 case OpenACCDirectiveKind::HostData:
1949 return true;
1950 case OpenACCDirectiveKind::EnterData:
1951 case OpenACCDirectiveKind::ExitData:
1952 case OpenACCDirectiveKind::Wait:
1953 case OpenACCDirectiveKind::Init:
1954 case OpenACCDirectiveKind::Shutdown:
1955 case OpenACCDirectiveKind::Set:
1956 case OpenACCDirectiveKind::Update:
1957 llvm_unreachable("Doesn't have an associated stmt");
1958 default:
1959 case OpenACCDirectiveKind::Invalid:
1960 llvm_unreachable("Unhandled directive kind?");
1961 }
1962 llvm_unreachable("Unhandled directive kind?");
1963}
1964
1965} // namespace
1966
1968
1971 ArrayRef<const OpenACCClause *> UnInstClauses,
1973 : SemaRef(S), OldActiveComputeConstructInfo(S.ActiveComputeConstructInfo),
1974 DirKind(DK), OldLoopGangClauseOnKernel(S.LoopGangClauseOnKernel),
1975 OldLoopWorkerClauseLoc(S.LoopWorkerClauseLoc),
1976 OldLoopVectorClauseLoc(S.LoopVectorClauseLoc),
1977 OldLoopWithoutSeqInfo(S.LoopWithoutSeqInfo),
1978 ActiveReductionClauses(S.ActiveReductionClauses),
1979 LoopRAII(SemaRef, PreserveLoopRAIIDepthInAssociatedStmtRAII(DirKind)) {
1980
1981 // Compute constructs end up taking their 'loop'.
1982 if (DirKind == OpenACCDirectiveKind::Parallel ||
1983 DirKind == OpenACCDirectiveKind::Serial ||
1984 DirKind == OpenACCDirectiveKind::Kernels) {
1985 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
1986 SemaRef.ActiveComputeConstructInfo.Kind = DirKind;
1987 SemaRef.ActiveComputeConstructInfo.Clauses = Clauses;
1988
1989 // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
1990 // construct, the gang clause behaves as follows. ... The region of a loop
1991 // with a gang clause may not contain another loop with a gang clause unless
1992 // within a nested compute region.
1993 //
1994 // Implement the 'unless within a nested compute region' part.
1995 SemaRef.LoopGangClauseOnKernel = {};
1996 SemaRef.LoopWorkerClauseLoc = {};
1997 SemaRef.LoopVectorClauseLoc = {};
1998 SemaRef.LoopWithoutSeqInfo = {};
1999 } else if (DirKind == OpenACCDirectiveKind::ParallelLoop ||
2002 SemaRef.ActiveComputeConstructInfo.Kind = DirKind;
2003 SemaRef.ActiveComputeConstructInfo.Clauses = Clauses;
2004
2005 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
2006 SetCollapseInfoBeforeAssociatedStmt(UnInstClauses, Clauses);
2007 SetTileInfoBeforeAssociatedStmt(UnInstClauses, Clauses);
2008
2009 SemaRef.LoopGangClauseOnKernel = {};
2010 SemaRef.LoopWorkerClauseLoc = {};
2011 SemaRef.LoopVectorClauseLoc = {};
2012
2013 // Set the active 'loop' location if there isn't a 'seq' on it, so we can
2014 // diagnose the for loops.
2015 SemaRef.LoopWithoutSeqInfo = {};
2016 if (Clauses.end() ==
2017 llvm::find_if(Clauses, llvm::IsaPred<OpenACCSeqClause>))
2018 SemaRef.LoopWithoutSeqInfo = {DirKind, DirLoc};
2019
2020 // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
2021 // construct, the gang clause behaves as follows. ... The region of a loop
2022 // with a gang clause may not contain another loop with a gang clause unless
2023 // within a nested compute region.
2024 //
2025 // We don't bother doing this when this is a template instantiation, as
2026 // there is no reason to do these checks: the existance of a
2027 // gang/kernels/etc cannot be dependent.
2028 if (DirKind == OpenACCDirectiveKind::KernelsLoop && UnInstClauses.empty()) {
2029 // This handles the 'outer loop' part of this.
2030 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCGangClause>);
2031 if (Itr != Clauses.end())
2032 SemaRef.LoopGangClauseOnKernel = {(*Itr)->getBeginLoc(), DirKind};
2033 }
2034
2035 if (UnInstClauses.empty()) {
2036 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCWorkerClause>);
2037 if (Itr != Clauses.end())
2038 SemaRef.LoopWorkerClauseLoc = (*Itr)->getBeginLoc();
2039
2040 auto *Itr2 = llvm::find_if(Clauses, llvm::IsaPred<OpenACCVectorClause>);
2041 if (Itr2 != Clauses.end())
2042 SemaRef.LoopVectorClauseLoc = (*Itr2)->getBeginLoc();
2043 }
2044 } else if (DirKind == OpenACCDirectiveKind::Loop) {
2045 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
2046 SetCollapseInfoBeforeAssociatedStmt(UnInstClauses, Clauses);
2047 SetTileInfoBeforeAssociatedStmt(UnInstClauses, Clauses);
2048
2049 // Set the active 'loop' location if there isn't a 'seq' on it, so we can
2050 // diagnose the for loops.
2051 SemaRef.LoopWithoutSeqInfo = {};
2052 if (Clauses.end() ==
2053 llvm::find_if(Clauses, llvm::IsaPred<OpenACCSeqClause>))
2054 SemaRef.LoopWithoutSeqInfo = {DirKind, DirLoc};
2055
2056 // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
2057 // construct, the gang clause behaves as follows. ... The region of a loop
2058 // with a gang clause may not contain another loop with a gang clause unless
2059 // within a nested compute region.
2060 //
2061 // We don't bother doing this when this is a template instantiation, as
2062 // there is no reason to do these checks: the existance of a
2063 // gang/kernels/etc cannot be dependent.
2064 if (SemaRef.getActiveComputeConstructInfo().Kind ==
2066 UnInstClauses.empty()) {
2067 // This handles the 'outer loop' part of this.
2068 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCGangClause>);
2069 if (Itr != Clauses.end())
2070 SemaRef.LoopGangClauseOnKernel = {(*Itr)->getBeginLoc(),
2072 }
2073
2074 if (UnInstClauses.empty()) {
2075 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCWorkerClause>);
2076 if (Itr != Clauses.end())
2077 SemaRef.LoopWorkerClauseLoc = (*Itr)->getBeginLoc();
2078
2079 auto *Itr2 = llvm::find_if(Clauses, llvm::IsaPred<OpenACCVectorClause>);
2080 if (Itr2 != Clauses.end())
2081 SemaRef.LoopVectorClauseLoc = (*Itr2)->getBeginLoc();
2082 }
2083 }
2084}
2085
2087 ArrayRef<const OpenACCClause *> UnInstClauses,
2088 ArrayRef<OpenACCClause *> Clauses) {
2089
2090 // Reset this checking for loops that aren't covered in a RAII object.
2091 SemaRef.LoopInfo.CurLevelHasLoopAlready = false;
2092 SemaRef.CollapseInfo.CollapseDepthSatisfied = true;
2093 SemaRef.TileInfo.TileDepthSatisfied = true;
2094
2095 // We make sure to take an optional list of uninstantiated clauses, so that
2096 // we can check to make sure we don't 'double diagnose' in the event that
2097 // the value of 'N' was not dependent in a template. We also ensure during
2098 // Sema that there is only 1 collapse on each construct, so we can count on
2099 // the fact that if both find a 'collapse', that they are the same one.
2100 auto *CollapseClauseItr =
2101 llvm::find_if(Clauses, llvm::IsaPred<OpenACCCollapseClause>);
2102 auto *UnInstCollapseClauseItr =
2103 llvm::find_if(UnInstClauses, llvm::IsaPred<OpenACCCollapseClause>);
2104
2105 if (Clauses.end() == CollapseClauseItr)
2106 return;
2107
2108 OpenACCCollapseClause *CollapseClause =
2109 cast<OpenACCCollapseClause>(*CollapseClauseItr);
2110
2111 SemaRef.CollapseInfo.ActiveCollapse = CollapseClause;
2112 Expr *LoopCount = CollapseClause->getLoopCount();
2113
2114 // If the loop count is still instantiation dependent, setting the depth
2115 // counter isn't necessary, so return here.
2116 if (!LoopCount || LoopCount->isInstantiationDependent())
2117 return;
2118
2119 // Suppress diagnostics if we've done a 'transform' where the previous version
2120 // wasn't dependent, meaning we already diagnosed it.
2121 if (UnInstCollapseClauseItr != UnInstClauses.end() &&
2122 !cast<OpenACCCollapseClause>(*UnInstCollapseClauseItr)
2123 ->getLoopCount()
2124 ->isInstantiationDependent())
2125 return;
2126
2127 SemaRef.CollapseInfo.CollapseDepthSatisfied = false;
2128 SemaRef.CollapseInfo.CurCollapseCount =
2129 cast<ConstantExpr>(LoopCount)->getResultAsAPSInt();
2130 SemaRef.CollapseInfo.DirectiveKind = DirKind;
2131}
2132
2134 ArrayRef<const OpenACCClause *> UnInstClauses,
2135 ArrayRef<OpenACCClause *> Clauses) {
2136 // We don't diagnose if this is during instantiation, since the only thing we
2137 // care about is the number of arguments, which we can figure out without
2138 // instantiation, so we don't want to double-diagnose.
2139 if (UnInstClauses.size() > 0)
2140 return;
2141 auto *TileClauseItr =
2142 llvm::find_if(Clauses, llvm::IsaPred<OpenACCTileClause>);
2143
2144 if (Clauses.end() == TileClauseItr)
2145 return;
2146
2147 OpenACCTileClause *TileClause = cast<OpenACCTileClause>(*TileClauseItr);
2148 SemaRef.TileInfo.ActiveTile = TileClause;
2149 SemaRef.TileInfo.TileDepthSatisfied = false;
2150 SemaRef.TileInfo.CurTileCount = TileClause->getSizeExprs().size();
2151 SemaRef.TileInfo.DirectiveKind = DirKind;
2152}
2153
2155 if (DirKind == OpenACCDirectiveKind::Parallel ||
2156 DirKind == OpenACCDirectiveKind::Serial ||
2157 DirKind == OpenACCDirectiveKind::Kernels ||
2158 DirKind == OpenACCDirectiveKind::Loop ||
2162 SemaRef.ActiveComputeConstructInfo = OldActiveComputeConstructInfo;
2163 SemaRef.LoopGangClauseOnKernel = OldLoopGangClauseOnKernel;
2164 SemaRef.LoopWorkerClauseLoc = OldLoopWorkerClauseLoc;
2165 SemaRef.LoopVectorClauseLoc = OldLoopVectorClauseLoc;
2166 SemaRef.LoopWithoutSeqInfo = OldLoopWithoutSeqInfo;
2167 SemaRef.ActiveReductionClauses.swap(ActiveReductionClauses);
2168 } else if (DirKind == OpenACCDirectiveKind::Data ||
2169 DirKind == OpenACCDirectiveKind::HostData) {
2170 // Intentionally doesn't reset the Loop, Compute Construct, or reduction
2171 // effects.
2172 }
2173}
2174
2177 OpenACCParsedClause &Clause) {
2179 return nullptr;
2180
2181 // Diagnose that we don't support this clause on this directive.
2182 if (!doesClauseApplyToDirective(Clause.getDirectiveKind(),
2183 Clause.getClauseKind())) {
2184 Diag(Clause.getBeginLoc(), diag::err_acc_clause_appertainment)
2185 << Clause.getDirectiveKind() << Clause.getClauseKind();
2186 return nullptr;
2187 }
2188
2189 if (const auto *DevTypeClause =
2190 llvm::find_if(ExistingClauses,
2191 [&](const OpenACCClause *C) {
2192 return isa<OpenACCDeviceTypeClause>(C);
2193 });
2194 DevTypeClause != ExistingClauses.end()) {
2195 if (checkValidAfterDeviceType(
2196 *this, *cast<OpenACCDeviceTypeClause>(*DevTypeClause), Clause))
2197 return nullptr;
2198 }
2199
2200 SemaOpenACCClauseVisitor Visitor{*this, ExistingClauses};
2201 OpenACCClause *Result = Visitor.Visit(Clause);
2202 assert((!Result || Result->getClauseKind() == Clause.getClauseKind()) &&
2203 "Created wrong clause?");
2204
2205 if (Visitor.diagNotImplemented())
2206 Diag(Clause.getBeginLoc(), diag::warn_acc_clause_unimplemented)
2207 << Clause.getClauseKind();
2208
2209 return Result;
2210
2211}
2212
2213namespace {
2214// Return true if the two vars refer to the same variable, for the purposes of
2215// equality checking.
2216bool areVarsEqual(Expr *VarExpr1, Expr *VarExpr2) {
2217 if (VarExpr1->isInstantiationDependent() ||
2218 VarExpr2->isInstantiationDependent())
2219 return false;
2220
2221 VarExpr1 = VarExpr1->IgnoreParenCasts();
2222 VarExpr2 = VarExpr2->IgnoreParenCasts();
2223
2224 // Legal expressions can be: Scalar variable reference, sub-array, array
2225 // element, or composite variable member.
2226
2227 // Sub-array.
2228 if (isa<ArraySectionExpr>(VarExpr1)) {
2229 auto *Expr2AS = dyn_cast<ArraySectionExpr>(VarExpr2);
2230 if (!Expr2AS)
2231 return false;
2232
2233 auto *Expr1AS = cast<ArraySectionExpr>(VarExpr1);
2234
2235 if (!areVarsEqual(Expr1AS->getBase(), Expr2AS->getBase()))
2236 return false;
2237 // We could possibly check to see if the ranges aren't overlapping, but it
2238 // isn't clear that the rules allow this.
2239 return true;
2240 }
2241
2242 // Array-element.
2243 if (isa<ArraySubscriptExpr>(VarExpr1)) {
2244 auto *Expr2AS = dyn_cast<ArraySubscriptExpr>(VarExpr2);
2245 if (!Expr2AS)
2246 return false;
2247
2248 auto *Expr1AS = cast<ArraySubscriptExpr>(VarExpr1);
2249
2250 if (!areVarsEqual(Expr1AS->getBase(), Expr2AS->getBase()))
2251 return false;
2252
2253 // We could possibly check to see if the elements referenced aren't the
2254 // same, but it isn't clear by reading of the standard that this is allowed
2255 // (and that the 'var' refered to isn't the array).
2256 return true;
2257 }
2258
2259 // Scalar variable reference, or composite variable.
2260 if (isa<DeclRefExpr>(VarExpr1)) {
2261 auto *Expr2DRE = dyn_cast<DeclRefExpr>(VarExpr2);
2262 if (!Expr2DRE)
2263 return false;
2264
2265 auto *Expr1DRE = cast<DeclRefExpr>(VarExpr1);
2266
2267 return Expr1DRE->getDecl()->getMostRecentDecl() ==
2268 Expr2DRE->getDecl()->getMostRecentDecl();
2269 }
2270
2271 llvm_unreachable("Unknown variable type encountered");
2272}
2273} // namespace
2274
2275/// OpenACC 3.3 section 2.5.15:
2276/// At a mininmum, the supported data types include ... the numerical data types
2277/// in C, C++, and Fortran.
2278///
2279/// If the reduction var is a composite variable, each
2280/// member of the composite variable must be a supported datatype for the
2281/// reduction operation.
2283 OpenACCReductionOperator ReductionOp,
2284 Expr *VarExpr) {
2285 VarExpr = VarExpr->IgnoreParenCasts();
2286
2287 auto TypeIsValid = [](QualType Ty) {
2288 return Ty->isDependentType() || Ty->isScalarType();
2289 };
2290
2291 if (isa<ArraySectionExpr>(VarExpr)) {
2292 Expr *ASExpr = VarExpr;
2294 QualType EltTy = getASTContext().getBaseElementType(BaseTy);
2295
2296 if (!TypeIsValid(EltTy)) {
2297 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_type)
2298 << EltTy << /*Sub array base type*/ 1;
2299 return ExprError();
2300 }
2301 } else if (auto *RD = VarExpr->getType()->getAsRecordDecl()) {
2302 if (!RD->isStruct() && !RD->isClass()) {
2303 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type)
2304 << /*not class or struct*/ 0 << VarExpr->getType();
2305 return ExprError();
2306 }
2307
2308 if (!RD->isCompleteDefinition()) {
2309 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type)
2310 << /*incomplete*/ 1 << VarExpr->getType();
2311 return ExprError();
2312 }
2313 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
2314 CXXRD && !CXXRD->isAggregate()) {
2315 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type)
2316 << /*aggregate*/ 2 << VarExpr->getType();
2317 return ExprError();
2318 }
2319
2320 for (FieldDecl *FD : RD->fields()) {
2321 if (!TypeIsValid(FD->getType())) {
2322 Diag(VarExpr->getExprLoc(),
2323 diag::err_acc_reduction_composite_member_type);
2324 Diag(FD->getLocation(), diag::note_acc_reduction_composite_member_loc);
2325 return ExprError();
2326 }
2327 }
2328 } else if (!TypeIsValid(VarExpr->getType())) {
2329 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_type)
2330 << VarExpr->getType() << /*Sub array base type*/ 0;
2331 return ExprError();
2332 }
2333
2334 // OpenACC3.3: 2.9.11: Reduction clauses on nested constructs for the same
2335 // reduction 'var' must have the same reduction operator.
2336 if (!VarExpr->isInstantiationDependent()) {
2337
2338 for (const OpenACCReductionClause *RClause : ActiveReductionClauses) {
2339 if (RClause->getReductionOp() == ReductionOp)
2340 break;
2341
2342 for (Expr *OldVarExpr : RClause->getVarList()) {
2343 if (OldVarExpr->isInstantiationDependent())
2344 continue;
2345
2346 if (areVarsEqual(VarExpr, OldVarExpr)) {
2347 Diag(VarExpr->getExprLoc(), diag::err_reduction_op_mismatch)
2348 << ReductionOp << RClause->getReductionOp();
2349 Diag(OldVarExpr->getExprLoc(), diag::note_acc_previous_clause_here);
2350 return ExprError();
2351 }
2352 }
2353 }
2354 }
2355
2356 return VarExpr;
2357}
2358
2360 SourceLocation DirLoc) {
2361 // Start an evaluation context to parse the clause arguments on.
2364
2365 switch (K) {
2367 // Nothing to do here, an invalid kind has nothing we can check here. We
2368 // want to continue parsing clauses as far as we can, so we will just
2369 // ensure that we can still work and don't check any construct-specific
2370 // rules anywhere.
2371 break;
2387 // Nothing to do here, there is no real legalization that needs to happen
2388 // here as these constructs do not take any arguments.
2389 break;
2391 // Nothing really to do here, the arguments to the 'wait' should have
2392 // already been handled by the time we get here.
2393 break;
2394 default:
2395 Diag(DirLoc, diag::warn_acc_construct_unimplemented) << K;
2396 break;
2397 }
2398}
2399
2402 Expr *IntExpr) {
2403
2404 assert(((DK != OpenACCDirectiveKind::Invalid &&
2410 "Only one of directive or clause kind should be provided");
2411
2412 class IntExprConverter : public Sema::ICEConvertDiagnoser {
2413 OpenACCDirectiveKind DirectiveKind;
2414 OpenACCClauseKind ClauseKind;
2415 Expr *IntExpr;
2416
2417 // gets the index into the diagnostics so we can use this for clauses,
2418 // directives, and sub array.s
2419 unsigned getDiagKind() const {
2420 if (ClauseKind != OpenACCClauseKind::Invalid)
2421 return 0;
2422 if (DirectiveKind != OpenACCDirectiveKind::Invalid)
2423 return 1;
2424 return 2;
2425 }
2426
2427 public:
2428 IntExprConverter(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
2429 Expr *IntExpr)
2430 : ICEConvertDiagnoser(/*AllowScopedEnumerations=*/false,
2431 /*Suppress=*/false,
2432 /*SuppressConversion=*/true),
2433 DirectiveKind(DK), ClauseKind(CK), IntExpr(IntExpr) {}
2434
2435 bool match(QualType T) override {
2436 // OpenACC spec just calls this 'integer expression' as having an
2437 // 'integer type', so fall back on C99's 'integer type'.
2438 return T->isIntegerType();
2439 }
2441 QualType T) override {
2442 return S.Diag(Loc, diag::err_acc_int_expr_requires_integer)
2443 << getDiagKind() << ClauseKind << DirectiveKind << T;
2444 }
2445
2447 diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) override {
2448 return S.Diag(Loc, diag::err_acc_int_expr_incomplete_class_type)
2449 << T << IntExpr->getSourceRange();
2450 }
2451
2453 diagnoseExplicitConv(Sema &S, SourceLocation Loc, QualType T,
2454 QualType ConvTy) override {
2455 return S.Diag(Loc, diag::err_acc_int_expr_explicit_conversion)
2456 << T << ConvTy;
2457 }
2458
2459 SemaBase::SemaDiagnosticBuilder noteExplicitConv(Sema &S,
2460 CXXConversionDecl *Conv,
2461 QualType ConvTy) override {
2462 return S.Diag(Conv->getLocation(), diag::note_acc_int_expr_conversion)
2463 << ConvTy->isEnumeralType() << ConvTy;
2464 }
2465
2467 diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) override {
2468 return S.Diag(Loc, diag::err_acc_int_expr_multiple_conversions) << T;
2469 }
2470
2472 noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
2473 return S.Diag(Conv->getLocation(), diag::note_acc_int_expr_conversion)
2474 << ConvTy->isEnumeralType() << ConvTy;
2475 }
2476
2478 diagnoseConversion(Sema &S, SourceLocation Loc, QualType T,
2479 QualType ConvTy) override {
2480 llvm_unreachable("conversion functions are permitted");
2481 }
2482 } IntExprDiagnoser(DK, CK, IntExpr);
2483
2484 if (!IntExpr)
2485 return ExprError();
2486
2488 Loc, IntExpr, IntExprDiagnoser);
2489 if (IntExprResult.isInvalid())
2490 return ExprError();
2491
2492 IntExpr = IntExprResult.get();
2493 if (!IntExpr->isTypeDependent() && !IntExpr->getType()->isIntegerType())
2494 return ExprError();
2495
2496 // TODO OpenACC: Do we want to perform usual unary conversions here? When
2497 // doing codegen we might find that is necessary, but skip it for now.
2498 return IntExpr;
2499}
2500
2502 Expr *VarExpr) {
2503 // We already know that VarExpr is a proper reference to a variable, so we
2504 // should be able to just take the type of the expression to get the type of
2505 // the referenced variable.
2506
2507 // We've already seen an error, don't diagnose anything else.
2508 if (!VarExpr || VarExpr->containsErrors())
2509 return false;
2510
2511 if (isa<ArraySectionExpr>(VarExpr->IgnoreParenImpCasts()) ||
2512 VarExpr->hasPlaceholderType(BuiltinType::ArraySection)) {
2513 Diag(VarExpr->getExprLoc(), diag::err_array_section_use) << /*OpenACC=*/0;
2514 Diag(VarExpr->getExprLoc(), diag::note_acc_expected_pointer_var);
2515 return true;
2516 }
2517
2518 QualType Ty = VarExpr->getType();
2520
2521 // Nothing we can do if this is a dependent type.
2522 if (Ty->isDependentType())
2523 return false;
2524
2525 if (!Ty->isPointerType())
2526 return Diag(VarExpr->getExprLoc(), diag::err_acc_var_not_pointer_type)
2527 << ClauseKind << Ty;
2528 return false;
2529}
2530
2532 Expr *CurVarExpr = VarExpr->IgnoreParenImpCasts();
2533
2534 // 'use_device' doesn't allow array subscript or array sections.
2535 // OpenACC3.3 2.8:
2536 // A 'var' in a 'use_device' clause must be the name of a variable or array.
2537 if (CK == OpenACCClauseKind::UseDevice &&
2538 isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
2539 Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref_use_device);
2540 return ExprError();
2541 }
2542
2543 // Sub-arrays/subscript-exprs are fine as long as the base is a
2544 // VarExpr/MemberExpr. So strip all of those off.
2545 while (isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
2546 if (auto *SubScrpt = dyn_cast<ArraySubscriptExpr>(CurVarExpr))
2547 CurVarExpr = SubScrpt->getBase()->IgnoreParenImpCasts();
2548 else
2549 CurVarExpr =
2550 cast<ArraySectionExpr>(CurVarExpr)->getBase()->IgnoreParenImpCasts();
2551 }
2552
2553 // References to a VarDecl are fine.
2554 if (const auto *DRE = dyn_cast<DeclRefExpr>(CurVarExpr)) {
2555 if (isa<VarDecl, NonTypeTemplateParmDecl>(
2556 DRE->getFoundDecl()->getCanonicalDecl()))
2557 return VarExpr;
2558 }
2559
2560 // If CK is a Reduction, this special cases for OpenACC3.3 2.5.15: "A var in a
2561 // reduction clause must be a scalar variable name, an aggregate variable
2562 // name, an array element, or a subarray.
2563 // If CK is a 'use_device', this also isn't valid, as it isn' the name of a
2564 // variable or array.
2565 // A MemberExpr that references a Field is valid for other clauses.
2566 if (CK != OpenACCClauseKind::Reduction &&
2568 if (const auto *ME = dyn_cast<MemberExpr>(CurVarExpr)) {
2569 if (isa<FieldDecl>(ME->getMemberDecl()->getCanonicalDecl()))
2570 return VarExpr;
2571 }
2572 }
2573
2574 // Referring to 'this' is ok for the most part, but for 'use_device' doesn't
2575 // fall into 'variable or array name'
2576 if (CK != OpenACCClauseKind::UseDevice && isa<CXXThisExpr>(CurVarExpr))
2577 return VarExpr;
2578
2579 // Nothing really we can do here, as these are dependent. So just return they
2580 // are valid.
2581 if (isa<DependentScopeDeclRefExpr>(CurVarExpr) ||
2583 isa<CXXDependentScopeMemberExpr>(CurVarExpr)))
2584 return VarExpr;
2585
2586 // There isn't really anything we can do in the case of a recovery expr, so
2587 // skip the diagnostic rather than produce a confusing diagnostic.
2588 if (isa<RecoveryExpr>(CurVarExpr))
2589 return ExprError();
2590
2592 Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref_use_device);
2593 else
2594 Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref)
2596 return ExprError();
2597}
2598
2600 Expr *LowerBound,
2601 SourceLocation ColonLoc,
2602 Expr *Length,
2603 SourceLocation RBLoc) {
2604 ASTContext &Context = getASTContext();
2605
2606 // Handle placeholders.
2607 if (Base->hasPlaceholderType() &&
2608 !Base->hasPlaceholderType(BuiltinType::ArraySection)) {
2610 if (Result.isInvalid())
2611 return ExprError();
2612 Base = Result.get();
2613 }
2614 if (LowerBound && LowerBound->getType()->isNonOverloadPlaceholderType()) {
2616 if (Result.isInvalid())
2617 return ExprError();
2619 if (Result.isInvalid())
2620 return ExprError();
2621 LowerBound = Result.get();
2622 }
2623 if (Length && Length->getType()->isNonOverloadPlaceholderType()) {
2625 if (Result.isInvalid())
2626 return ExprError();
2628 if (Result.isInvalid())
2629 return ExprError();
2630 Length = Result.get();
2631 }
2632
2633 // Check the 'base' value, it must be an array or pointer type, and not to/of
2634 // a function type.
2636 QualType ResultTy;
2637 if (!Base->isTypeDependent()) {
2638 if (OriginalBaseTy->isAnyPointerType()) {
2639 ResultTy = OriginalBaseTy->getPointeeType();
2640 } else if (OriginalBaseTy->isArrayType()) {
2641 ResultTy = OriginalBaseTy->getAsArrayTypeUnsafe()->getElementType();
2642 } else {
2643 return ExprError(
2644 Diag(Base->getExprLoc(), diag::err_acc_typecheck_subarray_value)
2645 << Base->getSourceRange());
2646 }
2647
2648 if (ResultTy->isFunctionType()) {
2649 Diag(Base->getExprLoc(), diag::err_acc_subarray_function_type)
2650 << ResultTy << Base->getSourceRange();
2651 return ExprError();
2652 }
2653
2654 if (SemaRef.RequireCompleteType(Base->getExprLoc(), ResultTy,
2655 diag::err_acc_subarray_incomplete_type,
2656 Base))
2657 return ExprError();
2658
2659 if (!Base->hasPlaceholderType(BuiltinType::ArraySection)) {
2661 if (Result.isInvalid())
2662 return ExprError();
2663 Base = Result.get();
2664 }
2665 }
2666
2667 auto GetRecovery = [&](Expr *E, QualType Ty) {
2668 ExprResult Recovery =
2670 return Recovery.isUsable() ? Recovery.get() : nullptr;
2671 };
2672
2673 // Ensure both of the expressions are int-exprs.
2674 if (LowerBound && !LowerBound->isTypeDependent()) {
2675 ExprResult LBRes =
2677 LowerBound->getExprLoc(), LowerBound);
2678
2679 if (LBRes.isUsable())
2680 LBRes = SemaRef.DefaultLvalueConversion(LBRes.get());
2681 LowerBound =
2682 LBRes.isUsable() ? LBRes.get() : GetRecovery(LowerBound, Context.IntTy);
2683 }
2684
2685 if (Length && !Length->isTypeDependent()) {
2686 ExprResult LenRes =
2688 Length->getExprLoc(), Length);
2689
2690 if (LenRes.isUsable())
2691 LenRes = SemaRef.DefaultLvalueConversion(LenRes.get());
2692 Length =
2693 LenRes.isUsable() ? LenRes.get() : GetRecovery(Length, Context.IntTy);
2694 }
2695
2696 // Length is required if the base type is not an array of known bounds.
2697 if (!Length && (OriginalBaseTy.isNull() ||
2698 (!OriginalBaseTy->isDependentType() &&
2699 !OriginalBaseTy->isConstantArrayType() &&
2700 !OriginalBaseTy->isDependentSizedArrayType()))) {
2701 bool IsArray = !OriginalBaseTy.isNull() && OriginalBaseTy->isArrayType();
2702 Diag(ColonLoc, diag::err_acc_subarray_no_length) << IsArray;
2703 // Fill in a dummy 'length' so that when we instantiate this we don't
2704 // double-diagnose here.
2706 ColonLoc, SourceLocation(), ArrayRef<Expr *>(), Context.IntTy);
2707 Length = Recovery.isUsable() ? Recovery.get() : nullptr;
2708 }
2709
2710 // Check the values of each of the arguments, they cannot be negative(we
2711 // assume), and if the array bound is known, must be within range. As we do
2712 // so, do our best to continue with evaluation, we can set the
2713 // value/expression to nullptr/nullopt if they are invalid, and treat them as
2714 // not present for the rest of evaluation.
2715
2716 // We don't have to check for dependence, because the dependent size is
2717 // represented as a different AST node.
2718 std::optional<llvm::APSInt> BaseSize;
2719 if (!OriginalBaseTy.isNull() && OriginalBaseTy->isConstantArrayType()) {
2720 const auto *ArrayTy = Context.getAsConstantArrayType(OriginalBaseTy);
2721 BaseSize = ArrayTy->getSize();
2722 }
2723
2724 auto GetBoundValue = [&](Expr *E) -> std::optional<llvm::APSInt> {
2725 if (!E || E->isInstantiationDependent())
2726 return std::nullopt;
2727
2728 Expr::EvalResult Res;
2729 if (!E->EvaluateAsInt(Res, Context))
2730 return std::nullopt;
2731 return Res.Val.getInt();
2732 };
2733
2734 std::optional<llvm::APSInt> LowerBoundValue = GetBoundValue(LowerBound);
2735 std::optional<llvm::APSInt> LengthValue = GetBoundValue(Length);
2736
2737 // Check lower bound for negative or out of range.
2738 if (LowerBoundValue.has_value()) {
2739 if (LowerBoundValue->isNegative()) {
2740 Diag(LowerBound->getExprLoc(), diag::err_acc_subarray_negative)
2741 << /*LowerBound=*/0 << toString(*LowerBoundValue, /*Radix=*/10);
2742 LowerBoundValue.reset();
2743 LowerBound = GetRecovery(LowerBound, LowerBound->getType());
2744 } else if (BaseSize.has_value() &&
2745 llvm::APSInt::compareValues(*LowerBoundValue, *BaseSize) >= 0) {
2746 // Lower bound (start index) must be less than the size of the array.
2747 Diag(LowerBound->getExprLoc(), diag::err_acc_subarray_out_of_range)
2748 << /*LowerBound=*/0 << toString(*LowerBoundValue, /*Radix=*/10)
2749 << toString(*BaseSize, /*Radix=*/10);
2750 LowerBoundValue.reset();
2751 LowerBound = GetRecovery(LowerBound, LowerBound->getType());
2752 }
2753 }
2754
2755 // Check length for negative or out of range.
2756 if (LengthValue.has_value()) {
2757 if (LengthValue->isNegative()) {
2758 Diag(Length->getExprLoc(), diag::err_acc_subarray_negative)
2759 << /*Length=*/1 << toString(*LengthValue, /*Radix=*/10);
2760 LengthValue.reset();
2761 Length = GetRecovery(Length, Length->getType());
2762 } else if (BaseSize.has_value() &&
2763 llvm::APSInt::compareValues(*LengthValue, *BaseSize) > 0) {
2764 // Length must be lessthan or EQUAL to the size of the array.
2765 Diag(Length->getExprLoc(), diag::err_acc_subarray_out_of_range)
2766 << /*Length=*/1 << toString(*LengthValue, /*Radix=*/10)
2767 << toString(*BaseSize, /*Radix=*/10);
2768 LengthValue.reset();
2769 Length = GetRecovery(Length, Length->getType());
2770 }
2771 }
2772
2773 // Adding two APSInts requires matching sign, so extract that here.
2774 auto AddAPSInt = [](llvm::APSInt LHS, llvm::APSInt RHS) -> llvm::APSInt {
2775 if (LHS.isSigned() == RHS.isSigned())
2776 return LHS + RHS;
2777
2778 unsigned Width = std::max(LHS.getBitWidth(), RHS.getBitWidth()) + 1;
2779 return llvm::APSInt(LHS.sext(Width) + RHS.sext(Width), /*Signed=*/true);
2780 };
2781
2782 // If we know all 3 values, we can diagnose that the total value would be out
2783 // of range.
2784 if (BaseSize.has_value() && LowerBoundValue.has_value() &&
2785 LengthValue.has_value() &&
2786 llvm::APSInt::compareValues(AddAPSInt(*LowerBoundValue, *LengthValue),
2787 *BaseSize) > 0) {
2788 Diag(Base->getExprLoc(),
2789 diag::err_acc_subarray_base_plus_length_out_of_range)
2790 << toString(*LowerBoundValue, /*Radix=*/10)
2791 << toString(*LengthValue, /*Radix=*/10)
2792 << toString(*BaseSize, /*Radix=*/10);
2793
2794 LowerBoundValue.reset();
2795 LowerBound = GetRecovery(LowerBound, LowerBound->getType());
2796 LengthValue.reset();
2797 Length = GetRecovery(Length, Length->getType());
2798 }
2799
2800 // If any part of the expression is dependent, return a dependent sub-array.
2801 QualType ArrayExprTy = Context.ArraySectionTy;
2802 if (Base->isTypeDependent() ||
2803 (LowerBound && LowerBound->isInstantiationDependent()) ||
2804 (Length && Length->isInstantiationDependent()))
2805 ArrayExprTy = Context.DependentTy;
2806
2807 return new (Context)
2808 ArraySectionExpr(Base, LowerBound, Length, ArrayExprTy, VK_LValue,
2809 OK_Ordinary, ColonLoc, RBLoc);
2810}
2811
2813 if (!LoopCount)
2814 return ExprError();
2815
2816 assert((LoopCount->isInstantiationDependent() ||
2817 LoopCount->getType()->isIntegerType()) &&
2818 "Loop argument non integer?");
2819
2820 // If this is dependent, there really isn't anything we can check.
2821 if (LoopCount->isInstantiationDependent())
2822 return ExprResult{LoopCount};
2823
2824 std::optional<llvm::APSInt> ICE =
2826
2827 // OpenACC 3.3: 2.9.1
2828 // The argument to the collapse clause must be a constant positive integer
2829 // expression.
2830 if (!ICE || *ICE <= 0) {
2831 Diag(LoopCount->getBeginLoc(), diag::err_acc_collapse_loop_count)
2832 << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue();
2833 return ExprError();
2834 }
2835
2836 return ExprResult{
2837 ConstantExpr::Create(getASTContext(), LoopCount, APValue{*ICE})};
2838}
2839
2843 Expr *E) {
2844 // There are two cases for the enforcement here: the 'current' directive is a
2845 // 'loop', where we need to check the active compute construct kind, or the
2846 // current directive is a 'combined' construct, where we have to check the
2847 // current one.
2848 switch (DK) {
2850 return CheckGangParallelExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK,
2851 E);
2853 return CheckGangSerialExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK,
2854 E);
2856 return CheckGangKernelsExpr(*this, ExistingClauses, DK,
2857 ActiveComputeConstructInfo.Kind, GK, E);
2859 switch (ActiveComputeConstructInfo.Kind) {
2863 return CheckGangParallelExpr(*this, DK, ActiveComputeConstructInfo.Kind,
2864 GK, E);
2867 return CheckGangSerialExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK,
2868 E);
2871 return CheckGangKernelsExpr(*this, ExistingClauses, DK,
2872 ActiveComputeConstructInfo.Kind, GK, E);
2873 default:
2874 llvm_unreachable("Non compute construct in active compute construct?");
2875 }
2876 default:
2877 // TODO: OpenACC: when we implement this on 'routine', we'll have to
2878 // implement its checking here.
2879 llvm_unreachable("Invalid directive kind for a Gang clause");
2880 }
2881 llvm_unreachable("Compute construct directive not handled?");
2882}
2883
2886 ArrayRef<const OpenACCClause *> ExistingClauses,
2887 SourceLocation BeginLoc, SourceLocation LParenLoc,
2888 ArrayRef<OpenACCGangKind> GangKinds,
2889 ArrayRef<Expr *> IntExprs, SourceLocation EndLoc) {
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 than 1.
2892
2893 const auto *ReductionItr =
2894 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>);
2895
2896 if (ReductionItr != ExistingClauses.end()) {
2897 const auto GangZip = llvm::zip_equal(GangKinds, IntExprs);
2898 const auto GangItr = llvm::find_if(GangZip, [](const auto &Tuple) {
2899 return std::get<0>(Tuple) == OpenACCGangKind::Dim;
2900 });
2901
2902 if (GangItr != GangZip.end()) {
2903 const Expr *DimExpr = std::get<1>(*GangItr);
2904
2905 assert(
2906 (DimExpr->isInstantiationDependent() || isa<ConstantExpr>(DimExpr)) &&
2907 "Improperly formed gang argument");
2908 if (const auto *DimVal = dyn_cast<ConstantExpr>(DimExpr);
2909 DimVal && DimVal->getResultAsAPSInt() > 1) {
2910 Diag(DimVal->getBeginLoc(), diag::err_acc_gang_reduction_conflict)
2911 << /*gang/reduction=*/0 << DirKind;
2912 Diag((*ReductionItr)->getBeginLoc(),
2913 diag::note_acc_previous_clause_here);
2914 return nullptr;
2915 }
2916 }
2917 }
2918
2919 return OpenACCGangClause::Create(getASTContext(), BeginLoc, LParenLoc,
2920 GangKinds, IntExprs, EndLoc);
2921}
2922
2924 ArrayRef<const OpenACCClause *> ExistingClauses,
2925 OpenACCDirectiveKind DirectiveKind, SourceLocation BeginLoc,
2926 SourceLocation LParenLoc, OpenACCReductionOperator ReductionOp,
2927 ArrayRef<Expr *> Vars, SourceLocation EndLoc) {
2928 if (DirectiveKind == OpenACCDirectiveKind::Loop ||
2929 isOpenACCCombinedDirectiveKind(DirectiveKind)) {
2930 // OpenACC 3.3 2.9.11: A reduction clause may not appear on a loop directive
2931 // that has a gang clause with a dim: argument whose value is greater
2932 // than 1.
2933 const auto GangClauses = llvm::make_filter_range(
2934 ExistingClauses, llvm::IsaPred<OpenACCGangClause>);
2935
2936 for (auto *GC : GangClauses) {
2937 const auto *GangClause = cast<OpenACCGangClause>(GC);
2938 for (unsigned I = 0; I < GangClause->getNumExprs(); ++I) {
2939 std::pair<OpenACCGangKind, const Expr *> EPair = GangClause->getExpr(I);
2940 if (EPair.first != OpenACCGangKind::Dim)
2941 continue;
2942
2943 if (const auto *DimVal = dyn_cast<ConstantExpr>(EPair.second);
2944 DimVal && DimVal->getResultAsAPSInt() > 1) {
2945 Diag(BeginLoc, diag::err_acc_gang_reduction_conflict)
2946 << /*reduction/gang=*/1 << DirectiveKind;
2947 Diag(GangClause->getBeginLoc(), diag::note_acc_previous_clause_here);
2948 return nullptr;
2949 }
2950 }
2951 }
2952 }
2953
2955 getASTContext(), BeginLoc, LParenLoc, ReductionOp, Vars, EndLoc);
2956 return Ret;
2957}
2958
2960 if (!SizeExpr)
2961 return ExprError();
2962
2963 assert((SizeExpr->isInstantiationDependent() ||
2964 SizeExpr->getType()->isIntegerType()) &&
2965 "size argument non integer?");
2966
2967 // If dependent, or an asterisk, the expression is fine.
2968 if (SizeExpr->isInstantiationDependent() ||
2969 isa<OpenACCAsteriskSizeExpr>(SizeExpr))
2970 return ExprResult{SizeExpr};
2971
2972 std::optional<llvm::APSInt> ICE =
2974
2975 // OpenACC 3.3 2.9.8
2976 // where each tile size is a constant positive integer expression or asterisk.
2977 if (!ICE || *ICE <= 0) {
2978 Diag(SizeExpr->getBeginLoc(), diag::err_acc_size_expr_value)
2979 << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue();
2980 return ExprError();
2981 }
2982
2983 return ExprResult{
2984 ConstantExpr::Create(getASTContext(), SizeExpr, APValue{*ICE})};
2985}
2986
2988 if (!getLangOpts().OpenACC)
2989 return;
2990
2991 if (!LoopInfo.TopLevelLoopSeen)
2992 return;
2993
2994 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
2995 Diag(WhileLoc, diag::err_acc_invalid_in_loop)
2996 << /*while loop*/ 1 << CollapseInfo.DirectiveKind
2998 assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");
2999 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
3000 diag::note_acc_active_clause_here)
3002
3003 // Remove the value so that we don't get cascading errors in the body. The
3004 // caller RAII object will restore this.
3005 CollapseInfo.CurCollapseCount = std::nullopt;
3006 }
3007
3008 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
3009 Diag(WhileLoc, diag::err_acc_invalid_in_loop)
3010 << /*while loop*/ 1 << TileInfo.DirectiveKind
3012 assert(TileInfo.ActiveTile && "tile count without object?");
3013 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
3015
3016 // Remove the value so that we don't get cascading errors in the body. The
3017 // caller RAII object will restore this.
3018 TileInfo.CurTileCount = std::nullopt;
3019 }
3020}
3021
3023 if (!getLangOpts().OpenACC)
3024 return;
3025
3026 if (!LoopInfo.TopLevelLoopSeen)
3027 return;
3028
3029 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
3030 Diag(DoLoc, diag::err_acc_invalid_in_loop)
3031 << /*do loop*/ 2 << CollapseInfo.DirectiveKind
3033 assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");
3034 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
3035 diag::note_acc_active_clause_here)
3037
3038 // Remove the value so that we don't get cascading errors in the body. The
3039 // caller RAII object will restore this.
3040 CollapseInfo.CurCollapseCount = std::nullopt;
3041 }
3042
3043 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
3044 Diag(DoLoc, diag::err_acc_invalid_in_loop)
3045 << /*do loop*/ 2 << TileInfo.DirectiveKind << OpenACCClauseKind::Tile;
3046 assert(TileInfo.ActiveTile && "tile count without object?");
3047 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
3049
3050 // Remove the value so that we don't get cascading errors in the body. The
3051 // caller RAII object will restore this.
3052 TileInfo.CurTileCount = std::nullopt;
3053 }
3054}
3055
3056void SemaOpenACC::ForStmtBeginHelper(SourceLocation ForLoc,
3057 ForStmtBeginChecker &C) {
3058 assert(getLangOpts().OpenACC && "Check enabled when not OpenACC?");
3059
3060 // Enable the while/do-while checking.
3061 LoopInfo.TopLevelLoopSeen = true;
3062
3063 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
3064 C.check();
3065
3066 // OpenACC 3.3 2.9.1:
3067 // Each associated loop, except the innermost, must contain exactly one loop
3068 // or loop nest.
3069 // This checks for more than 1 loop at the current level, the
3070 // 'depth'-satisifed checking manages the 'not zero' case.
3071 if (LoopInfo.CurLevelHasLoopAlready) {
3072 Diag(ForLoc, diag::err_acc_clause_multiple_loops)
3073 << CollapseInfo.DirectiveKind << OpenACCClauseKind::Collapse;
3074 assert(CollapseInfo.ActiveCollapse && "No collapse object?");
3075 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
3076 diag::note_acc_active_clause_here)
3078 } else {
3079 --(*CollapseInfo.CurCollapseCount);
3080
3081 // Once we've hit zero here, we know we have deep enough 'for' loops to
3082 // get to the bottom.
3083 if (*CollapseInfo.CurCollapseCount == 0)
3084 CollapseInfo.CollapseDepthSatisfied = true;
3085 }
3086 }
3087
3088 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
3089 C.check();
3090
3091 if (LoopInfo.CurLevelHasLoopAlready) {
3092 Diag(ForLoc, diag::err_acc_clause_multiple_loops)
3093 << TileInfo.DirectiveKind << OpenACCClauseKind::Tile;
3094 assert(TileInfo.ActiveTile && "No tile object?");
3095 Diag(TileInfo.ActiveTile->getBeginLoc(),
3096 diag::note_acc_active_clause_here)
3098 } else {
3099 --(*TileInfo.CurTileCount);
3100 // Once we've hit zero here, we know we have deep enough 'for' loops to
3101 // get to the bottom.
3102 if (*TileInfo.CurTileCount == 0)
3103 TileInfo.TileDepthSatisfied = true;
3104 }
3105 }
3106
3107 // Set this to 'false' for the body of this loop, so that the next level
3108 // checks independently.
3109 LoopInfo.CurLevelHasLoopAlready = false;
3110}
3111
3112namespace {
3113bool isValidLoopVariableType(QualType LoopVarTy) {
3114 // Just skip if it is dependent, it could be any of the below.
3115 if (LoopVarTy->isDependentType())
3116 return true;
3117
3118 // The loop variable must be of integer,
3119 if (LoopVarTy->isIntegerType())
3120 return true;
3121
3122 // C/C++ pointer,
3123 if (LoopVarTy->isPointerType())
3124 return true;
3125
3126 // or C++ random-access iterator type.
3127 if (const auto *RD = LoopVarTy->getAsCXXRecordDecl()) {
3128 // Note: Only do CXXRecordDecl because RecordDecl can't be a random access
3129 // iterator type!
3130
3131 // We could either do a lot of work to see if this matches
3132 // random-access-iterator, but it seems that just checking that the
3133 // 'iterator_category' typedef is more than sufficient. If programmers are
3134 // willing to lie about this, we can let them.
3135
3136 for (const auto *TD :
3137 llvm::make_filter_range(RD->decls(), llvm::IsaPred<TypedefNameDecl>)) {
3138 const auto *TDND = cast<TypedefNameDecl>(TD)->getCanonicalDecl();
3139
3140 if (TDND->getName() != "iterator_category")
3141 continue;
3142
3143 // If there is no type for this decl, return false.
3144 if (TDND->getUnderlyingType().isNull())
3145 return false;
3146
3147 const CXXRecordDecl *ItrCategoryDecl =
3148 TDND->getUnderlyingType()->getAsCXXRecordDecl();
3149
3150 // If the category isn't a record decl, it isn't the tag type.
3151 if (!ItrCategoryDecl)
3152 return false;
3153
3154 auto IsRandomAccessIteratorTag = [](const CXXRecordDecl *RD) {
3155 if (RD->getName() != "random_access_iterator_tag")
3156 return false;
3157 // Checks just for std::random_access_iterator_tag.
3159 };
3160
3161 if (IsRandomAccessIteratorTag(ItrCategoryDecl))
3162 return true;
3163
3164 // We can also support types inherited from the
3165 // random_access_iterator_tag.
3166 for (CXXBaseSpecifier BS : ItrCategoryDecl->bases()) {
3167
3168 if (IsRandomAccessIteratorTag(BS.getType()->getAsCXXRecordDecl()))
3169 return true;
3170 }
3171
3172 return false;
3173 }
3174 }
3175
3176 return false;
3177}
3178
3179} // namespace
3180
3181void SemaOpenACC::ForStmtBeginChecker::check() {
3182 if (SemaRef.LoopWithoutSeqInfo.Kind == OpenACCDirectiveKind::Invalid)
3183 return;
3184
3185 if (AlreadyChecked)
3186 return;
3187 AlreadyChecked = true;
3188
3189 // OpenACC3.3 2.1:
3190 // A loop associated with a loop construct that does not have a seq clause
3191 // must be written to meet all the following conditions:
3192 // - The loop variable must be of integer, C/C++ pointer, or C++ random-access
3193 // iterator type.
3194 // - The loop variable must monotonically increase or decrease in the
3195 // direction of its termination condition.
3196 // - The loop trip count must be computable in constant time when entering the
3197 // loop construct.
3198 //
3199 // For a C++ range-based for loop, the loop variable
3200 // identified by the above conditions is the internal iterator, such as a
3201 // pointer, that the compiler generates to iterate the range. it is not the
3202 // variable declared by the for loop.
3203
3204 if (IsRangeFor) {
3205 // If the range-for is being instantiated and didn't change, don't
3206 // re-diagnose.
3207 if (!RangeFor.has_value())
3208 return;
3209 // For a range-for, we can assume everything is 'corect' other than the type
3210 // of the iterator, so check that.
3211 const DeclStmt *RangeStmt = (*RangeFor)->getBeginStmt();
3212
3213 // In some dependent contexts, the autogenerated range statement doesn't get
3214 // included until instantiation, so skip for now.
3215 if (!RangeStmt)
3216 return;
3217
3218 const ValueDecl *InitVar = cast<ValueDecl>(RangeStmt->getSingleDecl());
3219 QualType VarType = InitVar->getType().getNonReferenceType();
3220 if (!isValidLoopVariableType(VarType)) {
3221 SemaRef.Diag(InitVar->getBeginLoc(), diag::err_acc_loop_variable_type)
3222 << SemaRef.LoopWithoutSeqInfo.Kind << VarType;
3223 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc,
3224 diag::note_acc_construct_here)
3225 << SemaRef.LoopWithoutSeqInfo.Kind;
3226 }
3227 return;
3228 }
3229
3230 // Else we are in normal 'ForStmt', so we can diagnose everything.
3231 // We only have to check cond/inc if they have changed, but 'init' needs to
3232 // just suppress its diagnostics if it hasn't changed.
3233 const ValueDecl *InitVar = checkInit();
3234 if (Cond.has_value())
3235 checkCond();
3236 if (Inc.has_value())
3237 checkInc(InitVar);
3238}
3239const ValueDecl *SemaOpenACC::ForStmtBeginChecker::checkInit() {
3240 if (!Init) {
3241 if (InitChanged) {
3242 SemaRef.Diag(ForLoc, diag::err_acc_loop_variable)
3243 << SemaRef.LoopWithoutSeqInfo.Kind;
3244 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc,
3245 diag::note_acc_construct_here)
3246 << SemaRef.LoopWithoutSeqInfo.Kind;
3247 }
3248 return nullptr;
3249 }
3250
3251 auto DiagLoopVar = [&]() {
3252 if (InitChanged) {
3253 SemaRef.Diag(Init->getBeginLoc(), diag::err_acc_loop_variable)
3254 << SemaRef.LoopWithoutSeqInfo.Kind;
3255 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc,
3256 diag::note_acc_construct_here)
3257 << SemaRef.LoopWithoutSeqInfo.Kind;
3258 }
3259 return nullptr;
3260 };
3261
3262 if (const auto *ExprTemp = dyn_cast<ExprWithCleanups>(Init))
3263 Init = ExprTemp->getSubExpr();
3264 if (const auto *E = dyn_cast<Expr>(Init))
3266
3267 const ValueDecl *InitVar = nullptr;
3268
3269 if (const auto *BO = dyn_cast<BinaryOperator>(Init)) {
3270 // Allow assignment operator here.
3271
3272 if (!BO->isAssignmentOp())
3273 return DiagLoopVar();
3274
3275 const Expr *LHS = BO->getLHS()->IgnoreParenImpCasts();
3276
3277 if (const auto *DRE = dyn_cast<DeclRefExpr>(LHS))
3278 InitVar = DRE->getDecl();
3279 } else if (const auto *DS = dyn_cast<DeclStmt>(Init)) {
3280 // Allow T t = <whatever>
3281 if (!DS->isSingleDecl())
3282 return DiagLoopVar();
3283
3284 InitVar = dyn_cast<ValueDecl>(DS->getSingleDecl());
3285
3286 // Ensure we have an initializer, unless this is a record/dependent type.
3287
3288 if (InitVar) {
3289 if (!isa<VarDecl>(InitVar))
3290 return DiagLoopVar();
3291
3292 if (!InitVar->getType()->isRecordType() &&
3293 !InitVar->getType()->isDependentType() &&
3294 !cast<VarDecl>(InitVar)->hasInit())
3295 return DiagLoopVar();
3296 }
3297 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(Init)) {
3298 // Allow assignment operator call.
3299 if (CE->getOperator() != OO_Equal)
3300 return DiagLoopVar();
3301
3302 const Expr *LHS = CE->getArg(0)->IgnoreParenImpCasts();
3303
3304 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3305 InitVar = DRE->getDecl();
3306 } else if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
3307 if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3308 InitVar = ME->getMemberDecl();
3309 }
3310 }
3311
3312 if (!InitVar)
3313 return DiagLoopVar();
3314
3315 InitVar = cast<ValueDecl>(InitVar->getCanonicalDecl());
3316 QualType VarType = InitVar->getType().getNonReferenceType();
3317
3318 // Since we have one, all we need to do is ensure it is the right type.
3319 if (!isValidLoopVariableType(VarType)) {
3320 if (InitChanged) {
3321 SemaRef.Diag(InitVar->getBeginLoc(), diag::err_acc_loop_variable_type)
3322 << SemaRef.LoopWithoutSeqInfo.Kind << VarType;
3323 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc,
3324 diag::note_acc_construct_here)
3325 << SemaRef.LoopWithoutSeqInfo.Kind;
3326 }
3327 return nullptr;
3328 }
3329
3330 return InitVar;
3331}
3332void SemaOpenACC::ForStmtBeginChecker::checkCond() {
3333 if (!*Cond) {
3334 SemaRef.Diag(ForLoc, diag::err_acc_loop_terminating_condition)
3335 << SemaRef.LoopWithoutSeqInfo.Kind;
3336 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc, diag::note_acc_construct_here)
3337 << SemaRef.LoopWithoutSeqInfo.Kind;
3338 }
3339 // Nothing else to do here. we could probably do some additional work to look
3340 // into the termination condition, but that error-prone. For now, we don't
3341 // implement anything other than 'there is a termination condition', and if
3342 // codegen/MLIR comes up with some necessary restrictions, we can implement
3343 // them here.
3344}
3345
3346void SemaOpenACC::ForStmtBeginChecker::checkInc(const ValueDecl *Init) {
3347
3348 if (!*Inc) {
3349 SemaRef.Diag(ForLoc, diag::err_acc_loop_not_monotonic)
3350 << SemaRef.LoopWithoutSeqInfo.Kind;
3351 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc, diag::note_acc_construct_here)
3352 << SemaRef.LoopWithoutSeqInfo.Kind;
3353 return;
3354 }
3355 auto DiagIncVar = [this] {
3356 SemaRef.Diag((*Inc)->getBeginLoc(), diag::err_acc_loop_not_monotonic)
3357 << SemaRef.LoopWithoutSeqInfo.Kind;
3358 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc, diag::note_acc_construct_here)
3359 << SemaRef.LoopWithoutSeqInfo.Kind;
3360 return;
3361 };
3362
3363 if (const auto *ExprTemp = dyn_cast<ExprWithCleanups>(*Inc))
3364 Inc = ExprTemp->getSubExpr();
3365 if (const auto *E = dyn_cast<Expr>(*Inc))
3367
3368 auto getDeclFromExpr = [](const Expr *E) -> const ValueDecl * {
3369 E = E->IgnoreParenImpCasts();
3370 if (const auto *FE = dyn_cast<FullExpr>(E))
3371 E = FE->getSubExpr();
3372
3373 E = E->IgnoreParenImpCasts();
3374
3375 if (!E)
3376 return nullptr;
3377 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
3378 return dyn_cast<ValueDecl>(DRE->getDecl());
3379
3380 if (const auto *ME = dyn_cast<MemberExpr>(E))
3381 if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3382 return ME->getMemberDecl();
3383
3384 return nullptr;
3385 };
3386
3387 const ValueDecl *IncVar = nullptr;
3388
3389 // Here we enforce the monotonically increase/decrease:
3390 if (const auto *UO = dyn_cast<UnaryOperator>(*Inc)) {
3391 // Allow increment/decrement ops.
3392 if (!UO->isIncrementDecrementOp())
3393 return DiagIncVar();
3394 IncVar = getDeclFromExpr(UO->getSubExpr());
3395 } else if (const auto *BO = dyn_cast<BinaryOperator>(*Inc)) {
3396 switch (BO->getOpcode()) {
3397 default:
3398 return DiagIncVar();
3399 case BO_AddAssign:
3400 case BO_SubAssign:
3401 case BO_MulAssign:
3402 case BO_DivAssign:
3403 case BO_Assign:
3404 // += -= *= /= should all be fine here, this should be all of the
3405 // 'monotonical' compound-assign ops.
3406 // Assignment we just give up on, we could do better, and ensure that it
3407 // is a binary/operator expr doing more work, but that seems like a lot
3408 // of work for an error prone check.
3409 break;
3410 }
3411 IncVar = getDeclFromExpr(BO->getLHS());
3412 } else if (const auto *CE = dyn_cast<CXXOperatorCallExpr>(*Inc)) {
3413 switch (CE->getOperator()) {
3414 default:
3415 return DiagIncVar();
3416 case OO_PlusPlus:
3417 case OO_MinusMinus:
3418 case OO_PlusEqual:
3419 case OO_MinusEqual:
3420 case OO_StarEqual:
3421 case OO_SlashEqual:
3422 case OO_Equal:
3423 // += -= *= /= should all be fine here, this should be all of the
3424 // 'monotonical' compound-assign ops.
3425 // Assignment we just give up on, we could do better, and ensure that it
3426 // is a binary/operator expr doing more work, but that seems like a lot
3427 // of work for an error prone check.
3428 break;
3429 }
3430
3431 IncVar = getDeclFromExpr(CE->getArg(0));
3432
3433 } else if (const auto *ME = dyn_cast<CXXMemberCallExpr>(*Inc)) {
3434 IncVar = getDeclFromExpr(ME->getImplicitObjectArgument());
3435 // We can't really do much for member expressions, other than hope they are
3436 // doing the right thing, so give up here.
3437 }
3438
3439 if (!IncVar)
3440 return DiagIncVar();
3441
3442 // InitVar shouldn't be null unless there was an error, so don't diagnose if
3443 // that is the case. Else we should ensure that it refers to the loop
3444 // value.
3445 if (Init && IncVar->getCanonicalDecl() != Init->getCanonicalDecl())
3446 return DiagIncVar();
3447
3448 return;
3449}
3450
3452 const Stmt *First, const Stmt *OldSecond,
3453 const Stmt *Second, const Stmt *OldThird,
3454 const Stmt *Third) {
3455 if (!getLangOpts().OpenACC)
3456 return;
3457
3458 std::optional<const Stmt *> S;
3459 if (OldSecond == Second)
3460 S = std::nullopt;
3461 else
3462 S = Second;
3463 std::optional<const Stmt *> T;
3464 if (OldThird == Third)
3465 S = std::nullopt;
3466 else
3467 S = Third;
3468
3469 bool InitChanged = false;
3470 if (OldFirst != First) {
3471 InitChanged = true;
3472
3473 // VarDecls are always rebuild because they are dependent, so we can do a
3474 // little work to suppress some of the double checking based on whether the
3475 // type is instantiation dependent.
3476 QualType OldVDTy;
3477 QualType NewVDTy;
3478 if (const auto *DS = dyn_cast<DeclStmt>(OldFirst))
3479 if (const VarDecl *VD = dyn_cast_if_present<VarDecl>(
3480 DS->isSingleDecl() ? DS->getSingleDecl() : nullptr))
3481 OldVDTy = VD->getType();
3482 if (const auto *DS = dyn_cast<DeclStmt>(First))
3483 if (const VarDecl *VD = dyn_cast_if_present<VarDecl>(
3484 DS->isSingleDecl() ? DS->getSingleDecl() : nullptr))
3485 NewVDTy = VD->getType();
3486
3487 if (!OldVDTy.isNull() && !NewVDTy.isNull())
3488 InitChanged = OldVDTy->isInstantiationDependentType() !=
3490 }
3491
3492 ForStmtBeginChecker FSBC{*this, ForLoc, First, InitChanged, S, T};
3493 if (!LoopInfo.TopLevelLoopSeen) {
3494 FSBC.check();
3495 }
3496
3497 ForStmtBeginHelper(ForLoc, FSBC);
3498}
3499
3501 const Stmt *Second, const Stmt *Third) {
3502 if (!getLangOpts().OpenACC)
3503 return;
3504
3505 ForStmtBeginChecker FSBC{*this, ForLoc, First, /*InitChanged=*/true,
3506 Second, Third};
3507 if (!LoopInfo.TopLevelLoopSeen) {
3508 FSBC.check();
3509 }
3510
3511 ForStmtBeginHelper(ForLoc, FSBC);
3512}
3513
3515 const Stmt *OldRangeFor,
3516 const Stmt *RangeFor) {
3517 if (!getLangOpts().OpenACC)
3518 return;
3519
3520 std::optional<const CXXForRangeStmt *> RF;
3521
3522 if (OldRangeFor == RangeFor)
3523 RF = std::nullopt;
3524 else
3525 RF = cast<CXXForRangeStmt>(RangeFor);
3526
3527 ForStmtBeginChecker FSBC{*this, ForLoc, RF};
3528 if (!LoopInfo.TopLevelLoopSeen) {
3529 FSBC.check();
3530 }
3531 ForStmtBeginHelper(ForLoc, FSBC);
3532}
3533
3535 const Stmt *RangeFor) {
3536 if (!getLangOpts().OpenACC)
3537 return;
3538
3539 ForStmtBeginChecker FSBC{*this, ForLoc, cast<CXXForRangeStmt>(RangeFor)};
3540 if (!LoopInfo.TopLevelLoopSeen) {
3541 FSBC.check();
3542 }
3543 ForStmtBeginHelper(ForLoc, FSBC);
3544}
3545
3546namespace {
3547SourceLocation FindInterveningCodeInLoop(const Stmt *CurStmt) {
3548 // We should diagnose on anything except `CompoundStmt`, `NullStmt`,
3549 // `ForStmt`, `CXXForRangeStmt`, since those are legal, and `WhileStmt` and
3550 // `DoStmt`, as those are caught as a violation elsewhere.
3551 // For `CompoundStmt` we need to search inside of it.
3552 if (!CurStmt ||
3553 isa<ForStmt, NullStmt, ForStmt, CXXForRangeStmt, WhileStmt, DoStmt>(
3554 CurStmt))
3555 return SourceLocation{};
3556
3557 // Any other construct is an error anyway, so it has already been diagnosed.
3558 if (isa<OpenACCConstructStmt>(CurStmt))
3559 return SourceLocation{};
3560
3561 // Search inside the compound statement, this allows for arbitrary nesting
3562 // of compound statements, as long as there isn't any code inside.
3563 if (const auto *CS = dyn_cast<CompoundStmt>(CurStmt)) {
3564 for (const auto *ChildStmt : CS->children()) {
3565 SourceLocation ChildStmtLoc = FindInterveningCodeInLoop(ChildStmt);
3566 if (ChildStmtLoc.isValid())
3567 return ChildStmtLoc;
3568 }
3569 // Empty/not invalid compound statements are legal.
3570 return SourceLocation{};
3571 }
3572 return CurStmt->getBeginLoc();
3573}
3574} // namespace
3575
3577 if (!getLangOpts().OpenACC)
3578 return;
3579
3580 // Set this to 'true' so if we find another one at this level we can diagnose.
3581 LoopInfo.CurLevelHasLoopAlready = true;
3582
3583 if (!Body.isUsable())
3584 return;
3585
3586 bool IsActiveCollapse = CollapseInfo.CurCollapseCount &&
3587 *CollapseInfo.CurCollapseCount > 0 &&
3588 !CollapseInfo.ActiveCollapse->hasForce();
3589 bool IsActiveTile = TileInfo.CurTileCount && *TileInfo.CurTileCount > 0;
3590
3591 if (IsActiveCollapse || IsActiveTile) {
3592 SourceLocation OtherStmtLoc = FindInterveningCodeInLoop(Body.get());
3593
3594 if (OtherStmtLoc.isValid() && IsActiveCollapse) {
3595 Diag(OtherStmtLoc, diag::err_acc_intervening_code)
3596 << OpenACCClauseKind::Collapse << CollapseInfo.DirectiveKind;
3597 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
3598 diag::note_acc_active_clause_here)
3600 }
3601
3602 if (OtherStmtLoc.isValid() && IsActiveTile) {
3603 Diag(OtherStmtLoc, diag::err_acc_intervening_code)
3604 << OpenACCClauseKind::Tile << TileInfo.DirectiveKind;
3605 Diag(TileInfo.ActiveTile->getBeginLoc(),
3606 diag::note_acc_active_clause_here)
3608 }
3609 }
3610}
3611
3612namespace {
3613// Get a list of clause Kinds for diagnosing a list, joined by a commas and an
3614// 'or'.
3615std::string GetListOfClauses(llvm::ArrayRef<OpenACCClauseKind> Clauses) {
3616 assert(!Clauses.empty() && "empty clause list not supported");
3617
3618 std::string Output;
3619 llvm::raw_string_ostream OS{Output};
3620
3621 if (Clauses.size() == 1) {
3622 OS << '\'' << Clauses[0] << '\'';
3623 return Output;
3624 }
3625
3626 llvm::ArrayRef<OpenACCClauseKind> AllButLast{Clauses.begin(),
3627 Clauses.end() - 1};
3628
3629 llvm::interleave(
3630 AllButLast, [&](OpenACCClauseKind K) { OS << '\'' << K << '\''; },
3631 [&] { OS << ", "; });
3632
3633 OS << " or \'" << Clauses.back() << '\'';
3634 return Output;
3635}
3636} // namespace
3637
3643
3644 // OpenACC 3.3 2.9.1:
3645 // Intervening code must not contain other OpenACC directives or calls to API
3646 // routines.
3647 //
3648 // ALL constructs are ill-formed if there is an active 'collapse'
3649 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
3650 Diag(StartLoc, diag::err_acc_invalid_in_loop)
3651 << /*OpenACC Construct*/ 0 << CollapseInfo.DirectiveKind
3653 assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");
3654 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
3655 diag::note_acc_active_clause_here)
3657 }
3658 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
3659 Diag(StartLoc, diag::err_acc_invalid_in_loop)
3660 << /*OpenACC Construct*/ 0 << TileInfo.DirectiveKind
3662 assert(TileInfo.ActiveTile && "Tile count without object?");
3663 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
3665 }
3666
3667 // OpenACC3.3 2.6.5: At least one copy, copyin, copyout, create, no_create,
3668 // present, deviceptr, attach, or default clause must appear on a 'data'
3669 // construct.
3670 if (K == OpenACCDirectiveKind::Data &&
3671 llvm::find_if(Clauses,
3676 OpenACCDefaultClause>) == Clauses.end())
3677 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
3678 << K
3679 << GetListOfClauses(
3685
3686 // OpenACC3.3 2.6.6: At least one copyin, create, or attach clause must appear
3687 // on an enter data directive.
3689 llvm::find_if(Clauses,
3691 OpenACCAttachClause>) == Clauses.end())
3692 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
3693 << K
3694 << GetListOfClauses({
3698 });
3699 // OpenACC3.3 2.6.6: At least one copyout, delete, or detach clause must
3700 // appear on an exit data directive.
3702 llvm::find_if(Clauses,
3704 OpenACCDetachClause>) == Clauses.end())
3705 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
3706 << K
3707 << GetListOfClauses({
3711 });
3712
3713 // OpenACC3.3 2.8: At least 'one use_device' clause must appear.
3715 llvm::find_if(Clauses, llvm::IsaPred<OpenACCUseDeviceClause>) ==
3716 Clauses.end())
3717 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
3718 << K << GetListOfClauses({OpenACCClauseKind::UseDevice});
3719
3720 // OpenACC3.3 2.14.3: At least one default_async, device_num, or device_type
3721 // clause must appear.
3722 if (K == OpenACCDirectiveKind::Set &&
3723 llvm::find_if(
3724 Clauses,
3727 Clauses.end())
3728 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
3729 << K
3730 << GetListOfClauses({OpenACCClauseKind::DefaultAsync,
3734
3735 // OpenACC3.3 2.14.4: At least one self, host, or device clause must appear on
3736 // an update directive.
3738 llvm::find_if(Clauses, llvm::IsaPred<OpenACCSelfClause, OpenACCHostClause,
3740 Clauses.end())
3741 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
3742 << K
3743 << GetListOfClauses({OpenACCClauseKind::Self,
3746
3747 return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/true);
3748}
3749
3752 SourceLocation LParenLoc, SourceLocation MiscLoc, ArrayRef<Expr *> Exprs,
3753 SourceLocation RParenLoc, SourceLocation EndLoc,
3754 ArrayRef<OpenACCClause *> Clauses, StmtResult AssocStmt) {
3755 switch (K) {
3756 default:
3757 return StmtEmpty();
3759 return StmtError();
3764 getASTContext(), K, StartLoc, DirLoc, EndLoc, Clauses,
3765 AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
3766 }
3771 getASTContext(), K, StartLoc, DirLoc, EndLoc, Clauses,
3772 AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
3773 }
3776 getASTContext(), ActiveComputeConstructInfo.Kind, StartLoc, DirLoc,
3777 EndLoc, Clauses, AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
3778 }
3781 getASTContext(), StartLoc, DirLoc, EndLoc, Clauses,
3782 AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
3783 }
3785 return OpenACCEnterDataConstruct::Create(getASTContext(), StartLoc, DirLoc,
3786 EndLoc, Clauses);
3787 }
3789 return OpenACCExitDataConstruct::Create(getASTContext(), StartLoc, DirLoc,
3790 EndLoc, Clauses);
3791 }
3794 getASTContext(), StartLoc, DirLoc, EndLoc, Clauses,
3795 AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
3796 }
3799 getASTContext(), StartLoc, DirLoc, LParenLoc, Exprs.front(), MiscLoc,
3800 Exprs.drop_front(), RParenLoc, EndLoc, Clauses);
3801 }
3803 return OpenACCInitConstruct::Create(getASTContext(), StartLoc, DirLoc,
3804 EndLoc, Clauses);
3805 }
3807 return OpenACCShutdownConstruct::Create(getASTContext(), StartLoc, DirLoc,
3808 EndLoc, Clauses);
3809 }
3811 return OpenACCSetConstruct::Create(getASTContext(), StartLoc, DirLoc,
3812 EndLoc, Clauses);
3813 }
3815 return OpenACCUpdateConstruct::Create(getASTContext(), StartLoc, DirLoc,
3816 EndLoc, Clauses);
3817 }
3818 }
3819 llvm_unreachable("Unhandled case in directive handling?");
3820}
3821
3823 SourceLocation DirectiveLoc, OpenACCDirectiveKind K,
3824 ArrayRef<const OpenACCClause *> Clauses, StmtResult AssocStmt) {
3825 switch (K) {
3826 default:
3827 llvm_unreachable("Unimplemented associated statement application");
3834 llvm_unreachable(
3835 "these don't have associated statements, so shouldn't get here");
3841 // There really isn't any checking here that could happen. As long as we
3842 // have a statement to associate, this should be fine.
3843 // OpenACC 3.3 Section 6:
3844 // Structured Block: in C or C++, an executable statement, possibly
3845 // compound, with a single entry at the top and a single exit at the
3846 // bottom.
3847 // FIXME: Should we reject DeclStmt's here? The standard isn't clear, and
3848 // an interpretation of it is to allow this and treat the initializer as
3849 // the 'structured block'.
3850 return AssocStmt;
3855 if (!AssocStmt.isUsable())
3856 return StmtError();
3857
3858 if (!isa<CXXForRangeStmt, ForStmt>(AssocStmt.get())) {
3859 Diag(AssocStmt.get()->getBeginLoc(), diag::err_acc_loop_not_for_loop)
3860 << K;
3861 Diag(DirectiveLoc, diag::note_acc_construct_here) << K;
3862 return StmtError();
3863 }
3864
3865 if (!CollapseInfo.CollapseDepthSatisfied || !TileInfo.TileDepthSatisfied) {
3866 if (!CollapseInfo.CollapseDepthSatisfied) {
3867 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
3869 assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");
3870 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
3871 diag::note_acc_active_clause_here)
3873 }
3874
3875 if (!TileInfo.TileDepthSatisfied) {
3876 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
3878 assert(TileInfo.ActiveTile && "Collapse count without object?");
3879 Diag(TileInfo.ActiveTile->getBeginLoc(),
3880 diag::note_acc_active_clause_here)
3882 }
3883 return StmtError();
3884 }
3885
3886 return AssocStmt.get();
3887 }
3888 llvm_unreachable("Invalid associated statement application");
3889}
3890
3892 SourceLocation StartLoc) {
3893 // OpenCC3.3 2.1 (line 889)
3894 // A program must not depend on the order of evaluation of expressions in
3895 // clause arguments or on any side effects of the evaluations.
3898 return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/false);
3899}
3900
3902
3905 return OpenACCAsteriskSizeExpr::Create(getASTContext(), AsteriskLoc);
3906}
3907
3910 return BuildOpenACCAsteriskSizeExpr(AsteriskLoc);
3911}
Expr * E
Defines some OpenACC-specific enums and functions.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
static NamedDecl * getDeclFromExpr(Expr *E)
Definition: SemaExpr.cpp:14673
SourceLocation Loc
Definition: SemaObjC.cpp:759
This file declares semantic analysis for OpenACC constructs and clauses.
This file defines OpenACC AST classes for statement-level contructs.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition: APValue.h:122
APSInt & getInt()
Definition: APValue.h:465
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
const ConstantArrayType * getAsConstantArrayType(QualType T) const
Definition: ASTContext.h:2915
CanQualType DependentTy
Definition: ASTContext.h:1188
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
CanQualType ArraySectionTy
Definition: ASTContext.h:1200
CanQualType IntTy
Definition: ASTContext.h:1169
PtrTy get() const
Definition: Ownership.h:170
bool isInvalid() const
Definition: Ownership.h:166
bool isUsable() const
Definition: Ownership.h:168
This class represents BOTH the OpenMP Array Section and OpenACC 'subarray', with a boolean differenti...
Definition: Expr.h:6986
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
Definition: Expr.cpp:5177
QualType getElementType() const
Definition: Type.h:3589
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2885
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
base_class_range bases()
Definition: DeclCXX.h:620
llvm::APInt getSize() const
Return the constant array size as an APInt.
Definition: Type.h:3671
static ConstantExpr * Create(const ASTContext &Context, Expr *E, const APValue &Result)
Definition: Expr.cpp:350
bool isStdNamespace() const
Definition: DeclBase.cpp:1318
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
Definition: DeclBase.cpp:2008
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition: Stmt.h:1519
const Decl * getSingleDecl() const
Definition: Stmt.h:1534
SourceLocation getLocation() const
Definition: DeclBase.h:442
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: DeclBase.h:434
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:967
This represents one expression.
Definition: Expr.h:110
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Definition: Expr.cpp:3095
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Definition: Expr.h:192
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition: Expr.cpp:3090
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
Definition: Expr.h:245
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
Definition: Expr.h:221
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition: Expr.cpp:277
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
QualType getType() const
Definition: Expr.h:142
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
Definition: Expr.h:516
Represents a member of a struct/union/class.
Definition: Decl.h:3033
static OpenACCAsteriskSizeExpr * Create(const ASTContext &C, SourceLocation Loc)
Definition: Expr.cpp:5424
static OpenACCAsyncClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static OpenACCAttachClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCAutoClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)
This is the base type for all OpenACC Clauses.
Definition: OpenACCClause.h:24
OpenACCClauseKind getClauseKind() const
Definition: OpenACCClause.h:37
SourceLocation getBeginLoc() const
Definition: OpenACCClause.h:38
Represents a 'collapse' clause on a 'loop' construct.
static OpenACCCollapseClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, bool HasForce, Expr *LoopCount, SourceLocation EndLoc)
const Expr * getLoopCount() const
static OpenACCCombinedConstruct * Create(const ASTContext &C, OpenACCDirectiveKind K, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses, Stmt *StructuredBlock)
static OpenACCComputeConstruct * Create(const ASTContext &C, OpenACCDirectiveKind K, SourceLocation BeginLoc, SourceLocation DirectiveLoc, SourceLocation EndLoc, ArrayRef< const OpenACCClause * > Clauses, Stmt *StructuredBlock)
Definition: StmtOpenACC.cpp:27
static OpenACCCopyClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCCopyInClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsReadOnly, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCCopyOutClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsZero, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCCreateClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsZero, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCDataConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses, Stmt *StructuredBlock)
static OpenACCDefaultAsyncClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
A 'default' clause, has the optional 'none' or 'present' argument.
static OpenACCDefaultClause * Create(const ASTContext &C, OpenACCDefaultClauseKind K, SourceLocation BeginLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
static OpenACCDeleteClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCDetachClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCDeviceClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCDeviceNumClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static OpenACCDevicePtrClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
A 'device_type' or 'dtype' clause, takes a list of either an 'asterisk' or an identifier.
static OpenACCDeviceTypeClause * Create(const ASTContext &C, OpenACCClauseKind K, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< DeviceTypeArgument > Archs, SourceLocation EndLoc)
static OpenACCEnterDataConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses)
static OpenACCExitDataConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses)
static OpenACCFinalizeClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)
static OpenACCFirstPrivateClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCGangClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< OpenACCGangKind > GangKinds, ArrayRef< Expr * > IntExprs, SourceLocation EndLoc)
static OpenACCHostClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCHostDataConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses, Stmt *StructuredBlock)
An 'if' clause, which has a required condition expression.
static OpenACCIfClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *ConditionExpr, SourceLocation EndLoc)
static OpenACCIfPresentClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)
static OpenACCIndependentClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)
static OpenACCInitConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses)
static OpenACCLoopConstruct * Create(const ASTContext &C, OpenACCDirectiveKind ParentKind, SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation EndLoc, ArrayRef< const OpenACCClause * > Clauses, Stmt *Loop)
Definition: StmtOpenACC.cpp:80
static OpenACCNoCreateClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCNumGangsClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > IntExprs, SourceLocation EndLoc)
static OpenACCNumWorkersClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static OpenACCPresentClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCPrivateClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCReductionClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, OpenACCReductionOperator Operator, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
A 'self' clause, which has an optional condition expression, or, in the event of an 'update' directiv...
static OpenACCSelfClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *ConditionExpr, SourceLocation EndLoc)
static OpenACCSeqClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)
static OpenACCSetConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses)
static OpenACCShutdownConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses)
static OpenACCTileClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > SizeExprs, SourceLocation EndLoc)
llvm::ArrayRef< Expr * > getSizeExprs()
static OpenACCUpdateConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses)
static OpenACCUseDeviceClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCVectorClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static OpenACCVectorLengthClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static OpenACCWaitClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef< Expr * > QueueIdExprs, SourceLocation EndLoc)
static OpenACCWaitConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation LParenLoc, Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef< Expr * > QueueIdExprs, SourceLocation RParenLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses)
static OpenACCWorkerClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
A (possibly-)qualified type.
Definition: Type.h:929
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:996
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Definition: Type.h:8134
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition: Type.h:8025
A generic diagnostic builder for errors which may or may not be deferred.
Definition: SemaBase.h:110
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: SemaBase.cpp:60
ASTContext & getASTContext() const
Definition: SemaBase.cpp:9
Sema & SemaRef
Definition: SemaBase.h:40
const LangOptions & getLangOpts() const
Definition: SemaBase.cpp:11
AssociatedStmtRAII(SemaOpenACC &, OpenACCDirectiveKind, SourceLocation, ArrayRef< const OpenACCClause * >, ArrayRef< OpenACCClause * >)
void SetTileInfoBeforeAssociatedStmt(ArrayRef< const OpenACCClause * > UnInstClauses, ArrayRef< OpenACCClause * > Clauses)
void SetCollapseInfoBeforeAssociatedStmt(ArrayRef< const OpenACCClause * > UnInstClauses, ArrayRef< OpenACCClause * > Clauses)
A type to represent all the data for an OpenACC Clause that has been parsed, but not yet created/sema...
Definition: SemaOpenACC.h:202
ArrayRef< Expr * > getQueueIdExprs() const
Definition: SemaOpenACC.h:338
OpenACCDirectiveKind getDirectiveKind() const
Definition: SemaOpenACC.h:260
ArrayRef< OpenACCGangKind > getGangKinds() const
Definition: SemaOpenACC.h:380
OpenACCReductionOperator getReductionOp() const
Definition: SemaOpenACC.h:376
OpenACCClauseKind getClauseKind() const
Definition: SemaOpenACC.h:262
SourceLocation getLParenLoc() const
Definition: SemaOpenACC.h:266
ArrayRef< DeviceTypeArgument > getDeviceTypeArchitectures() const
Definition: SemaOpenACC.h:460
SourceLocation getBeginLoc() const
Definition: SemaOpenACC.h:264
SourceLocation getQueuesLoc() const
Definition: SemaOpenACC.h:318
void setVarListDetails(ArrayRef< Expr * > VarList, bool IsReadOnly, bool IsZero)
Definition: SemaOpenACC.h:536
OpenACCDefaultClauseKind getDefaultClauseKind() const
Definition: SemaOpenACC.h:270
ExprResult ActOnVar(OpenACCClauseKind CK, Expr *VarExpr)
Called when encountering a 'var' for OpenACC, ensures it is actually a declaration reference to a var...
ComputeConstructInfo & getActiveComputeConstructInfo()
Definition: SemaOpenACC.h:162
bool ActOnStartStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, ArrayRef< const OpenACCClause * > Clauses)
Called after the directive, including its clauses, have been parsed and parsing has consumed the 'ann...
ExprResult BuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc)
ExprResult ActOnIntExpr(OpenACCDirectiveKind DK, OpenACCClauseKind CK, SourceLocation Loc, Expr *IntExpr)
Called when encountering an 'int-expr' for OpenACC, and manages conversions and diagnostics to 'int'.
void ActOnWhileStmt(SourceLocation WhileLoc)
SourceLocation LoopWorkerClauseLoc
If there is a current 'active' loop construct with a 'worker' clause on it (on any sort of construct)...
Definition: SemaOpenACC.h:179
OpenACCClause * ActOnClause(ArrayRef< const OpenACCClause * > ExistingClauses, OpenACCParsedClause &Clause)
Called after parsing an OpenACC Clause so that it can be checked.
bool ActOnStartDeclDirective(OpenACCDirectiveKind K, SourceLocation StartLoc)
Called after the directive, including its clauses, have been parsed and parsing has consumed the 'ann...
bool CheckVarIsPointerType(OpenACCClauseKind ClauseKind, Expr *VarExpr)
Called to check the 'var' type is a variable of pointer type, necessary for 'deviceptr' and 'attach' ...
struct clang::SemaOpenACC::LoopGangOnKernelTy LoopGangClauseOnKernel
ExprResult CheckReductionVar(OpenACCDirectiveKind DirectiveKind, OpenACCReductionOperator ReductionOp, Expr *VarExpr)
Called while semantically analyzing the reduction clause, ensuring the var is the correct kind of ref...
ExprResult CheckCollapseLoopCount(Expr *LoopCount)
Checks the loop depth value for a collapse clause.
struct clang::SemaOpenACC::LoopWithoutSeqCheckingInfo LoopWithoutSeqInfo
StmtResult ActOnEndStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc, SourceLocation LParenLoc, SourceLocation MiscLoc, ArrayRef< Expr * > Exprs, SourceLocation RParenLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses, StmtResult AssocStmt)
Called after the directive has been completely parsed, including the declaration group or associated ...
DeclGroupRef ActOnEndDeclDirective()
Called after the directive has been completely parsed, including the declaration group or associated ...
OpenACCClause * CheckReductionClause(ArrayRef< const OpenACCClause * > ExistingClauses, OpenACCDirectiveKind DirectiveKind, SourceLocation BeginLoc, SourceLocation LParenLoc, OpenACCReductionOperator ReductionOp, ArrayRef< Expr * > Vars, SourceLocation EndLoc)
SourceLocation LoopVectorClauseLoc
If there is a current 'active' loop construct with a 'vector' clause on it (on any sort of construct)...
Definition: SemaOpenACC.h:184
void ActOnConstruct(OpenACCDirectiveKind K, SourceLocation DirLoc)
Called after the construct has been parsed, but clauses haven't been parsed.
ExprResult ActOnOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc)
ExprResult CheckGangExpr(ArrayRef< const OpenACCClause * > ExistingClauses, OpenACCDirectiveKind DK, OpenACCGangKind GK, Expr *E)
void ActOnDoStmt(SourceLocation DoLoc)
void ActOnRangeForStmtBegin(SourceLocation ForLoc, const Stmt *OldRangeFor, const Stmt *RangeFor)
void ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body)
OpenACCClause * CheckGangClause(OpenACCDirectiveKind DirKind, ArrayRef< const OpenACCClause * > ExistingClauses, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< OpenACCGangKind > GangKinds, ArrayRef< Expr * > IntExprs, SourceLocation EndLoc)
StmtResult ActOnAssociatedStmt(SourceLocation DirectiveLoc, OpenACCDirectiveKind K, ArrayRef< const OpenACCClause * > Clauses, StmtResult AssocStmt)
Called when we encounter an associated statement for our construct, this should check legality of the...
void ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *First, const Stmt *Second, const Stmt *Third)
ExprResult ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc, Expr *LowerBound, SourceLocation ColonLocFirst, Expr *Length, SourceLocation RBLoc)
Checks and creates an Array Section used in an OpenACC construct/clause.
ExprResult CheckTileSizeExpr(Expr *SizeExpr)
Checks a single size expr for a tile clause.
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:464
void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl=nullptr, ExpressionEvaluationContextRecord::ExpressionKind Type=ExpressionEvaluationContextRecord::EK_Other)
Definition: SemaExpr.cpp:17394
ExprResult PerformContextualImplicitConversion(SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter)
Perform a contextual implicit conversion.
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
Definition: SemaExpr.cpp:752
ASTContext & getASTContext() const
Definition: Sema.h:532
void PopExpressionEvaluationContext()
Definition: SemaExpr.cpp:17827
ExprResult DefaultLvalueConversion(Expr *E)
Definition: SemaExpr.cpp:640
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
Definition: SemaExpr.cpp:20971
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Definition: SemaType.cpp:9068
void DiscardCleanupsInEvaluationContext()
Definition: SemaExpr.cpp:17904
ExprResult CreateRecoveryExpr(SourceLocation Begin, SourceLocation End, ArrayRef< Expr * > SubExprs, QualType T=QualType())
Attempts to produce a RecoveryExpr after some AST node cannot be created.
Definition: SemaExpr.cpp:21168
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
Stmt - This represents one statement.
Definition: Stmt.h:84
SourceLocation getEndLoc() const LLVM_READONLY
Definition: Stmt.cpp:357
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:333
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:345
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1916
bool isDependentSizedArrayType() const
Definition: Type.h:8278
bool isConstantArrayType() const
Definition: Type.h:8262
bool isArrayType() const
Definition: Type.h:8258
bool isPointerType() const
Definition: Type.h:8186
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition: Type.h:8550
bool isEnumeralType() const
Definition: Type.h:8290
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:738
bool isNonOverloadPlaceholderType() const
Test for a placeholder type other than Overload; see BuiltinType::isNonOverloadPlaceholderType.
Definition: Type.h:8504
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
Definition: Type.h:2714
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2706
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition: Type.h:8786
bool isFunctionType() const
Definition: Type.h:8182
bool isAnyPointerType() const
Definition: Type.h:8194
bool isRecordType() const
Definition: Type.h:8286
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition: Type.cpp:1920
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:671
QualType getType() const
Definition: Decl.h:682
Represents a variable declaration or definition.
Definition: Decl.h:882
SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)
Returns the results of matching Matcher on Node.
bool Inc(InterpState &S, CodePtr OpPC)
1) Pops a pointer from the stack 2) Load the value from the pointer 3) Writes the value increased by ...
Definition: Interp.h:824
The JSON file list parser is used to communicate input to InstallAPI.
OpenACCDirectiveKind
Definition: OpenACCKinds.h:25
OpenACCReductionOperator
Definition: OpenACCKinds.h:509
bool isOpenACCComputeDirectiveKind(OpenACCDirectiveKind K)
Definition: OpenACCKinds.h:149
bool isOpenACCCombinedDirectiveKind(OpenACCDirectiveKind K)
Definition: OpenACCKinds.h:155
bool isOpenACCDataDirectiveKind(OpenACCDirectiveKind K)
Definition: OpenACCKinds.h:162
@ OK_Ordinary
An ordinary object is located at an address in memory.
Definition: Specifiers.h:151
OpenACCClauseKind
Represents the kind of an OpenACC clause.
Definition: OpenACCKinds.h:178
@ DevicePtr
'deviceptr' clause, allowed on Compute and Combined Constructs, plus 'data' and 'declare'.
@ Collapse
'collapse' clause, allowed on 'loop' and Combined constructs.
@ DeviceNum
'device_num' clause, allowed on 'init', 'shutdown', and 'set' constructs.
@ Invalid
Represents an invalid clause, for the purposes of parsing.
@ Copy
'copy' clause, allowed on Compute and Combined Constructs, plus 'data' and 'declare'.
@ Create
'create' clause, allowed on Compute and Combined constructs, plus 'data', 'enter data',...
@ DeviceType
'device_type' clause, allowed on Compute, 'data', 'init', 'shutdown', 'set', update',...
@ DefaultAsync
'default_async' clause, allowed on 'set' construct.
@ Attach
'attach' clause, allowed on Compute and Combined constructs, plus 'data' and 'enter data'.
@ If
'if' clause, allowed on all the Compute Constructs, Data Constructs, Executable Constructs,...
@ Default
'default' clause, allowed on parallel, serial, kernel (and compound) constructs.
@ UseDevice
'use_device' clause, allowed on 'host_data' construct.
@ NoCreate
'no_create' clause, allowed on allowed on Compute and Combined constructs, plus 'data'.
@ Reduction
'reduction' clause, allowed on Parallel, Serial, Loop, and the combined constructs.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ CopyOut
'copyout' clause, allowed on Compute and Combined constructs, plus 'data', 'exit data',...
@ Host
'host' clause, allowed on 'update' construct.
@ Tile
'tile' clause, allowed on 'loop' and Combined constructs.
@ Present
'present' clause, allowed on Compute and Combined constructs, plus 'data' and 'declare'.
@ CopyIn
'copyin' clause, allowed on Compute and Combined constructs, plus 'data', 'enter data',...
@ Device
'device' clause, allowed on the 'update' construct.
@ Detach
'detach' clause, allowed on the 'exit data' construct.
@ Delete
'delete' clause, allowed on the 'exit data' construct.
StmtResult StmtError()
Definition: Ownership.h:265
@ Result
The result type of a method or function.
ExprResult ExprError()
Definition: Ownership.h:264
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
Definition: Specifiers.h:139
const FunctionProtoType * T
OpenACCGangKind
Definition: OpenACCKinds.h:568
StmtResult StmtEmpty()
Definition: Ownership.h:272
EvalResult is a struct with detailed info about an evaluated expression.
Definition: Expr.h:642
APValue Val
Val - This is the value the expression can be folded to.
Definition: Expr.h:644