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