clang 21.0.0git
SemaOpenACCClause.cpp
Go to the documentation of this file.
1//===--- SemaOpenACCClause.cpp - Semantic Analysis for OpenACC clause -----===//
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 clauses.
10///
11//===----------------------------------------------------------------------===//
12
14#include "clang/AST/DeclCXX.h"
18
19using namespace clang;
20
21namespace {
22bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind,
23 OpenACCClauseKind ClauseKind) {
24 switch (ClauseKind) {
25 // FIXME: For each clause as we implement them, we can add the
26 // 'legalization' list here.
27 case OpenACCClauseKind::Default:
28 switch (DirectiveKind) {
29 case OpenACCDirectiveKind::Parallel:
30 case OpenACCDirectiveKind::Serial:
31 case OpenACCDirectiveKind::Kernels:
32 case OpenACCDirectiveKind::ParallelLoop:
33 case OpenACCDirectiveKind::SerialLoop:
34 case OpenACCDirectiveKind::KernelsLoop:
35 case OpenACCDirectiveKind::Data:
36 return true;
37 default:
38 return false;
39 }
40 case OpenACCClauseKind::If:
41 switch (DirectiveKind) {
42 case OpenACCDirectiveKind::Parallel:
43 case OpenACCDirectiveKind::Serial:
44 case OpenACCDirectiveKind::Kernels:
45 case OpenACCDirectiveKind::Data:
46 case OpenACCDirectiveKind::EnterData:
47 case OpenACCDirectiveKind::ExitData:
48 case OpenACCDirectiveKind::HostData:
49 case OpenACCDirectiveKind::Init:
50 case OpenACCDirectiveKind::Shutdown:
51 case OpenACCDirectiveKind::Set:
52 case OpenACCDirectiveKind::Update:
53 case OpenACCDirectiveKind::Wait:
54 case OpenACCDirectiveKind::ParallelLoop:
55 case OpenACCDirectiveKind::SerialLoop:
56 case OpenACCDirectiveKind::KernelsLoop:
57 return true;
58 default:
59 return false;
60 }
61 case OpenACCClauseKind::Self:
62 switch (DirectiveKind) {
63 case OpenACCDirectiveKind::Parallel:
64 case OpenACCDirectiveKind::Serial:
65 case OpenACCDirectiveKind::Kernels:
66 case OpenACCDirectiveKind::Update:
67 case OpenACCDirectiveKind::ParallelLoop:
68 case OpenACCDirectiveKind::SerialLoop:
69 case OpenACCDirectiveKind::KernelsLoop:
70 return true;
71 default:
72 return false;
73 }
74 case OpenACCClauseKind::NumGangs:
75 case OpenACCClauseKind::NumWorkers:
76 case OpenACCClauseKind::VectorLength:
77 switch (DirectiveKind) {
78 case OpenACCDirectiveKind::Parallel:
79 case OpenACCDirectiveKind::Kernels:
80 case OpenACCDirectiveKind::ParallelLoop:
81 case OpenACCDirectiveKind::KernelsLoop:
82 return true;
83 default:
84 return false;
85 }
86 case OpenACCClauseKind::FirstPrivate:
87 switch (DirectiveKind) {
88 case OpenACCDirectiveKind::Parallel:
89 case OpenACCDirectiveKind::Serial:
90 case OpenACCDirectiveKind::ParallelLoop:
91 case OpenACCDirectiveKind::SerialLoop:
92 return true;
93 default:
94 return false;
95 }
96 case OpenACCClauseKind::Private:
97 switch (DirectiveKind) {
98 case OpenACCDirectiveKind::Parallel:
99 case OpenACCDirectiveKind::Serial:
100 case OpenACCDirectiveKind::Loop:
101 case OpenACCDirectiveKind::ParallelLoop:
102 case OpenACCDirectiveKind::SerialLoop:
103 case OpenACCDirectiveKind::KernelsLoop:
104 return true;
105 default:
106 return false;
107 }
108 case OpenACCClauseKind::NoCreate:
109 switch (DirectiveKind) {
110 case OpenACCDirectiveKind::Parallel:
111 case OpenACCDirectiveKind::Serial:
112 case OpenACCDirectiveKind::Kernels:
113 case OpenACCDirectiveKind::Data:
114 case OpenACCDirectiveKind::ParallelLoop:
115 case OpenACCDirectiveKind::SerialLoop:
116 case OpenACCDirectiveKind::KernelsLoop:
117 return true;
118 default:
119 return false;
120 }
121 case OpenACCClauseKind::Present:
122 switch (DirectiveKind) {
123 case OpenACCDirectiveKind::Parallel:
124 case OpenACCDirectiveKind::Serial:
125 case OpenACCDirectiveKind::Kernels:
126 case OpenACCDirectiveKind::Data:
127 case OpenACCDirectiveKind::Declare:
128 case OpenACCDirectiveKind::ParallelLoop:
129 case OpenACCDirectiveKind::SerialLoop:
130 case OpenACCDirectiveKind::KernelsLoop:
131 return true;
132 default:
133 return false;
134 }
135
136 case OpenACCClauseKind::Copy:
137 case OpenACCClauseKind::PCopy:
138 case OpenACCClauseKind::PresentOrCopy:
139 switch (DirectiveKind) {
140 case OpenACCDirectiveKind::Parallel:
141 case OpenACCDirectiveKind::Serial:
142 case OpenACCDirectiveKind::Kernels:
143 case OpenACCDirectiveKind::Data:
144 case OpenACCDirectiveKind::Declare:
145 case OpenACCDirectiveKind::ParallelLoop:
146 case OpenACCDirectiveKind::SerialLoop:
147 case OpenACCDirectiveKind::KernelsLoop:
148 return true;
149 default:
150 return false;
151 }
152 case OpenACCClauseKind::CopyIn:
153 case OpenACCClauseKind::PCopyIn:
154 case OpenACCClauseKind::PresentOrCopyIn:
155 switch (DirectiveKind) {
156 case OpenACCDirectiveKind::Parallel:
157 case OpenACCDirectiveKind::Serial:
158 case OpenACCDirectiveKind::Kernels:
159 case OpenACCDirectiveKind::Data:
160 case OpenACCDirectiveKind::EnterData:
161 case OpenACCDirectiveKind::Declare:
162 case OpenACCDirectiveKind::ParallelLoop:
163 case OpenACCDirectiveKind::SerialLoop:
164 case OpenACCDirectiveKind::KernelsLoop:
165 return true;
166 default:
167 return false;
168 }
169 case OpenACCClauseKind::CopyOut:
170 case OpenACCClauseKind::PCopyOut:
171 case OpenACCClauseKind::PresentOrCopyOut:
172 switch (DirectiveKind) {
173 case OpenACCDirectiveKind::Parallel:
174 case OpenACCDirectiveKind::Serial:
175 case OpenACCDirectiveKind::Kernels:
176 case OpenACCDirectiveKind::Data:
177 case OpenACCDirectiveKind::ExitData:
178 case OpenACCDirectiveKind::Declare:
179 case OpenACCDirectiveKind::ParallelLoop:
180 case OpenACCDirectiveKind::SerialLoop:
181 case OpenACCDirectiveKind::KernelsLoop:
182 return true;
183 default:
184 return false;
185 }
186 case OpenACCClauseKind::Create:
187 case OpenACCClauseKind::PCreate:
188 case OpenACCClauseKind::PresentOrCreate:
189 switch (DirectiveKind) {
190 case OpenACCDirectiveKind::Parallel:
191 case OpenACCDirectiveKind::Serial:
192 case OpenACCDirectiveKind::Kernels:
193 case OpenACCDirectiveKind::Data:
194 case OpenACCDirectiveKind::EnterData:
195 case OpenACCDirectiveKind::ParallelLoop:
196 case OpenACCDirectiveKind::SerialLoop:
197 case OpenACCDirectiveKind::KernelsLoop:
198 return true;
199 default:
200 return false;
201 }
202
203 case OpenACCClauseKind::Attach:
204 switch (DirectiveKind) {
205 case OpenACCDirectiveKind::Parallel:
206 case OpenACCDirectiveKind::Serial:
207 case OpenACCDirectiveKind::Kernels:
208 case OpenACCDirectiveKind::Data:
209 case OpenACCDirectiveKind::EnterData:
210 case OpenACCDirectiveKind::ParallelLoop:
211 case OpenACCDirectiveKind::SerialLoop:
212 case OpenACCDirectiveKind::KernelsLoop:
213 return true;
214 default:
215 return false;
216 }
217 case OpenACCClauseKind::DevicePtr:
218 switch (DirectiveKind) {
219 case OpenACCDirectiveKind::Parallel:
220 case OpenACCDirectiveKind::Serial:
221 case OpenACCDirectiveKind::Kernels:
222 case OpenACCDirectiveKind::Data:
223 case OpenACCDirectiveKind::Declare:
224 case OpenACCDirectiveKind::ParallelLoop:
225 case OpenACCDirectiveKind::SerialLoop:
226 case OpenACCDirectiveKind::KernelsLoop:
227 return true;
228 default:
229 return false;
230 }
231 case OpenACCClauseKind::Async:
232 switch (DirectiveKind) {
233 case OpenACCDirectiveKind::Parallel:
234 case OpenACCDirectiveKind::Serial:
235 case OpenACCDirectiveKind::Kernels:
236 case OpenACCDirectiveKind::Data:
237 case OpenACCDirectiveKind::EnterData:
238 case OpenACCDirectiveKind::ExitData:
239 case OpenACCDirectiveKind::Set:
240 case OpenACCDirectiveKind::Update:
241 case OpenACCDirectiveKind::Wait:
242 case OpenACCDirectiveKind::ParallelLoop:
243 case OpenACCDirectiveKind::SerialLoop:
244 case OpenACCDirectiveKind::KernelsLoop:
245 return true;
246 default:
247 return false;
248 }
249 case OpenACCClauseKind::Wait:
250 switch (DirectiveKind) {
251 case OpenACCDirectiveKind::Parallel:
252 case OpenACCDirectiveKind::Serial:
253 case OpenACCDirectiveKind::Kernels:
254 case OpenACCDirectiveKind::Data:
255 case OpenACCDirectiveKind::EnterData:
256 case OpenACCDirectiveKind::ExitData:
257 case OpenACCDirectiveKind::Update:
258 case OpenACCDirectiveKind::ParallelLoop:
259 case OpenACCDirectiveKind::SerialLoop:
260 case OpenACCDirectiveKind::KernelsLoop:
261 return true;
262 default:
263 return false;
264 }
265
266 case OpenACCClauseKind::Seq:
267 switch (DirectiveKind) {
268 case OpenACCDirectiveKind::Loop:
269 case OpenACCDirectiveKind::Routine:
270 case OpenACCDirectiveKind::ParallelLoop:
271 case OpenACCDirectiveKind::SerialLoop:
272 case OpenACCDirectiveKind::KernelsLoop:
273 return true;
274 default:
275 return false;
276 }
277
278 case OpenACCClauseKind::Independent:
279 case OpenACCClauseKind::Auto:
280 switch (DirectiveKind) {
281 case OpenACCDirectiveKind::Loop:
282 case OpenACCDirectiveKind::ParallelLoop:
283 case OpenACCDirectiveKind::SerialLoop:
284 case OpenACCDirectiveKind::KernelsLoop:
285 return true;
286 default:
287 return false;
288 }
289
290 case OpenACCClauseKind::Reduction:
291 switch (DirectiveKind) {
292 case OpenACCDirectiveKind::Parallel:
293 case OpenACCDirectiveKind::Serial:
294 case OpenACCDirectiveKind::Loop:
295 case OpenACCDirectiveKind::ParallelLoop:
296 case OpenACCDirectiveKind::SerialLoop:
297 case OpenACCDirectiveKind::KernelsLoop:
298 return true;
299 default:
300 return false;
301 }
302
303 case OpenACCClauseKind::DeviceType:
304 case OpenACCClauseKind::DType:
305 switch (DirectiveKind) {
306 case OpenACCDirectiveKind::Parallel:
307 case OpenACCDirectiveKind::Serial:
308 case OpenACCDirectiveKind::Kernels:
309 case OpenACCDirectiveKind::Data:
310 case OpenACCDirectiveKind::Init:
311 case OpenACCDirectiveKind::Shutdown:
312 case OpenACCDirectiveKind::Set:
313 case OpenACCDirectiveKind::Update:
314 case OpenACCDirectiveKind::Loop:
315 case OpenACCDirectiveKind::Routine:
316 case OpenACCDirectiveKind::ParallelLoop:
317 case OpenACCDirectiveKind::SerialLoop:
318 case OpenACCDirectiveKind::KernelsLoop:
319 return true;
320 default:
321 return false;
322 }
323
324 case OpenACCClauseKind::Collapse: {
325 switch (DirectiveKind) {
326 case OpenACCDirectiveKind::Loop:
327 case OpenACCDirectiveKind::ParallelLoop:
328 case OpenACCDirectiveKind::SerialLoop:
329 case OpenACCDirectiveKind::KernelsLoop:
330 return true;
331 default:
332 return false;
333 }
334 }
335 case OpenACCClauseKind::Tile: {
336 switch (DirectiveKind) {
337 case OpenACCDirectiveKind::Loop:
338 case OpenACCDirectiveKind::ParallelLoop:
339 case OpenACCDirectiveKind::SerialLoop:
340 case OpenACCDirectiveKind::KernelsLoop:
341 return true;
342 default:
343 return false;
344 }
345 }
346
347 case OpenACCClauseKind::Gang: {
348 switch (DirectiveKind) {
349 case OpenACCDirectiveKind::Loop:
350 case OpenACCDirectiveKind::ParallelLoop:
351 case OpenACCDirectiveKind::SerialLoop:
352 case OpenACCDirectiveKind::KernelsLoop:
353 case OpenACCDirectiveKind::Routine:
354 return true;
355 default:
356 return false;
357 }
358 case OpenACCClauseKind::Worker: {
359 switch (DirectiveKind) {
360 case OpenACCDirectiveKind::Loop:
361 case OpenACCDirectiveKind::ParallelLoop:
362 case OpenACCDirectiveKind::SerialLoop:
363 case OpenACCDirectiveKind::KernelsLoop:
364 case OpenACCDirectiveKind::Routine:
365 return true;
366 default:
367 return false;
368 }
369 }
370 case OpenACCClauseKind::Vector: {
371 switch (DirectiveKind) {
372 case OpenACCDirectiveKind::Loop:
373 case OpenACCDirectiveKind::ParallelLoop:
374 case OpenACCDirectiveKind::SerialLoop:
375 case OpenACCDirectiveKind::KernelsLoop:
376 case OpenACCDirectiveKind::Routine:
377 return true;
378 default:
379 return false;
380 }
381 }
382 case OpenACCClauseKind::Finalize: {
383 switch (DirectiveKind) {
384 case OpenACCDirectiveKind::ExitData:
385 return true;
386 default:
387 return false;
388 }
389 }
390 case OpenACCClauseKind::IfPresent: {
391 switch (DirectiveKind) {
392 case OpenACCDirectiveKind::HostData:
393 case OpenACCDirectiveKind::Update:
394 return true;
395 default:
396 return false;
397 }
398 }
399 case OpenACCClauseKind::Delete: {
400 switch (DirectiveKind) {
401 case OpenACCDirectiveKind::ExitData:
402 return true;
403 default:
404 return false;
405 }
406 }
407
408 case OpenACCClauseKind::Detach: {
409 switch (DirectiveKind) {
410 case OpenACCDirectiveKind::ExitData:
411 return true;
412 default:
413 return false;
414 }
415 }
416
417 case OpenACCClauseKind::DeviceNum: {
418 switch (DirectiveKind) {
419 case OpenACCDirectiveKind::Init:
420 case OpenACCDirectiveKind::Shutdown:
421 case OpenACCDirectiveKind::Set:
422 return true;
423 default:
424 return false;
425 }
426 }
427
428 case OpenACCClauseKind::UseDevice: {
429 switch (DirectiveKind) {
430 case OpenACCDirectiveKind::HostData:
431 return true;
432 default:
433 return false;
434 }
435 }
436 case OpenACCClauseKind::DefaultAsync: {
437 switch (DirectiveKind) {
438 case OpenACCDirectiveKind::Set:
439 return true;
440 default:
441 return false;
442 }
443 }
444 case OpenACCClauseKind::Device: {
445 switch (DirectiveKind) {
446 case OpenACCDirectiveKind::Update:
447 return true;
448 default:
449 return false;
450 }
451 }
452 case OpenACCClauseKind::Host: {
453 switch (DirectiveKind) {
454 case OpenACCDirectiveKind::Update:
455 return true;
456 default:
457 return false;
458 }
459 }
460 }
461
462 default:
463 // Do nothing so we can go to the 'unimplemented' diagnostic instead.
464 return true;
465 }
466 llvm_unreachable("Invalid clause kind");
467}
468
469bool checkAlreadyHasClauseOfKind(
472 const auto *Itr = llvm::find_if(ExistingClauses, [&](const OpenACCClause *C) {
473 return C->getClauseKind() == Clause.getClauseKind();
474 });
475 if (Itr != ExistingClauses.end()) {
476 S.Diag(Clause.getBeginLoc(), diag::err_acc_duplicate_clause_disallowed)
477 << Clause.getDirectiveKind() << Clause.getClauseKind();
478 S.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
479 return true;
480 }
481 return false;
482}
483bool checkValidAfterDeviceType(
484 SemaOpenACC &S, const OpenACCDeviceTypeClause &DeviceTypeClause,
485 const SemaOpenACC::OpenACCParsedClause &NewClause) {
486 // This is implemented for everything but 'routine', so treat as 'fine' for
487 // that.
488 if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Routine)
489 return false;
490
491 // OpenACC3.3: Section 2.4: Clauses that precede any device_type clause are
492 // default clauses. Clauses that follow a device_type clause up to the end of
493 // the directive or up to the next device_type clause are device-specific
494 // clauses for the device types specified in the device_type argument.
495 //
496 // The above implies that despite what the individual text says, these are
497 // valid.
498 if (NewClause.getClauseKind() == OpenACCClauseKind::DType ||
499 NewClause.getClauseKind() == OpenACCClauseKind::DeviceType)
500 return false;
501
502 // Implement check from OpenACC3.3: section 2.5.4:
503 // Only the async, wait, num_gangs, num_workers, and vector_length clauses may
504 // follow a device_type clause.
505 if (isOpenACCComputeDirectiveKind(NewClause.getDirectiveKind())) {
506 switch (NewClause.getClauseKind()) {
507 case OpenACCClauseKind::Async:
508 case OpenACCClauseKind::Wait:
509 case OpenACCClauseKind::NumGangs:
510 case OpenACCClauseKind::NumWorkers:
511 case OpenACCClauseKind::VectorLength:
512 return false;
513 default:
514 break;
515 }
516 } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Loop) {
517 // Implement check from OpenACC3.3: section 2.9:
518 // Only the collapse, gang, worker, vector, seq, independent, auto, and tile
519 // clauses may follow a device_type clause.
520 switch (NewClause.getClauseKind()) {
521 case OpenACCClauseKind::Collapse:
522 case OpenACCClauseKind::Gang:
523 case OpenACCClauseKind::Worker:
524 case OpenACCClauseKind::Vector:
525 case OpenACCClauseKind::Seq:
526 case OpenACCClauseKind::Independent:
527 case OpenACCClauseKind::Auto:
528 case OpenACCClauseKind::Tile:
529 return false;
530 default:
531 break;
532 }
533 } else if (isOpenACCCombinedDirectiveKind(NewClause.getDirectiveKind())) {
534 // This seems like it should be the union of 2.9 and 2.5.4 from above.
535 switch (NewClause.getClauseKind()) {
536 case OpenACCClauseKind::Async:
537 case OpenACCClauseKind::Wait:
538 case OpenACCClauseKind::NumGangs:
539 case OpenACCClauseKind::NumWorkers:
540 case OpenACCClauseKind::VectorLength:
541 case OpenACCClauseKind::Collapse:
542 case OpenACCClauseKind::Gang:
543 case OpenACCClauseKind::Worker:
544 case OpenACCClauseKind::Vector:
545 case OpenACCClauseKind::Seq:
546 case OpenACCClauseKind::Independent:
547 case OpenACCClauseKind::Auto:
548 case OpenACCClauseKind::Tile:
549 return false;
550 default:
551 break;
552 }
553 } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Data) {
554 // OpenACC3.3 section 2.6.5: Only the async and wait clauses may follow a
555 // device_type clause.
556 switch (NewClause.getClauseKind()) {
557 case OpenACCClauseKind::Async:
558 case OpenACCClauseKind::Wait:
559 return false;
560 default:
561 break;
562 }
563 } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Set ||
564 NewClause.getDirectiveKind() == OpenACCDirectiveKind::Init ||
565 NewClause.getDirectiveKind() == OpenACCDirectiveKind::Shutdown) {
566 // There are no restrictions on 'set', 'init', or 'shutdown'.
567 return false;
568 } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Update) {
569 // OpenACC3.3 section 2.14.4: Only the async and wait clauses may follow a
570 // device_type clause.
571 switch (NewClause.getClauseKind()) {
572 case OpenACCClauseKind::Async:
573 case OpenACCClauseKind::Wait:
574 return false;
575 default:
576 break;
577 }
578 }
579 S.Diag(NewClause.getBeginLoc(), diag::err_acc_clause_after_device_type)
580 << NewClause.getClauseKind() << DeviceTypeClause.getClauseKind()
581 << NewClause.getDirectiveKind();
582 S.Diag(DeviceTypeClause.getBeginLoc(), diag::note_acc_previous_clause_here);
583 return true;
584}
585
586// A temporary function that helps implement the 'not implemented' check at the
587// top of each clause checking function. This should only be used in conjunction
588// with the one being currently implemented/only updated after the entire
589// construct has been implemented.
590bool isDirectiveKindImplemented(OpenACCDirectiveKind DK) {
591 return DK != OpenACCDirectiveKind::Declare &&
592 DK != OpenACCDirectiveKind::Routine;
593}
594
595class SemaOpenACCClauseVisitor {
596 SemaOpenACC &SemaRef;
597 ASTContext &Ctx;
598 ArrayRef<const OpenACCClause *> ExistingClauses;
599 bool NotImplemented = false;
600
601 OpenACCClause *isNotImplemented() {
602 NotImplemented = true;
603 return nullptr;
604 }
605
606 // OpenACC 3.3 2.9:
607 // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' clause
608 // appears.
609 bool DiagIfSeqClause(SemaOpenACC::OpenACCParsedClause &Clause) {
610 const auto *Itr =
611 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSeqClause>);
612
613 if (Itr != ExistingClauses.end()) {
614 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine)
615 << Clause.getClauseKind() << (*Itr)->getClauseKind()
616 << Clause.getDirectiveKind();
617 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
618
619 return true;
620 }
621 return false;
622 }
623
624public:
625 SemaOpenACCClauseVisitor(SemaOpenACC &S,
626 ArrayRef<const OpenACCClause *> ExistingClauses)
627 : SemaRef(S), Ctx(S.getASTContext()), ExistingClauses(ExistingClauses) {}
628 // Once we've implemented everything, we shouldn't need this infrastructure.
629 // But in the meantime, we use this to help decide whether the clause was
630 // handled for this directive.
631 bool diagNotImplemented() { return NotImplemented; }
632
634 switch (Clause.getClauseKind()) {
635#define VISIT_CLAUSE(CLAUSE_NAME) \
636 case OpenACCClauseKind::CLAUSE_NAME: \
637 return Visit##CLAUSE_NAME##Clause(Clause);
638#define CLAUSE_ALIAS(ALIAS, CLAUSE_NAME, DEPRECATED) \
639 case OpenACCClauseKind::ALIAS: \
640 if (DEPRECATED) \
641 SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name) \
642 << Clause.getClauseKind() << OpenACCClauseKind::CLAUSE_NAME; \
643 return Visit##CLAUSE_NAME##Clause(Clause);
644#include "clang/Basic/OpenACCClauses.def"
645 default:
646 return isNotImplemented();
647 }
648 llvm_unreachable("Invalid clause kind");
649 }
650
651#define VISIT_CLAUSE(CLAUSE_NAME) \
652 OpenACCClause *Visit##CLAUSE_NAME##Clause( \
653 SemaOpenACC::OpenACCParsedClause &Clause);
654#include "clang/Basic/OpenACCClauses.def"
655};
656
657OpenACCClause *SemaOpenACCClauseVisitor::VisitDefaultClause(
659 // Don't add an invalid clause to the AST.
660 if (Clause.getDefaultClauseKind() == OpenACCDefaultClauseKind::Invalid)
661 return nullptr;
662
663 // OpenACC 3.3, Section 2.5.4:
664 // At most one 'default' clause may appear, and it must have a value of
665 // either 'none' or 'present'.
666 // Second half of the sentence is diagnosed during parsing.
667 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
668 return nullptr;
669
671 Ctx, Clause.getDefaultClauseKind(), Clause.getBeginLoc(),
672 Clause.getLParenLoc(), Clause.getEndLoc());
673}
674
675OpenACCClause *SemaOpenACCClauseVisitor::VisitTileClause(
677
678 // Duplicates here are not really sensible. We could possible permit
679 // multiples if they all had the same value, but there isn't really a good
680 // reason to do so. Also, this simplifies the suppression of duplicates, in
681 // that we know if we 'find' one after instantiation, that it is the same
682 // clause, which simplifies instantiation/checking/etc.
683 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
684 return nullptr;
685
686 llvm::SmallVector<Expr *> NewSizeExprs;
687
688 // Make sure these are all positive constant expressions or *.
689 for (Expr *E : Clause.getIntExprs()) {
690 ExprResult Res = SemaRef.CheckTileSizeExpr(E);
691
692 if (!Res.isUsable())
693 return nullptr;
694
695 NewSizeExprs.push_back(Res.get());
696 }
697
698 return OpenACCTileClause::Create(Ctx, Clause.getBeginLoc(),
699 Clause.getLParenLoc(), NewSizeExprs,
700 Clause.getEndLoc());
701}
702
703OpenACCClause *SemaOpenACCClauseVisitor::VisitIfClause(
705 // There is no prose in the standard that says duplicates aren't allowed,
706 // but this diagnostic is present in other compilers, as well as makes
707 // sense. Prose DOES exist for 'data' and 'host_data', 'set', 'enter data' and
708 // 'exit data' both don't, but other implmementations do this. OpenACC issue
709 // 519 filed for the latter two. Prose also exists for 'update'.
710 // GCC allows this on init/shutdown, presumably for good reason, so we do too.
711 if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Init &&
712 Clause.getDirectiveKind() != OpenACCDirectiveKind::Shutdown &&
713 checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
714 return nullptr;
715
716 // The parser has ensured that we have a proper condition expr, so there
717 // isn't really much to do here.
718
719 // If the 'if' clause is true, it makes the 'self' clause have no effect,
720 // diagnose that here. This only applies on compute/combined constructs.
721 if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Update) {
722 const auto *Itr =
723 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSelfClause>);
724 if (Itr != ExistingClauses.end()) {
725 SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict);
726 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
727 }
728 }
729
730 return OpenACCIfClause::Create(Ctx, Clause.getBeginLoc(),
731 Clause.getLParenLoc(),
732 Clause.getConditionExpr(), Clause.getEndLoc());
733}
734
735OpenACCClause *SemaOpenACCClauseVisitor::VisitSelfClause(
737 // There is no prose in the standard that says duplicates aren't allowed,
738 // but this diagnostic is present in other compilers, as well as makes
739 // sense.
740 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
741 return nullptr;
742
743 // If the 'if' clause is true, it makes the 'self' clause have no effect,
744 // diagnose that here. This only applies on compute/combined constructs.
745 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Update)
746 return OpenACCSelfClause::Create(Ctx, Clause.getBeginLoc(),
747 Clause.getLParenLoc(), Clause.getVarList(),
748 Clause.getEndLoc());
749
750 const auto *Itr =
751 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCIfClause>);
752 if (Itr != ExistingClauses.end()) {
753 SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict);
754 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
755 }
757 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(),
758 Clause.getConditionExpr(), Clause.getEndLoc());
759}
760
761OpenACCClause *SemaOpenACCClauseVisitor::VisitNumGangsClause(
763 // There is no prose in the standard that says duplicates aren't allowed,
764 // but this diagnostic is present in other compilers, as well as makes
765 // sense.
766 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
767 return nullptr;
768
769 // num_gangs requires at least 1 int expr in all forms. Diagnose here, but
770 // allow us to continue, an empty clause might be useful for future
771 // diagnostics.
772 if (Clause.getIntExprs().empty())
773 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args)
774 << /*NoArgs=*/0;
775
776 unsigned MaxArgs =
777 (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel ||
778 Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop)
779 ? 3
780 : 1;
781 // The max number of args differs between parallel and other constructs.
782 // Again, allow us to continue for the purposes of future diagnostics.
783 if (Clause.getIntExprs().size() > MaxArgs)
784 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args)
785 << /*NoArgs=*/1 << Clause.getDirectiveKind() << MaxArgs
786 << Clause.getIntExprs().size();
787
788 // OpenACC 3.3 Section 2.9.11: A reduction clause may not appear on a loop
789 // directive that has a gang clause and is within a compute construct that has
790 // a num_gangs clause with more than one explicit argument.
791 if (Clause.getIntExprs().size() > 1 &&
793 auto *GangClauseItr =
794 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCGangClause>);
795 auto *ReductionClauseItr =
796 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>);
797
798 if (GangClauseItr != ExistingClauses.end() &&
799 ReductionClauseItr != ExistingClauses.end()) {
800 SemaRef.Diag(Clause.getBeginLoc(),
801 diag::err_acc_gang_reduction_numgangs_conflict)
802 << OpenACCClauseKind::Reduction << OpenACCClauseKind::Gang
803 << Clause.getDirectiveKind() << /*is on combined directive=*/1;
804 SemaRef.Diag((*ReductionClauseItr)->getBeginLoc(),
805 diag::note_acc_previous_clause_here);
806 SemaRef.Diag((*GangClauseItr)->getBeginLoc(),
807 diag::note_acc_previous_clause_here);
808 return nullptr;
809 }
810 }
811
812 // OpenACC 3.3 Section 2.5.4:
813 // A reduction clause may not appear on a parallel construct with a
814 // num_gangs clause that has more than one argument.
815 if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel ||
816 Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop) &&
817 Clause.getIntExprs().size() > 1) {
818 auto *Parallel =
819 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>);
820
821 if (Parallel != ExistingClauses.end()) {
822 SemaRef.Diag(Clause.getBeginLoc(),
823 diag::err_acc_reduction_num_gangs_conflict)
824 << /*>1 arg in first loc=*/1 << Clause.getClauseKind()
825 << Clause.getDirectiveKind() << OpenACCClauseKind::Reduction;
826 SemaRef.Diag((*Parallel)->getBeginLoc(),
827 diag::note_acc_previous_clause_here);
828 return nullptr;
829 }
830 }
831
832 // OpenACC 3.3 Section 2.9.2:
833 // An argument with no keyword or with the 'num' keyword is allowed only when
834 // the 'num_gangs' does not appear on the 'kernel' construct.
835 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) {
836 auto GangClauses = llvm::make_filter_range(
837 ExistingClauses, llvm::IsaPred<OpenACCGangClause>);
838
839 for (auto *GC : GangClauses) {
840 if (cast<OpenACCGangClause>(GC)->hasExprOfKind(OpenACCGangKind::Num)) {
841 SemaRef.Diag(Clause.getBeginLoc(),
842 diag::err_acc_num_arg_conflict_reverse)
843 << OpenACCClauseKind::NumGangs << OpenACCClauseKind::Gang
844 << /*Num argument*/ 1;
845 SemaRef.Diag(GC->getBeginLoc(), diag::note_acc_previous_clause_here);
846 return nullptr;
847 }
848 }
849 }
850
852 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs(),
853 Clause.getEndLoc());
854}
855
856OpenACCClause *SemaOpenACCClauseVisitor::VisitNumWorkersClause(
858 // There is no prose in the standard that says duplicates aren't allowed,
859 // but this diagnostic is present in other compilers, as well as makes
860 // sense.
861 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
862 return nullptr;
863
864 // OpenACC 3.3 Section 2.9.2:
865 // An argument is allowed only when the 'num_workers' does not appear on the
866 // kernels construct.
867 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) {
868 auto WorkerClauses = llvm::make_filter_range(
869 ExistingClauses, llvm::IsaPred<OpenACCWorkerClause>);
870
871 for (auto *WC : WorkerClauses) {
872 if (cast<OpenACCWorkerClause>(WC)->hasIntExpr()) {
873 SemaRef.Diag(Clause.getBeginLoc(),
874 diag::err_acc_num_arg_conflict_reverse)
875 << OpenACCClauseKind::NumWorkers << OpenACCClauseKind::Worker
876 << /*num argument*/ 0;
877 SemaRef.Diag(WC->getBeginLoc(), diag::note_acc_previous_clause_here);
878 return nullptr;
879 }
880 }
881 }
882
883 assert(Clause.getIntExprs().size() == 1 &&
884 "Invalid number of expressions for NumWorkers");
886 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0],
887 Clause.getEndLoc());
888}
889
890OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorLengthClause(
892 // There is no prose in the standard that says duplicates aren't allowed,
893 // but this diagnostic is present in other compilers, as well as makes
894 // sense.
895 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
896 return nullptr;
897
898 // OpenACC 3.3 Section 2.9.4:
899 // An argument is allowed only when the 'vector_length' does not appear on the
900 // 'kernels' construct.
901 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) {
902 auto VectorClauses = llvm::make_filter_range(
903 ExistingClauses, llvm::IsaPred<OpenACCVectorClause>);
904
905 for (auto *VC : VectorClauses) {
906 if (cast<OpenACCVectorClause>(VC)->hasIntExpr()) {
907 SemaRef.Diag(Clause.getBeginLoc(),
908 diag::err_acc_num_arg_conflict_reverse)
909 << OpenACCClauseKind::VectorLength << OpenACCClauseKind::Vector
910 << /*num argument*/ 0;
911 SemaRef.Diag(VC->getBeginLoc(), diag::note_acc_previous_clause_here);
912 return nullptr;
913 }
914 }
915 }
916
917 assert(Clause.getIntExprs().size() == 1 &&
918 "Invalid number of expressions for NumWorkers");
920 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0],
921 Clause.getEndLoc());
922}
923
924OpenACCClause *SemaOpenACCClauseVisitor::VisitAsyncClause(
926 // There is no prose in the standard that says duplicates aren't allowed,
927 // but this diagnostic is present in other compilers, as well as makes
928 // sense.
929 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
930 return nullptr;
931
932 assert(Clause.getNumIntExprs() < 2 &&
933 "Invalid number of expressions for Async");
935 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(),
936 Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr,
937 Clause.getEndLoc());
938}
939
940OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceNumClause(
942 // Restrictions only properly implemented on certain constructs, so skip/treat
943 // as unimplemented in those cases.
944 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
945 return isNotImplemented();
946
947 // OpenACC 3.3 2.14.3: Two instances of the same clause may not appear on the
948 // same directive.
949 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Set &&
950 checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
951 return nullptr;
952
953 assert(Clause.getNumIntExprs() == 1 &&
954 "Invalid number of expressions for device_num");
956 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0],
957 Clause.getEndLoc());
958}
959
960OpenACCClause *SemaOpenACCClauseVisitor::VisitDefaultAsyncClause(
962 // OpenACC 3.3 2.14.3: Two instances of the same clause may not appear on the
963 // same directive.
964 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
965 return nullptr;
966
967 assert(Clause.getNumIntExprs() == 1 &&
968 "Invalid number of expressions for default_async");
970 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0],
971 Clause.getEndLoc());
972}
973
974OpenACCClause *SemaOpenACCClauseVisitor::VisitPrivateClause(
976 // ActOnVar ensured that everything is a valid variable reference, so there
977 // really isn't anything to do here. GCC does some duplicate-finding, though
978 // it isn't apparent in the standard where this is justified.
979
980 return OpenACCPrivateClause::Create(Ctx, Clause.getBeginLoc(),
981 Clause.getLParenLoc(),
982 Clause.getVarList(), Clause.getEndLoc());
983}
984
985OpenACCClause *SemaOpenACCClauseVisitor::VisitFirstPrivateClause(
987 // ActOnVar ensured that everything is a valid variable reference, so there
988 // really isn't anything to do here. GCC does some duplicate-finding, though
989 // it isn't apparent in the standard where this is justified.
990
992 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(),
993 Clause.getEndLoc());
994}
995
996OpenACCClause *SemaOpenACCClauseVisitor::VisitNoCreateClause(
998 // ActOnVar ensured that everything is a valid variable reference, so there
999 // really isn't anything to do here. GCC does some duplicate-finding, though
1000 // it isn't apparent in the standard where this is justified.
1001
1002 return OpenACCNoCreateClause::Create(Ctx, Clause.getBeginLoc(),
1003 Clause.getLParenLoc(),
1004 Clause.getVarList(), Clause.getEndLoc());
1005}
1006
1007OpenACCClause *SemaOpenACCClauseVisitor::VisitPresentClause(
1009 // Restrictions only properly implemented on 'compute'/'combined'/'data'
1010 // constructs, and 'compute'/'combined'/'data' constructs are the only
1011 // construct that can do anything with this yet, so skip/treat as
1012 // unimplemented in this case.
1013 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1014 return isNotImplemented();
1015 // ActOnVar ensured that everything is a valid variable reference, so there
1016 // really isn't anything to do here. GCC does some duplicate-finding, though
1017 // it isn't apparent in the standard where this is justified.
1018
1019 return OpenACCPresentClause::Create(Ctx, Clause.getBeginLoc(),
1020 Clause.getLParenLoc(),
1021 Clause.getVarList(), Clause.getEndLoc());
1022}
1023
1024OpenACCClause *SemaOpenACCClauseVisitor::VisitHostClause(
1026 // ActOnVar ensured that everything is a valid variable reference, so there
1027 // really isn't anything to do here. GCC does some duplicate-finding, though
1028 // it isn't apparent in the standard where this is justified.
1029
1030 return OpenACCHostClause::Create(Ctx, Clause.getBeginLoc(),
1031 Clause.getLParenLoc(), Clause.getVarList(),
1032 Clause.getEndLoc());
1033}
1034
1035OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceClause(
1037 // ActOnVar ensured that everything is a valid variable reference, so there
1038 // really isn't anything to do here. GCC does some duplicate-finding, though
1039 // it isn't apparent in the standard where this is justified.
1040
1041 return OpenACCDeviceClause::Create(Ctx, Clause.getBeginLoc(),
1042 Clause.getLParenLoc(), Clause.getVarList(),
1043 Clause.getEndLoc());
1044}
1045
1046OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyClause(
1048 // Restrictions only properly implemented on 'compute'/'combined'/'data'
1049 // constructs, and 'compute'/'combined'/'data' constructs are the only
1050 // construct that can do anything with this yet, so skip/treat as
1051 // unimplemented in this case.
1052 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1053 return isNotImplemented();
1054 // ActOnVar ensured that everything is a valid variable reference, so there
1055 // really isn't anything to do here. GCC does some duplicate-finding, though
1056 // it isn't apparent in the standard where this is justified.
1057
1059 Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
1060 Clause.getVarList(), Clause.getEndLoc());
1061}
1062
1063OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyInClause(
1065 // Restrictions only properly implemented on 'compute'/'combined'/'data'
1066 // constructs, and 'compute'/'combined'/'data' constructs are the only
1067 // construct that can do anything with this yet, so skip/treat as
1068 // unimplemented in this case.
1069 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1070 return isNotImplemented();
1071 // ActOnVar ensured that everything is a valid variable reference, so there
1072 // really isn't anything to do here. GCC does some duplicate-finding, though
1073 // it isn't apparent in the standard where this is justified.
1074
1076 Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
1077 Clause.isReadOnly(), Clause.getVarList(), Clause.getEndLoc());
1078}
1079
1080OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyOutClause(
1082 // Restrictions only properly implemented on 'compute'/'combined'/'data'
1083 // constructs, and 'compute'/'combined'/'data' constructs are the only
1084 // construct that can do anything with this yet, so skip/treat as
1085 // unimplemented in this case.
1086 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1087 return isNotImplemented();
1088 // ActOnVar ensured that everything is a valid variable reference, so there
1089 // really isn't anything to do here. GCC does some duplicate-finding, though
1090 // it isn't apparent in the standard where this is justified.
1091
1093 Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
1094 Clause.isZero(), Clause.getVarList(), Clause.getEndLoc());
1095}
1096
1097OpenACCClause *SemaOpenACCClauseVisitor::VisitCreateClause(
1099 // ActOnVar ensured that everything is a valid variable reference, so there
1100 // really isn't anything to do here. GCC does some duplicate-finding, though
1101 // it isn't apparent in the standard where this is justified.
1102
1104 Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
1105 Clause.isZero(), Clause.getVarList(), Clause.getEndLoc());
1106}
1107
1108OpenACCClause *SemaOpenACCClauseVisitor::VisitAttachClause(
1110 // ActOnVar ensured that everything is a valid variable reference, but we
1111 // still have to make sure it is a pointer type.
1112 llvm::SmallVector<Expr *> VarList{Clause.getVarList()};
1113 llvm::erase_if(VarList, [&](Expr *E) {
1114 return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::Attach, E);
1115 });
1116 Clause.setVarListDetails(VarList,
1117 /*IsReadOnly=*/false, /*IsZero=*/false);
1118 return OpenACCAttachClause::Create(Ctx, Clause.getBeginLoc(),
1119 Clause.getLParenLoc(), Clause.getVarList(),
1120 Clause.getEndLoc());
1121}
1122
1123OpenACCClause *SemaOpenACCClauseVisitor::VisitDetachClause(
1125 // ActOnVar ensured that everything is a valid variable reference, but we
1126 // still have to make sure it is a pointer type.
1127 llvm::SmallVector<Expr *> VarList{Clause.getVarList()};
1128 llvm::erase_if(VarList, [&](Expr *E) {
1129 return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::Detach, E);
1130 });
1131 Clause.setVarListDetails(VarList,
1132 /*IsReadOnly=*/false, /*IsZero=*/false);
1133 return OpenACCDetachClause::Create(Ctx, Clause.getBeginLoc(),
1134 Clause.getLParenLoc(), Clause.getVarList(),
1135 Clause.getEndLoc());
1136}
1137
1138OpenACCClause *SemaOpenACCClauseVisitor::VisitDeleteClause(
1140 // ActOnVar ensured that everything is a valid variable reference, so there
1141 // really isn't anything to do here. GCC does some duplicate-finding, though
1142 // it isn't apparent in the standard where this is justified.
1143 return OpenACCDeleteClause::Create(Ctx, Clause.getBeginLoc(),
1144 Clause.getLParenLoc(), Clause.getVarList(),
1145 Clause.getEndLoc());
1146}
1147
1148OpenACCClause *SemaOpenACCClauseVisitor::VisitUseDeviceClause(
1150 // ActOnVar ensured that everything is a valid variable or array, so nothing
1151 // left to do here.
1153 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(),
1154 Clause.getEndLoc());
1155}
1156
1157OpenACCClause *SemaOpenACCClauseVisitor::VisitDevicePtrClause(
1159 // Restrictions only properly implemented on 'compute'/'combined'/'data'
1160 // constructs, and 'compute'/'combined'/'data' constructs are the only
1161 // construct that can do anything with this yet, so skip/treat as
1162 // unimplemented in this case.
1163 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1164 return isNotImplemented();
1165
1166 // ActOnVar ensured that everything is a valid variable reference, but we
1167 // still have to make sure it is a pointer type.
1168 llvm::SmallVector<Expr *> VarList{Clause.getVarList()};
1169 llvm::erase_if(VarList, [&](Expr *E) {
1170 return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::DevicePtr, E);
1171 });
1172 Clause.setVarListDetails(VarList,
1173 /*IsReadOnly=*/false, /*IsZero=*/false);
1174
1176 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(),
1177 Clause.getEndLoc());
1178}
1179
1180OpenACCClause *SemaOpenACCClauseVisitor::VisitWaitClause(
1183 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getDevNumExpr(),
1184 Clause.getQueuesLoc(), Clause.getQueueIdExprs(), Clause.getEndLoc());
1185}
1186
1187OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceTypeClause(
1189 // Restrictions implemented properly on everything except 'routine'.
1190 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Routine)
1191 return isNotImplemented();
1192
1193 // OpenACC 3.3 2.14.3: Two instances of the same clause may not appear on the
1194 // same directive.
1195 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Set &&
1196 checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
1197 return nullptr;
1198
1199 // TODO OpenACC: Once we get enough of the CodeGen implemented that we have
1200 // a source for the list of valid architectures, we need to warn on unknown
1201 // identifiers here.
1202
1204 Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
1205 Clause.getDeviceTypeArchitectures(), Clause.getEndLoc());
1206}
1207
1208OpenACCClause *SemaOpenACCClauseVisitor::VisitAutoClause(
1210 // OpenACC 3.3 2.9:
1211 // Only one of the seq, independent, and auto clauses may appear.
1212 const auto *Itr =
1213 llvm::find_if(ExistingClauses,
1214 llvm::IsaPred<OpenACCIndependentClause, OpenACCSeqClause>);
1215 if (Itr != ExistingClauses.end()) {
1216 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict)
1217 << Clause.getClauseKind() << Clause.getDirectiveKind();
1218 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1219 return nullptr;
1220 }
1221
1222 return OpenACCAutoClause::Create(Ctx, Clause.getBeginLoc(),
1223 Clause.getEndLoc());
1224}
1225
1226OpenACCClause *SemaOpenACCClauseVisitor::VisitIndependentClause(
1228 // OpenACC 3.3 2.9:
1229 // Only one of the seq, independent, and auto clauses may appear.
1230 const auto *Itr = llvm::find_if(
1231 ExistingClauses, llvm::IsaPred<OpenACCAutoClause, OpenACCSeqClause>);
1232 if (Itr != ExistingClauses.end()) {
1233 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict)
1234 << Clause.getClauseKind() << Clause.getDirectiveKind();
1235 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1236 return nullptr;
1237 }
1238
1239 return OpenACCIndependentClause::Create(Ctx, Clause.getBeginLoc(),
1240 Clause.getEndLoc());
1241}
1242
1243ExprResult CheckGangStaticExpr(SemaOpenACC &S, Expr *E) {
1244 if (isa<OpenACCAsteriskSizeExpr>(E))
1245 return E;
1246 return S.ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Gang,
1247 E->getBeginLoc(), E);
1248}
1249
1250bool IsOrphanLoop(OpenACCDirectiveKind DK, OpenACCDirectiveKind AssocKind) {
1251 return DK == OpenACCDirectiveKind::Loop &&
1252 AssocKind == OpenACCDirectiveKind::Invalid;
1253}
1254
1255bool HasAssocKind(OpenACCDirectiveKind DK, OpenACCDirectiveKind AssocKind) {
1256 return DK == OpenACCDirectiveKind::Loop &&
1257 AssocKind != OpenACCDirectiveKind::Invalid;
1258}
1259
1260ExprResult DiagIntArgInvalid(SemaOpenACC &S, Expr *E, OpenACCGangKind GK,
1262 OpenACCDirectiveKind AssocKind) {
1263 S.Diag(E->getBeginLoc(), diag::err_acc_int_arg_invalid)
1264 << GK << CK << IsOrphanLoop(DK, AssocKind) << DK
1265 << HasAssocKind(DK, AssocKind) << AssocKind;
1266 return ExprError();
1267}
1268ExprResult DiagIntArgInvalid(SemaOpenACC &S, Expr *E, StringRef TagKind,
1270 OpenACCDirectiveKind AssocKind) {
1271 S.Diag(E->getBeginLoc(), diag::err_acc_int_arg_invalid)
1272 << TagKind << CK << IsOrphanLoop(DK, AssocKind) << DK
1273 << HasAssocKind(DK, AssocKind) << AssocKind;
1274 return ExprError();
1275}
1276
1277ExprResult CheckGangParallelExpr(SemaOpenACC &S, OpenACCDirectiveKind DK,
1278 OpenACCDirectiveKind AssocKind,
1279 OpenACCGangKind GK, Expr *E) {
1280 switch (GK) {
1281 case OpenACCGangKind::Static:
1282 return CheckGangStaticExpr(S, E);
1283 case OpenACCGangKind::Num:
1284 // OpenACC 3.3 2.9.2: When the parent compute construct is a parallel
1285 // construct, or an orphaned loop construct, the gang clause behaves as
1286 // follows. ... The num argument is not allowed.
1287 return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind);
1288 case OpenACCGangKind::Dim: {
1289 // OpenACC 3.3 2.9.2: When the parent compute construct is a parallel
1290 // construct, or an orphaned loop construct, the gang clause behaves as
1291 // follows. ... The dim argument must be a constant positive integer value
1292 // 1, 2, or 3.
1293 if (!E)
1294 return ExprError();
1295 ExprResult Res =
1296 S.ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Gang,
1297 E->getBeginLoc(), E);
1298
1299 if (!Res.isUsable())
1300 return Res;
1301
1302 if (Res.get()->isInstantiationDependent())
1303 return Res;
1304
1305 std::optional<llvm::APSInt> ICE =
1307
1308 if (!ICE || *ICE <= 0 || ICE > 3) {
1309 S.Diag(Res.get()->getBeginLoc(), diag::err_acc_gang_dim_value)
1310 << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue();
1311 return ExprError();
1312 }
1313
1314 return ExprResult{
1315 ConstantExpr::Create(S.getASTContext(), Res.get(), APValue{*ICE})};
1316 }
1317 }
1318 llvm_unreachable("Unknown gang kind in gang parallel check");
1319}
1320
1321ExprResult CheckGangKernelsExpr(SemaOpenACC &S,
1322 ArrayRef<const OpenACCClause *> ExistingClauses,
1324 OpenACCDirectiveKind AssocKind,
1325 OpenACCGangKind GK, Expr *E) {
1326 switch (GK) {
1327 // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
1328 // construct, the gang clause behaves as follows. ... The dim argument is
1329 // not allowed.
1330 case OpenACCGangKind::Dim:
1331 return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind);
1332 case OpenACCGangKind::Num: {
1333 // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
1334 // construct, the gang clause behaves as follows. ... An argument with no
1335 // keyword or with num keyword is only allowed when num_gangs does not
1336 // appear on the kernels construct. ... The region of a loop with the gang
1337 // clause may not contain another loop with a gang clause unless within a
1338 // nested compute region.
1339
1340 // If this is a 'combined' construct, search the list of existing clauses.
1341 // Else we need to search the containing 'kernel'.
1342 auto Collection = isOpenACCCombinedDirectiveKind(DK)
1343 ? ExistingClauses
1344 : S.getActiveComputeConstructInfo().Clauses;
1345
1346 const auto *Itr =
1347 llvm::find_if(Collection, llvm::IsaPred<OpenACCNumGangsClause>);
1348
1349 if (Itr != Collection.end()) {
1350 S.Diag(E->getBeginLoc(), diag::err_acc_num_arg_conflict)
1351 << "num" << OpenACCClauseKind::Gang << DK
1352 << HasAssocKind(DK, AssocKind) << AssocKind
1353 << OpenACCClauseKind::NumGangs;
1354
1355 S.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1356 return ExprError();
1357 }
1358 return ExprResult{E};
1359 }
1360 case OpenACCGangKind::Static:
1361 return CheckGangStaticExpr(S, E);
1362 }
1363 llvm_unreachable("Unknown gang kind in gang kernels check");
1364}
1365
1366ExprResult CheckGangSerialExpr(SemaOpenACC &S, OpenACCDirectiveKind DK,
1367 OpenACCDirectiveKind AssocKind,
1368 OpenACCGangKind GK, Expr *E) {
1369 switch (GK) {
1370 // 'dim' and 'num' don't really make sense on serial, and GCC rejects them
1371 // too, so we disallow them too.
1372 case OpenACCGangKind::Dim:
1373 case OpenACCGangKind::Num:
1374 return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind);
1375 case OpenACCGangKind::Static:
1376 return CheckGangStaticExpr(S, E);
1377 }
1378 llvm_unreachable("Unknown gang kind in gang serial check");
1379}
1380
1381OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorClause(
1383 if (DiagIfSeqClause(Clause))
1384 return nullptr;
1385
1386 // Restrictions only properly implemented on 'loop'/'combined' constructs, and
1387 // it is the only construct that can do anything with this, so skip/treat as
1388 // unimplemented for the routine constructs.
1389 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1390 return isNotImplemented();
1391
1392 Expr *IntExpr =
1393 Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr;
1394 if (IntExpr) {
1396 switch (SemaRef.getActiveComputeConstructInfo().Kind) {
1397 case OpenACCDirectiveKind::Invalid:
1398 case OpenACCDirectiveKind::Parallel:
1399 // No restriction on when 'parallel' can contain an argument.
1400 break;
1401 case OpenACCDirectiveKind::Serial:
1402 // GCC disallows this, and there is no real good reason for us to permit
1403 // it, so disallow until we come up with a use case that makes sense.
1404 DiagIntArgInvalid(SemaRef, IntExpr, "length", OpenACCClauseKind::Vector,
1405 Clause.getDirectiveKind(),
1406 SemaRef.getActiveComputeConstructInfo().Kind);
1407 IntExpr = nullptr;
1408 break;
1409 case OpenACCDirectiveKind::Kernels: {
1410 const auto *Itr =
1411 llvm::find_if(SemaRef.getActiveComputeConstructInfo().Clauses,
1412 llvm::IsaPred<OpenACCVectorLengthClause>);
1413 if (Itr != SemaRef.getActiveComputeConstructInfo().Clauses.end()) {
1414 SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1415 << "length" << OpenACCClauseKind::Vector
1416 << Clause.getDirectiveKind()
1417 << HasAssocKind(Clause.getDirectiveKind(),
1418 SemaRef.getActiveComputeConstructInfo().Kind)
1419 << SemaRef.getActiveComputeConstructInfo().Kind
1420 << OpenACCClauseKind::VectorLength;
1421 SemaRef.Diag((*Itr)->getBeginLoc(),
1422 diag::note_acc_previous_clause_here);
1423
1424 IntExpr = nullptr;
1425 }
1426 break;
1427 }
1428 default:
1429 llvm_unreachable("Non compute construct in active compute construct");
1430 }
1431 } else {
1432 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::SerialLoop) {
1433 DiagIntArgInvalid(SemaRef, IntExpr, "length", OpenACCClauseKind::Vector,
1434 Clause.getDirectiveKind(),
1435 SemaRef.getActiveComputeConstructInfo().Kind);
1436 IntExpr = nullptr;
1437 } else if (Clause.getDirectiveKind() ==
1438 OpenACCDirectiveKind::KernelsLoop) {
1439 const auto *Itr = llvm::find_if(
1440 ExistingClauses, llvm::IsaPred<OpenACCVectorLengthClause>);
1441 if (Itr != ExistingClauses.end()) {
1442 SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1443 << "length" << OpenACCClauseKind::Vector
1444 << Clause.getDirectiveKind()
1445 << HasAssocKind(Clause.getDirectiveKind(),
1446 SemaRef.getActiveComputeConstructInfo().Kind)
1447 << SemaRef.getActiveComputeConstructInfo().Kind
1448 << OpenACCClauseKind::VectorLength;
1449 SemaRef.Diag((*Itr)->getBeginLoc(),
1450 diag::note_acc_previous_clause_here);
1451
1452 IntExpr = nullptr;
1453 }
1454 }
1455 }
1456 }
1457
1459 // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1460 // contain a loop with a gang, worker, or vector clause unless within a
1461 // nested compute region.
1462 if (SemaRef.LoopVectorClauseLoc.isValid()) {
1463 // This handles the 'inner loop' diagnostic, but we cannot set that we're
1464 // on one of these until we get to the end of the construct.
1465 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1466 << OpenACCClauseKind::Vector << OpenACCClauseKind::Vector
1467 << /*skip kernels construct info*/ 0;
1468 SemaRef.Diag(SemaRef.LoopVectorClauseLoc,
1469 diag::note_acc_previous_clause_here);
1470 return nullptr;
1471 }
1472 }
1473
1474 return OpenACCVectorClause::Create(Ctx, Clause.getBeginLoc(),
1475 Clause.getLParenLoc(), IntExpr,
1476 Clause.getEndLoc());
1477}
1478
1479OpenACCClause *SemaOpenACCClauseVisitor::VisitWorkerClause(
1481 if (DiagIfSeqClause(Clause))
1482 return nullptr;
1483
1484 // Restrictions only properly implemented on 'loop'/'combined' constructs, and
1485 // it is the only construct that can do anything with this, so skip/treat as
1486 // unimplemented for the routine constructs.
1487 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1488 return isNotImplemented();
1489
1490 Expr *IntExpr =
1491 Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr;
1492
1493 if (IntExpr) {
1495 switch (SemaRef.getActiveComputeConstructInfo().Kind) {
1496 case OpenACCDirectiveKind::Invalid:
1497 case OpenACCDirectiveKind::ParallelLoop:
1498 case OpenACCDirectiveKind::SerialLoop:
1499 case OpenACCDirectiveKind::Parallel:
1500 case OpenACCDirectiveKind::Serial:
1501 DiagIntArgInvalid(SemaRef, IntExpr, OpenACCGangKind::Num,
1502 OpenACCClauseKind::Worker, Clause.getDirectiveKind(),
1503 SemaRef.getActiveComputeConstructInfo().Kind);
1504 IntExpr = nullptr;
1505 break;
1506 case OpenACCDirectiveKind::KernelsLoop:
1507 case OpenACCDirectiveKind::Kernels: {
1508 const auto *Itr =
1509 llvm::find_if(SemaRef.getActiveComputeConstructInfo().Clauses,
1510 llvm::IsaPred<OpenACCNumWorkersClause>);
1511 if (Itr != SemaRef.getActiveComputeConstructInfo().Clauses.end()) {
1512 SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1513 << "num" << OpenACCClauseKind::Worker << Clause.getDirectiveKind()
1514 << HasAssocKind(Clause.getDirectiveKind(),
1515 SemaRef.getActiveComputeConstructInfo().Kind)
1516 << SemaRef.getActiveComputeConstructInfo().Kind
1517 << OpenACCClauseKind::NumWorkers;
1518 SemaRef.Diag((*Itr)->getBeginLoc(),
1519 diag::note_acc_previous_clause_here);
1520
1521 IntExpr = nullptr;
1522 }
1523 break;
1524 }
1525 default:
1526 llvm_unreachable("Non compute construct in active compute construct");
1527 }
1528 } else {
1529 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop ||
1530 Clause.getDirectiveKind() == OpenACCDirectiveKind::SerialLoop) {
1531 DiagIntArgInvalid(SemaRef, IntExpr, OpenACCGangKind::Num,
1532 OpenACCClauseKind::Worker, Clause.getDirectiveKind(),
1533 SemaRef.getActiveComputeConstructInfo().Kind);
1534 IntExpr = nullptr;
1535 } else {
1536 assert(Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop &&
1537 "Unknown combined directive kind?");
1538 const auto *Itr = llvm::find_if(ExistingClauses,
1539 llvm::IsaPred<OpenACCNumWorkersClause>);
1540 if (Itr != ExistingClauses.end()) {
1541 SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1542 << "num" << OpenACCClauseKind::Worker << Clause.getDirectiveKind()
1543 << HasAssocKind(Clause.getDirectiveKind(),
1544 SemaRef.getActiveComputeConstructInfo().Kind)
1545 << SemaRef.getActiveComputeConstructInfo().Kind
1546 << OpenACCClauseKind::NumWorkers;
1547 SemaRef.Diag((*Itr)->getBeginLoc(),
1548 diag::note_acc_previous_clause_here);
1549
1550 IntExpr = nullptr;
1551 }
1552 }
1553 }
1554 }
1555
1557 // OpenACC 3.3 2.9.3: The region of a loop with a 'worker' clause may not
1558 // contain a loop with a gang or worker clause unless within a nested
1559 // compute region.
1560 if (SemaRef.LoopWorkerClauseLoc.isValid()) {
1561 // This handles the 'inner loop' diagnostic, but we cannot set that we're
1562 // on one of these until we get to the end of the construct.
1563 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1564 << OpenACCClauseKind::Worker << OpenACCClauseKind::Worker
1565 << /*skip kernels construct info*/ 0;
1566 SemaRef.Diag(SemaRef.LoopWorkerClauseLoc,
1567 diag::note_acc_previous_clause_here);
1568 return nullptr;
1569 }
1570
1571 // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1572 // contain a loop with a gang, worker, or vector clause unless within a
1573 // nested compute region.
1574 if (SemaRef.LoopVectorClauseLoc.isValid()) {
1575 // This handles the 'inner loop' diagnostic, but we cannot set that we're
1576 // on one of these until we get to the end of the construct.
1577 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1578 << OpenACCClauseKind::Worker << OpenACCClauseKind::Vector
1579 << /*skip kernels construct info*/ 0;
1580 SemaRef.Diag(SemaRef.LoopVectorClauseLoc,
1581 diag::note_acc_previous_clause_here);
1582 return nullptr;
1583 }
1584 }
1585
1586 return OpenACCWorkerClause::Create(Ctx, Clause.getBeginLoc(),
1587 Clause.getLParenLoc(), IntExpr,
1588 Clause.getEndLoc());
1589}
1590
1591OpenACCClause *SemaOpenACCClauseVisitor::VisitGangClause(
1593 if (DiagIfSeqClause(Clause))
1594 return nullptr;
1595
1596 // Restrictions only properly implemented on 'loop' constructs, and it is
1597 // the only construct that can do anything with this, so skip/treat as
1598 // unimplemented for the combined constructs.
1599 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1600 return isNotImplemented();
1601
1602 // OpenACC 3.3 Section 2.9.11: A reduction clause may not appear on a loop
1603 // directive that has a gang clause and is within a compute construct that has
1604 // a num_gangs clause with more than one explicit argument.
1605 if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop &&
1606 SemaRef.getActiveComputeConstructInfo().Kind !=
1607 OpenACCDirectiveKind::Invalid) ||
1609 // num_gangs clause on the active compute construct.
1610 auto ActiveComputeConstructContainer =
1612 ? ExistingClauses
1613 : SemaRef.getActiveComputeConstructInfo().Clauses;
1614 auto *NumGangsClauseItr = llvm::find_if(
1615 ActiveComputeConstructContainer, llvm::IsaPred<OpenACCNumGangsClause>);
1616
1617 if (NumGangsClauseItr != ActiveComputeConstructContainer.end() &&
1618 cast<OpenACCNumGangsClause>(*NumGangsClauseItr)->getIntExprs().size() >
1619 1) {
1620 auto *ReductionClauseItr =
1621 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>);
1622
1623 if (ReductionClauseItr != ExistingClauses.end()) {
1624 SemaRef.Diag(Clause.getBeginLoc(),
1625 diag::err_acc_gang_reduction_numgangs_conflict)
1626 << OpenACCClauseKind::Gang << OpenACCClauseKind::Reduction
1627 << Clause.getDirectiveKind()
1629 SemaRef.Diag((*ReductionClauseItr)->getBeginLoc(),
1630 diag::note_acc_previous_clause_here);
1631 SemaRef.Diag((*NumGangsClauseItr)->getBeginLoc(),
1632 diag::note_acc_previous_clause_here);
1633 return nullptr;
1634 }
1635 }
1636 }
1637
1640
1641 // Store the existing locations, so we can do duplicate checking. Index is
1642 // the int-value of the OpenACCGangKind enum.
1643 SourceLocation ExistingElemLoc[3];
1644
1645 for (unsigned I = 0; I < Clause.getIntExprs().size(); ++I) {
1646 OpenACCGangKind GK = Clause.getGangKinds()[I];
1647 ExprResult ER =
1648 SemaRef.CheckGangExpr(ExistingClauses, Clause.getDirectiveKind(), GK,
1649 Clause.getIntExprs()[I]);
1650
1651 if (!ER.isUsable())
1652 continue;
1653
1654 // OpenACC 3.3 2.9: 'gang-arg-list' may have at most one num, one dim, and
1655 // one static argument.
1656 if (ExistingElemLoc[static_cast<unsigned>(GK)].isValid()) {
1657 SemaRef.Diag(ER.get()->getBeginLoc(), diag::err_acc_gang_multiple_elt)
1658 << static_cast<unsigned>(GK);
1659 SemaRef.Diag(ExistingElemLoc[static_cast<unsigned>(GK)],
1660 diag::note_acc_previous_expr_here);
1661 continue;
1662 }
1663
1664 ExistingElemLoc[static_cast<unsigned>(GK)] = ER.get()->getBeginLoc();
1665 GangKinds.push_back(GK);
1666 IntExprs.push_back(ER.get());
1667 }
1668
1670 // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
1671 // construct, the gang clause behaves as follows. ... The region of a loop
1672 // with a gang clause may not contain another loop with a gang clause unless
1673 // within a nested compute region.
1674 if (SemaRef.LoopGangClauseOnKernel.Loc.isValid()) {
1675 // This handles the 'inner loop' diagnostic, but we cannot set that we're
1676 // on one of these until we get to the end of the construct.
1677 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1678 << OpenACCClauseKind::Gang << OpenACCClauseKind::Gang
1679 << /*kernels construct info*/ 1
1681 SemaRef.Diag(SemaRef.LoopGangClauseOnKernel.Loc,
1682 diag::note_acc_previous_clause_here);
1683 return nullptr;
1684 }
1685
1686 // OpenACC 3.3 2.9.3: The region of a loop with a 'worker' clause may not
1687 // contain a loop with a gang or worker clause unless within a nested
1688 // compute region.
1689 if (SemaRef.LoopWorkerClauseLoc.isValid()) {
1690 // This handles the 'inner loop' diagnostic, but we cannot set that we're
1691 // on one of these until we get to the end of the construct.
1692 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1693 << OpenACCClauseKind::Gang << OpenACCClauseKind::Worker
1694 << /*!kernels construct info*/ 0;
1695 SemaRef.Diag(SemaRef.LoopWorkerClauseLoc,
1696 diag::note_acc_previous_clause_here);
1697 return nullptr;
1698 }
1699
1700 // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1701 // contain a loop with a gang, worker, or vector clause unless within a
1702 // nested compute region.
1703 if (SemaRef.LoopVectorClauseLoc.isValid()) {
1704 // This handles the 'inner loop' diagnostic, but we cannot set that we're
1705 // on one of these until we get to the end of the construct.
1706 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1707 << OpenACCClauseKind::Gang << OpenACCClauseKind::Vector
1708 << /*!kernels construct info*/ 0;
1709 SemaRef.Diag(SemaRef.LoopVectorClauseLoc,
1710 diag::note_acc_previous_clause_here);
1711 return nullptr;
1712 }
1713 }
1714
1715 return SemaRef.CheckGangClause(Clause.getDirectiveKind(), ExistingClauses,
1716 Clause.getBeginLoc(), Clause.getLParenLoc(),
1717 GangKinds, IntExprs, Clause.getEndLoc());
1718}
1719
1720OpenACCClause *SemaOpenACCClauseVisitor::VisitFinalizeClause(
1722 // There isn't anything to do here, this is only valid on one construct, and
1723 // has no associated rules.
1724 return OpenACCFinalizeClause::Create(Ctx, Clause.getBeginLoc(),
1725 Clause.getEndLoc());
1726}
1727
1728OpenACCClause *SemaOpenACCClauseVisitor::VisitIfPresentClause(
1730 // There isn't anything to do here, this is only valid on one construct, and
1731 // has no associated rules.
1732 return OpenACCIfPresentClause::Create(Ctx, Clause.getBeginLoc(),
1733 Clause.getEndLoc());
1734}
1735
1736OpenACCClause *SemaOpenACCClauseVisitor::VisitSeqClause(
1738 // Restrictions only properly implemented on 'loop' constructs and combined ,
1739 // and it is the only construct that can do anything with this, so skip/treat
1740 // as unimplemented for the routine constructs.
1741 if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1742 return isNotImplemented();
1743
1744 // OpenACC 3.3 2.9:
1745 // Only one of the seq, independent, and auto clauses may appear.
1746 const auto *Itr =
1747 llvm::find_if(ExistingClauses,
1748 llvm::IsaPred<OpenACCAutoClause, OpenACCIndependentClause>);
1749 if (Itr != ExistingClauses.end()) {
1750 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict)
1751 << Clause.getClauseKind() << Clause.getDirectiveKind();
1752 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1753 return nullptr;
1754 }
1755
1756 // OpenACC 3.3 2.9:
1757 // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' clause
1758 // appears.
1759 Itr = llvm::find_if(ExistingClauses,
1762
1763 if (Itr != ExistingClauses.end()) {
1764 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine)
1765 << Clause.getClauseKind() << (*Itr)->getClauseKind()
1766 << Clause.getDirectiveKind();
1767 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1768 return nullptr;
1769 }
1770
1771 return OpenACCSeqClause::Create(Ctx, Clause.getBeginLoc(),
1772 Clause.getEndLoc());
1773}
1774
1775OpenACCClause *SemaOpenACCClauseVisitor::VisitReductionClause(
1777 // OpenACC 3.3 Section 2.9.11: A reduction clause may not appear on a loop
1778 // directive that has a gang clause and is within a compute construct that has
1779 // a num_gangs clause with more than one explicit argument.
1780 if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop &&
1781 SemaRef.getActiveComputeConstructInfo().Kind !=
1782 OpenACCDirectiveKind::Invalid) ||
1784 // num_gangs clause on the active compute construct.
1785 auto ActiveComputeConstructContainer =
1787 ? ExistingClauses
1788 : SemaRef.getActiveComputeConstructInfo().Clauses;
1789 auto *NumGangsClauseItr = llvm::find_if(
1790 ActiveComputeConstructContainer, llvm::IsaPred<OpenACCNumGangsClause>);
1791
1792 if (NumGangsClauseItr != ActiveComputeConstructContainer.end() &&
1793 cast<OpenACCNumGangsClause>(*NumGangsClauseItr)->getIntExprs().size() >
1794 1) {
1795 auto *GangClauseItr =
1796 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCGangClause>);
1797
1798 if (GangClauseItr != ExistingClauses.end()) {
1799 SemaRef.Diag(Clause.getBeginLoc(),
1800 diag::err_acc_gang_reduction_numgangs_conflict)
1801 << OpenACCClauseKind::Reduction << OpenACCClauseKind::Gang
1802 << Clause.getDirectiveKind()
1804 SemaRef.Diag((*GangClauseItr)->getBeginLoc(),
1805 diag::note_acc_previous_clause_here);
1806 SemaRef.Diag((*NumGangsClauseItr)->getBeginLoc(),
1807 diag::note_acc_previous_clause_here);
1808 return nullptr;
1809 }
1810 }
1811 }
1812
1813 // OpenACC3.3 Section 2.9.11: If a variable is involved in a reduction that
1814 // spans multiple nested loops where two or more of those loops have
1815 // associated loop directives, a reduction clause containing that variable
1816 // must appear on each of those loop directives.
1817 //
1818 // This can't really be implemented in the CFE, as this requires a level of
1819 // rechability/useage analysis that we're not really wanting to get into.
1820 // Additionally, I'm alerted that this restriction is one that the middle-end
1821 // can just 'figure out' as an extension and isn't really necessary.
1822 //
1823 // OpenACC3.3 Section 2.9.11: Every 'var' in a reduction clause appearing on
1824 // an orphaned loop construct must be private.
1825 //
1826 // This again is something we cannot really diagnose, as it requires we see
1827 // all the uses/scopes of all variables referenced. The middle end/MLIR might
1828 // be able to diagnose this.
1829
1830 // OpenACC 3.3 Section 2.5.4:
1831 // A reduction clause may not appear on a parallel construct with a
1832 // num_gangs clause that has more than one argument.
1833 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel ||
1834 Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop) {
1835 auto NumGangsClauses = llvm::make_filter_range(
1836 ExistingClauses, llvm::IsaPred<OpenACCNumGangsClause>);
1837
1838 for (auto *NGC : NumGangsClauses) {
1839 unsigned NumExprs =
1840 cast<OpenACCNumGangsClause>(NGC)->getIntExprs().size();
1841
1842 if (NumExprs > 1) {
1843 SemaRef.Diag(Clause.getBeginLoc(),
1844 diag::err_acc_reduction_num_gangs_conflict)
1845 << /*>1 arg in first loc=*/0 << Clause.getClauseKind()
1846 << Clause.getDirectiveKind() << OpenACCClauseKind::NumGangs;
1847 SemaRef.Diag(NGC->getBeginLoc(), diag::note_acc_previous_clause_here);
1848 return nullptr;
1849 }
1850 }
1851 }
1852
1853 SmallVector<Expr *> ValidVars;
1854
1855 for (Expr *Var : Clause.getVarList()) {
1856 ExprResult Res = SemaRef.CheckReductionVar(Clause.getDirectiveKind(),
1857 Clause.getReductionOp(), Var);
1858
1859 if (Res.isUsable())
1860 ValidVars.push_back(Res.get());
1861 }
1862
1863 return SemaRef.CheckReductionClause(
1864 ExistingClauses, Clause.getDirectiveKind(), Clause.getBeginLoc(),
1865 Clause.getLParenLoc(), Clause.getReductionOp(), ValidVars,
1866 Clause.getEndLoc());
1867}
1868
1869OpenACCClause *SemaOpenACCClauseVisitor::VisitCollapseClause(
1871 // Duplicates here are not really sensible. We could possible permit
1872 // multiples if they all had the same value, but there isn't really a good
1873 // reason to do so. Also, this simplifies the suppression of duplicates, in
1874 // that we know if we 'find' one after instantiation, that it is the same
1875 // clause, which simplifies instantiation/checking/etc.
1876 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
1877 return nullptr;
1878
1879 ExprResult LoopCount = SemaRef.CheckCollapseLoopCount(Clause.getLoopCount());
1880
1881 if (!LoopCount.isUsable())
1882 return nullptr;
1883
1884 return OpenACCCollapseClause::Create(Ctx, Clause.getBeginLoc(),
1885 Clause.getLParenLoc(), Clause.isForce(),
1886 LoopCount.get(), Clause.getEndLoc());
1887}
1888
1889// Return true if the two vars refer to the same variable, for the purposes of
1890// equality checking.
1891bool areVarsEqual(Expr *VarExpr1, Expr *VarExpr2) {
1892 if (VarExpr1->isInstantiationDependent() ||
1893 VarExpr2->isInstantiationDependent())
1894 return false;
1895
1896 VarExpr1 = VarExpr1->IgnoreParenCasts();
1897 VarExpr2 = VarExpr2->IgnoreParenCasts();
1898
1899 // Legal expressions can be: Scalar variable reference, sub-array, array
1900 // element, or composite variable member.
1901
1902 // Sub-array.
1903 if (isa<ArraySectionExpr>(VarExpr1)) {
1904 auto *Expr2AS = dyn_cast<ArraySectionExpr>(VarExpr2);
1905 if (!Expr2AS)
1906 return false;
1907
1908 auto *Expr1AS = cast<ArraySectionExpr>(VarExpr1);
1909
1910 if (!areVarsEqual(Expr1AS->getBase(), Expr2AS->getBase()))
1911 return false;
1912 // We could possibly check to see if the ranges aren't overlapping, but it
1913 // isn't clear that the rules allow this.
1914 return true;
1915 }
1916
1917 // Array-element.
1918 if (isa<ArraySubscriptExpr>(VarExpr1)) {
1919 auto *Expr2AS = dyn_cast<ArraySubscriptExpr>(VarExpr2);
1920 if (!Expr2AS)
1921 return false;
1922
1923 auto *Expr1AS = cast<ArraySubscriptExpr>(VarExpr1);
1924
1925 if (!areVarsEqual(Expr1AS->getBase(), Expr2AS->getBase()))
1926 return false;
1927
1928 // We could possibly check to see if the elements referenced aren't the
1929 // same, but it isn't clear by reading of the standard that this is allowed
1930 // (and that the 'var' refered to isn't the array).
1931 return true;
1932 }
1933
1934 // Scalar variable reference, or composite variable.
1935 if (isa<DeclRefExpr>(VarExpr1)) {
1936 auto *Expr2DRE = dyn_cast<DeclRefExpr>(VarExpr2);
1937 if (!Expr2DRE)
1938 return false;
1939
1940 auto *Expr1DRE = cast<DeclRefExpr>(VarExpr1);
1941
1942 return Expr1DRE->getDecl()->getMostRecentDecl() ==
1943 Expr2DRE->getDecl()->getMostRecentDecl();
1944 }
1945
1946 llvm_unreachable("Unknown variable type encountered");
1947}
1948} // namespace
1949
1952 OpenACCParsedClause &Clause) {
1954 return nullptr;
1955
1956 // Diagnose that we don't support this clause on this directive.
1957 if (!doesClauseApplyToDirective(Clause.getDirectiveKind(),
1958 Clause.getClauseKind())) {
1959 Diag(Clause.getBeginLoc(), diag::err_acc_clause_appertainment)
1960 << Clause.getDirectiveKind() << Clause.getClauseKind();
1961 return nullptr;
1962 }
1963
1964 if (const auto *DevTypeClause =
1965 llvm::find_if(ExistingClauses,
1966 [&](const OpenACCClause *C) {
1967 return isa<OpenACCDeviceTypeClause>(C);
1968 });
1969 DevTypeClause != ExistingClauses.end()) {
1970 if (checkValidAfterDeviceType(
1971 *this, *cast<OpenACCDeviceTypeClause>(*DevTypeClause), Clause))
1972 return nullptr;
1973 }
1974
1975 SemaOpenACCClauseVisitor Visitor{*this, ExistingClauses};
1976 OpenACCClause *Result = Visitor.Visit(Clause);
1977 assert((!Result || Result->getClauseKind() == Clause.getClauseKind()) &&
1978 "Created wrong clause?");
1979
1980 if (Visitor.diagNotImplemented())
1981 Diag(Clause.getBeginLoc(), diag::warn_acc_clause_unimplemented)
1982 << Clause.getClauseKind();
1983
1984 return Result;
1985
1986}
1987
1988/// OpenACC 3.3 section 2.5.15:
1989/// At a mininmum, the supported data types include ... the numerical data types
1990/// in C, C++, and Fortran.
1991///
1992/// If the reduction var is a composite variable, each
1993/// member of the composite variable must be a supported datatype for the
1994/// reduction operation.
1996 OpenACCReductionOperator ReductionOp,
1997 Expr *VarExpr) {
1998 VarExpr = VarExpr->IgnoreParenCasts();
1999
2000 auto TypeIsValid = [](QualType Ty) {
2001 return Ty->isDependentType() || Ty->isScalarType();
2002 };
2003
2004 if (isa<ArraySectionExpr>(VarExpr)) {
2005 Expr *ASExpr = VarExpr;
2007 QualType EltTy = getASTContext().getBaseElementType(BaseTy);
2008
2009 if (!TypeIsValid(EltTy)) {
2010 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_type)
2011 << EltTy << /*Sub array base type*/ 1;
2012 return ExprError();
2013 }
2014 } else if (auto *RD = VarExpr->getType()->getAsRecordDecl()) {
2015 if (!RD->isStruct() && !RD->isClass()) {
2016 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type)
2017 << /*not class or struct*/ 0 << VarExpr->getType();
2018 return ExprError();
2019 }
2020
2021 if (!RD->isCompleteDefinition()) {
2022 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type)
2023 << /*incomplete*/ 1 << VarExpr->getType();
2024 return ExprError();
2025 }
2026 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
2027 CXXRD && !CXXRD->isAggregate()) {
2028 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type)
2029 << /*aggregate*/ 2 << VarExpr->getType();
2030 return ExprError();
2031 }
2032
2033 for (FieldDecl *FD : RD->fields()) {
2034 if (!TypeIsValid(FD->getType())) {
2035 Diag(VarExpr->getExprLoc(),
2036 diag::err_acc_reduction_composite_member_type);
2037 Diag(FD->getLocation(), diag::note_acc_reduction_composite_member_loc);
2038 return ExprError();
2039 }
2040 }
2041 } else if (!TypeIsValid(VarExpr->getType())) {
2042 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_type)
2043 << VarExpr->getType() << /*Sub array base type*/ 0;
2044 return ExprError();
2045 }
2046
2047 // OpenACC3.3: 2.9.11: Reduction clauses on nested constructs for the same
2048 // reduction 'var' must have the same reduction operator.
2049 if (!VarExpr->isInstantiationDependent()) {
2050
2051 for (const OpenACCReductionClause *RClause : ActiveReductionClauses) {
2052 if (RClause->getReductionOp() == ReductionOp)
2053 break;
2054
2055 for (Expr *OldVarExpr : RClause->getVarList()) {
2056 if (OldVarExpr->isInstantiationDependent())
2057 continue;
2058
2059 if (areVarsEqual(VarExpr, OldVarExpr)) {
2060 Diag(VarExpr->getExprLoc(), diag::err_reduction_op_mismatch)
2061 << ReductionOp << RClause->getReductionOp();
2062 Diag(OldVarExpr->getExprLoc(), diag::note_acc_previous_clause_here);
2063 return ExprError();
2064 }
2065 }
2066 }
2067 }
2068
2069 return VarExpr;
2070}
2071
2073 if (!SizeExpr)
2074 return ExprError();
2075
2076 assert((SizeExpr->isInstantiationDependent() ||
2077 SizeExpr->getType()->isIntegerType()) &&
2078 "size argument non integer?");
2079
2080 // If dependent, or an asterisk, the expression is fine.
2081 if (SizeExpr->isInstantiationDependent() ||
2082 isa<OpenACCAsteriskSizeExpr>(SizeExpr))
2083 return ExprResult{SizeExpr};
2084
2085 std::optional<llvm::APSInt> ICE =
2087
2088 // OpenACC 3.3 2.9.8
2089 // where each tile size is a constant positive integer expression or asterisk.
2090 if (!ICE || *ICE <= 0) {
2091 Diag(SizeExpr->getBeginLoc(), diag::err_acc_size_expr_value)
2092 << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue();
2093 return ExprError();
2094 }
2095
2096 return ExprResult{
2097 ConstantExpr::Create(getASTContext(), SizeExpr, APValue{*ICE})};
2098}
2099
2101 if (!LoopCount)
2102 return ExprError();
2103
2104 assert((LoopCount->isInstantiationDependent() ||
2105 LoopCount->getType()->isIntegerType()) &&
2106 "Loop argument non integer?");
2107
2108 // If this is dependent, there really isn't anything we can check.
2109 if (LoopCount->isInstantiationDependent())
2110 return ExprResult{LoopCount};
2111
2112 std::optional<llvm::APSInt> ICE =
2114
2115 // OpenACC 3.3: 2.9.1
2116 // The argument to the collapse clause must be a constant positive integer
2117 // expression.
2118 if (!ICE || *ICE <= 0) {
2119 Diag(LoopCount->getBeginLoc(), diag::err_acc_collapse_loop_count)
2120 << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue();
2121 return ExprError();
2122 }
2123
2124 return ExprResult{
2125 ConstantExpr::Create(getASTContext(), LoopCount, APValue{*ICE})};
2126}
2127
2131 Expr *E) {
2132 // There are two cases for the enforcement here: the 'current' directive is a
2133 // 'loop', where we need to check the active compute construct kind, or the
2134 // current directive is a 'combined' construct, where we have to check the
2135 // current one.
2136 switch (DK) {
2138 return CheckGangParallelExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK,
2139 E);
2141 return CheckGangSerialExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK,
2142 E);
2144 return CheckGangKernelsExpr(*this, ExistingClauses, DK,
2145 ActiveComputeConstructInfo.Kind, GK, E);
2147 switch (ActiveComputeConstructInfo.Kind) {
2151 return CheckGangParallelExpr(*this, DK, ActiveComputeConstructInfo.Kind,
2152 GK, E);
2155 return CheckGangSerialExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK,
2156 E);
2159 return CheckGangKernelsExpr(*this, ExistingClauses, DK,
2160 ActiveComputeConstructInfo.Kind, GK, E);
2161 default:
2162 llvm_unreachable("Non compute construct in active compute construct?");
2163 }
2164 default:
2165 // TODO: OpenACC: when we implement this on 'routine', we'll have to
2166 // implement its checking here.
2167 llvm_unreachable("Invalid directive kind for a Gang clause");
2168 }
2169 llvm_unreachable("Compute construct directive not handled?");
2170}
2171
2174 ArrayRef<const OpenACCClause *> ExistingClauses,
2175 SourceLocation BeginLoc, SourceLocation LParenLoc,
2176 ArrayRef<OpenACCGangKind> GangKinds,
2177 ArrayRef<Expr *> IntExprs, SourceLocation EndLoc) {
2178 // OpenACC 3.3 2.9.11: A reduction clause may not appear on a loop directive
2179 // that has a gang clause with a dim: argument whose value is greater than 1.
2180
2181 const auto *ReductionItr =
2182 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>);
2183
2184 if (ReductionItr != ExistingClauses.end()) {
2185 const auto GangZip = llvm::zip_equal(GangKinds, IntExprs);
2186 const auto GangItr = llvm::find_if(GangZip, [](const auto &Tuple) {
2187 return std::get<0>(Tuple) == OpenACCGangKind::Dim;
2188 });
2189
2190 if (GangItr != GangZip.end()) {
2191 const Expr *DimExpr = std::get<1>(*GangItr);
2192
2193 assert(
2194 (DimExpr->isInstantiationDependent() || isa<ConstantExpr>(DimExpr)) &&
2195 "Improperly formed gang argument");
2196 if (const auto *DimVal = dyn_cast<ConstantExpr>(DimExpr);
2197 DimVal && DimVal->getResultAsAPSInt() > 1) {
2198 Diag(DimVal->getBeginLoc(), diag::err_acc_gang_reduction_conflict)
2199 << /*gang/reduction=*/0 << DirKind;
2200 Diag((*ReductionItr)->getBeginLoc(),
2201 diag::note_acc_previous_clause_here);
2202 return nullptr;
2203 }
2204 }
2205 }
2206
2207 return OpenACCGangClause::Create(getASTContext(), BeginLoc, LParenLoc,
2208 GangKinds, IntExprs, EndLoc);
2209}
2210
2212 ArrayRef<const OpenACCClause *> ExistingClauses,
2213 OpenACCDirectiveKind DirectiveKind, SourceLocation BeginLoc,
2214 SourceLocation LParenLoc, OpenACCReductionOperator ReductionOp,
2215 ArrayRef<Expr *> Vars, SourceLocation EndLoc) {
2216 if (DirectiveKind == OpenACCDirectiveKind::Loop ||
2217 isOpenACCCombinedDirectiveKind(DirectiveKind)) {
2218 // OpenACC 3.3 2.9.11: A reduction clause may not appear on a loop directive
2219 // that has a gang clause with a dim: argument whose value is greater
2220 // than 1.
2221 const auto GangClauses = llvm::make_filter_range(
2222 ExistingClauses, llvm::IsaPred<OpenACCGangClause>);
2223
2224 for (auto *GC : GangClauses) {
2225 const auto *GangClause = cast<OpenACCGangClause>(GC);
2226 for (unsigned I = 0; I < GangClause->getNumExprs(); ++I) {
2227 std::pair<OpenACCGangKind, const Expr *> EPair = GangClause->getExpr(I);
2228 if (EPair.first != OpenACCGangKind::Dim)
2229 continue;
2230
2231 if (const auto *DimVal = dyn_cast<ConstantExpr>(EPair.second);
2232 DimVal && DimVal->getResultAsAPSInt() > 1) {
2233 Diag(BeginLoc, diag::err_acc_gang_reduction_conflict)
2234 << /*reduction/gang=*/1 << DirectiveKind;
2235 Diag(GangClause->getBeginLoc(), diag::note_acc_previous_clause_here);
2236 return nullptr;
2237 }
2238 }
2239 }
2240 }
2241
2243 getASTContext(), BeginLoc, LParenLoc, ReductionOp, Vars, EndLoc);
2244 return Ret;
2245}
Expr * E
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines some OpenACC-specific enums and functions.
This file declares semantic analysis for OpenACC constructs and clauses.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition: APValue.h:122
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
PtrTy get() const
Definition: Ownership.h:170
bool isUsable() const
Definition: Ownership.h:168
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
Definition: Expr.cpp:5186
static ConstantExpr * Create(const ASTContext &Context, Expr *E, const APValue &Result)
Definition: Expr.cpp:349
This represents one expression.
Definition: Expr.h:110
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Definition: Expr.cpp:3101
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:276
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
Represents a member of a struct/union/class.
Definition: Decl.h:3033
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
static OpenACCCollapseClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, bool HasForce, Expr *LoopCount, SourceLocation EndLoc)
static OpenACCCopyClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCCopyInClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsReadOnly, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCCopyOutClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsZero, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCCreateClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsZero, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCDefaultAsyncClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static OpenACCDefaultClause * Create(const ASTContext &C, OpenACCDefaultClauseKind K, SourceLocation BeginLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
static OpenACCDeleteClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCDetachClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCDeviceClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCDeviceNumClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static OpenACCDevicePtrClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
A 'device_type' or 'dtype' clause, takes a list of either an 'asterisk' or an identifier.
static OpenACCDeviceTypeClause * Create(const ASTContext &C, OpenACCClauseKind K, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< DeviceTypeArgument > Archs, SourceLocation EndLoc)
static OpenACCFinalizeClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)
static OpenACCFirstPrivateClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCGangClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< OpenACCGangKind > GangKinds, ArrayRef< Expr * > IntExprs, SourceLocation EndLoc)
static OpenACCHostClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCIfClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *ConditionExpr, SourceLocation EndLoc)
static OpenACCIfPresentClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)
static OpenACCIndependentClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)
static OpenACCNoCreateClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCNumGangsClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > IntExprs, SourceLocation EndLoc)
static OpenACCNumWorkersClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static OpenACCPresentClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCPrivateClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCReductionClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, OpenACCReductionOperator Operator, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCSelfClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *ConditionExpr, SourceLocation EndLoc)
static OpenACCSeqClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)
static OpenACCTileClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > SizeExprs, SourceLocation EndLoc)
static OpenACCUseDeviceClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCVectorClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static OpenACCVectorLengthClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static OpenACCWaitClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef< Expr * > QueueIdExprs, SourceLocation EndLoc)
static OpenACCWorkerClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
A (possibly-)qualified type.
Definition: Type.h:929
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: SemaBase.cpp:60
ASTContext & getASTContext() const
Definition: SemaBase.cpp:9
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
ComputeConstructInfo & getActiveComputeConstructInfo()
Definition: SemaOpenACC.h:162
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 CheckVarIsPointerType(OpenACCClauseKind ClauseKind, Expr *VarExpr)
Called to check the 'var' type is a variable of pointer type, necessary for 'deviceptr' and 'attach' ...
struct clang::SemaOpenACC::LoopGangOnKernelTy LoopGangClauseOnKernel
ExprResult CheckReductionVar(OpenACCDirectiveKind DirectiveKind, OpenACCReductionOperator ReductionOp, Expr *VarExpr)
Called while semantically analyzing the reduction clause, ensuring the var is the correct kind of ref...
ExprResult CheckCollapseLoopCount(Expr *LoopCount)
Checks the loop depth value for a collapse clause.
OpenACCClause * CheckReductionClause(ArrayRef< const OpenACCClause * > ExistingClauses, OpenACCDirectiveKind DirectiveKind, SourceLocation BeginLoc, SourceLocation LParenLoc, OpenACCReductionOperator ReductionOp, ArrayRef< Expr * > Vars, SourceLocation EndLoc)
SourceLocation LoopVectorClauseLoc
If there is a current 'active' loop construct with a 'vector' clause on it (on any sort of construct)...
Definition: SemaOpenACC.h:184
ExprResult CheckGangExpr(ArrayRef< const OpenACCClause * > ExistingClauses, OpenACCDirectiveKind DK, OpenACCGangKind GK, Expr *E)
OpenACCClause * CheckGangClause(OpenACCDirectiveKind DirKind, ArrayRef< const OpenACCClause * > ExistingClauses, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< OpenACCGangKind > GangKinds, ArrayRef< Expr * > IntExprs, SourceLocation EndLoc)
ExprResult CheckTileSizeExpr(Expr *SizeExpr)
Checks a single size expr for a tile clause.
ASTContext & getASTContext() const
Definition: Sema.h:534
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:346
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition: Type.h:8560
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition: Type.cpp:1920
The JSON file list parser is used to communicate input to InstallAPI.
OpenACCDirectiveKind
Definition: OpenACCKinds.h:25
OpenACCReductionOperator
Definition: OpenACCKinds.h:533
bool isOpenACCComputeDirectiveKind(OpenACCDirectiveKind K)
Definition: OpenACCKinds.h:149
bool isOpenACCCombinedDirectiveKind(OpenACCDirectiveKind K)
Definition: OpenACCKinds.h:155
OpenACCClauseKind
Represents the kind of an OpenACC clause.
Definition: OpenACCKinds.h:202
@ Invalid
Represents an invalid clause, for the purposes of parsing.
@ Result
The result type of a method or function.
ExprResult ExprError()
Definition: Ownership.h:264
OpenACCGangKind
Definition: OpenACCKinds.h:592