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