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
14#include "clang/Sema/SemaOpenACC.h"
15#include "clang/AST/StmtOpenACC.h"
16#include "clang/Basic/DiagnosticSema.h"
17#include "clang/Basic/OpenACCKinds.h"
18#include "clang/Sema/Sema.h"
19#include "llvm/ADT/StringExtras.h"
20#include "llvm/Support/Casting.h"
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::Parallel:
34 case OpenACCDirectiveKind::Serial:
35 case OpenACCDirectiveKind::Kernels:
36 case OpenACCDirectiveKind::Loop:
37 if (!IsStmt)
38 return S.Diag(Loc: StartLoc, DiagID: diag::err_acc_construct_appertainment) << K;
39 break;
40 }
41 return false;
42}
43
44bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind,
45 OpenACCClauseKind ClauseKind) {
46 switch (ClauseKind) {
47 // FIXME: For each clause as we implement them, we can add the
48 // 'legalization' list here.
49 case OpenACCClauseKind::Default:
50 switch (DirectiveKind) {
51 case OpenACCDirectiveKind::Parallel:
52 case OpenACCDirectiveKind::Serial:
53 case OpenACCDirectiveKind::Kernels:
54 case OpenACCDirectiveKind::ParallelLoop:
55 case OpenACCDirectiveKind::SerialLoop:
56 case OpenACCDirectiveKind::KernelsLoop:
57 case OpenACCDirectiveKind::Data:
58 return true;
59 default:
60 return false;
61 }
62 case OpenACCClauseKind::If:
63 switch (DirectiveKind) {
64 case OpenACCDirectiveKind::Parallel:
65 case OpenACCDirectiveKind::Serial:
66 case OpenACCDirectiveKind::Kernels:
67 case OpenACCDirectiveKind::Data:
68 case OpenACCDirectiveKind::EnterData:
69 case OpenACCDirectiveKind::ExitData:
70 case OpenACCDirectiveKind::HostData:
71 case OpenACCDirectiveKind::Init:
72 case OpenACCDirectiveKind::Shutdown:
73 case OpenACCDirectiveKind::Set:
74 case OpenACCDirectiveKind::Update:
75 case OpenACCDirectiveKind::Wait:
76 case OpenACCDirectiveKind::ParallelLoop:
77 case OpenACCDirectiveKind::SerialLoop:
78 case OpenACCDirectiveKind::KernelsLoop:
79 return true;
80 default:
81 return false;
82 }
83 case OpenACCClauseKind::Self:
84 switch (DirectiveKind) {
85 case OpenACCDirectiveKind::Parallel:
86 case OpenACCDirectiveKind::Serial:
87 case OpenACCDirectiveKind::Kernels:
88 case OpenACCDirectiveKind::Update:
89 case OpenACCDirectiveKind::ParallelLoop:
90 case OpenACCDirectiveKind::SerialLoop:
91 case OpenACCDirectiveKind::KernelsLoop:
92 return true;
93 default:
94 return false;
95 }
96 case OpenACCClauseKind::NumGangs:
97 case OpenACCClauseKind::NumWorkers:
98 case OpenACCClauseKind::VectorLength:
99 switch (DirectiveKind) {
100 case OpenACCDirectiveKind::Parallel:
101 case OpenACCDirectiveKind::Kernels:
102 case OpenACCDirectiveKind::ParallelLoop:
103 case OpenACCDirectiveKind::KernelsLoop:
104 return true;
105 default:
106 return false;
107 }
108 case OpenACCClauseKind::FirstPrivate:
109 switch (DirectiveKind) {
110 case OpenACCDirectiveKind::Parallel:
111 case OpenACCDirectiveKind::Serial:
112 case OpenACCDirectiveKind::ParallelLoop:
113 case OpenACCDirectiveKind::SerialLoop:
114 return true;
115 default:
116 return false;
117 }
118 case OpenACCClauseKind::Private:
119 switch (DirectiveKind) {
120 case OpenACCDirectiveKind::Parallel:
121 case OpenACCDirectiveKind::Serial:
122 case OpenACCDirectiveKind::Loop:
123 case OpenACCDirectiveKind::ParallelLoop:
124 case OpenACCDirectiveKind::SerialLoop:
125 case OpenACCDirectiveKind::KernelsLoop:
126 return true;
127 default:
128 return false;
129 }
130 case OpenACCClauseKind::NoCreate:
131 switch (DirectiveKind) {
132 case OpenACCDirectiveKind::Parallel:
133 case OpenACCDirectiveKind::Serial:
134 case OpenACCDirectiveKind::Kernels:
135 case OpenACCDirectiveKind::Data:
136 case OpenACCDirectiveKind::ParallelLoop:
137 case OpenACCDirectiveKind::SerialLoop:
138 case OpenACCDirectiveKind::KernelsLoop:
139 return true;
140 default:
141 return false;
142 }
143 case OpenACCClauseKind::Present:
144 switch (DirectiveKind) {
145 case OpenACCDirectiveKind::Parallel:
146 case OpenACCDirectiveKind::Serial:
147 case OpenACCDirectiveKind::Kernels:
148 case OpenACCDirectiveKind::Data:
149 case OpenACCDirectiveKind::Declare:
150 case OpenACCDirectiveKind::ParallelLoop:
151 case OpenACCDirectiveKind::SerialLoop:
152 case OpenACCDirectiveKind::KernelsLoop:
153 return true;
154 default:
155 return false;
156 }
157
158 case OpenACCClauseKind::Copy:
159 case OpenACCClauseKind::PCopy:
160 case OpenACCClauseKind::PresentOrCopy:
161 switch (DirectiveKind) {
162 case OpenACCDirectiveKind::Parallel:
163 case OpenACCDirectiveKind::Serial:
164 case OpenACCDirectiveKind::Kernels:
165 case OpenACCDirectiveKind::Data:
166 case OpenACCDirectiveKind::Declare:
167 case OpenACCDirectiveKind::ParallelLoop:
168 case OpenACCDirectiveKind::SerialLoop:
169 case OpenACCDirectiveKind::KernelsLoop:
170 return true;
171 default:
172 return false;
173 }
174 case OpenACCClauseKind::CopyIn:
175 case OpenACCClauseKind::PCopyIn:
176 case OpenACCClauseKind::PresentOrCopyIn:
177 switch (DirectiveKind) {
178 case OpenACCDirectiveKind::Parallel:
179 case OpenACCDirectiveKind::Serial:
180 case OpenACCDirectiveKind::Kernels:
181 case OpenACCDirectiveKind::Data:
182 case OpenACCDirectiveKind::EnterData:
183 case OpenACCDirectiveKind::Declare:
184 case OpenACCDirectiveKind::ParallelLoop:
185 case OpenACCDirectiveKind::SerialLoop:
186 case OpenACCDirectiveKind::KernelsLoop:
187 return true;
188 default:
189 return false;
190 }
191 case OpenACCClauseKind::CopyOut:
192 case OpenACCClauseKind::PCopyOut:
193 case OpenACCClauseKind::PresentOrCopyOut:
194 switch (DirectiveKind) {
195 case OpenACCDirectiveKind::Parallel:
196 case OpenACCDirectiveKind::Serial:
197 case OpenACCDirectiveKind::Kernels:
198 case OpenACCDirectiveKind::Data:
199 case OpenACCDirectiveKind::ExitData:
200 case OpenACCDirectiveKind::Declare:
201 case OpenACCDirectiveKind::ParallelLoop:
202 case OpenACCDirectiveKind::SerialLoop:
203 case OpenACCDirectiveKind::KernelsLoop:
204 return true;
205 default:
206 return false;
207 }
208 case OpenACCClauseKind::Create:
209 case OpenACCClauseKind::PCreate:
210 case OpenACCClauseKind::PresentOrCreate:
211 switch (DirectiveKind) {
212 case OpenACCDirectiveKind::Parallel:
213 case OpenACCDirectiveKind::Serial:
214 case OpenACCDirectiveKind::Kernels:
215 case OpenACCDirectiveKind::Data:
216 case OpenACCDirectiveKind::EnterData:
217 case OpenACCDirectiveKind::ParallelLoop:
218 case OpenACCDirectiveKind::SerialLoop:
219 case OpenACCDirectiveKind::KernelsLoop:
220 return true;
221 default:
222 return false;
223 }
224
225 case OpenACCClauseKind::Attach:
226 switch (DirectiveKind) {
227 case OpenACCDirectiveKind::Parallel:
228 case OpenACCDirectiveKind::Serial:
229 case OpenACCDirectiveKind::Kernels:
230 case OpenACCDirectiveKind::Data:
231 case OpenACCDirectiveKind::EnterData:
232 case OpenACCDirectiveKind::ParallelLoop:
233 case OpenACCDirectiveKind::SerialLoop:
234 case OpenACCDirectiveKind::KernelsLoop:
235 return true;
236 default:
237 return false;
238 }
239 case OpenACCClauseKind::DevicePtr:
240 switch (DirectiveKind) {
241 case OpenACCDirectiveKind::Parallel:
242 case OpenACCDirectiveKind::Serial:
243 case OpenACCDirectiveKind::Kernels:
244 case OpenACCDirectiveKind::Data:
245 case OpenACCDirectiveKind::Declare:
246 case OpenACCDirectiveKind::ParallelLoop:
247 case OpenACCDirectiveKind::SerialLoop:
248 case OpenACCDirectiveKind::KernelsLoop:
249 return true;
250 default:
251 return false;
252 }
253 case OpenACCClauseKind::Async:
254 switch (DirectiveKind) {
255 case OpenACCDirectiveKind::Parallel:
256 case OpenACCDirectiveKind::Serial:
257 case OpenACCDirectiveKind::Kernels:
258 case OpenACCDirectiveKind::Data:
259 case OpenACCDirectiveKind::EnterData:
260 case OpenACCDirectiveKind::ExitData:
261 case OpenACCDirectiveKind::Set:
262 case OpenACCDirectiveKind::Update:
263 case OpenACCDirectiveKind::Wait:
264 case OpenACCDirectiveKind::ParallelLoop:
265 case OpenACCDirectiveKind::SerialLoop:
266 case OpenACCDirectiveKind::KernelsLoop:
267 return true;
268 default:
269 return false;
270 }
271 case OpenACCClauseKind::Wait:
272 switch (DirectiveKind) {
273 case OpenACCDirectiveKind::Parallel:
274 case OpenACCDirectiveKind::Serial:
275 case OpenACCDirectiveKind::Kernels:
276 case OpenACCDirectiveKind::Data:
277 case OpenACCDirectiveKind::EnterData:
278 case OpenACCDirectiveKind::ExitData:
279 case OpenACCDirectiveKind::Update:
280 case OpenACCDirectiveKind::ParallelLoop:
281 case OpenACCDirectiveKind::SerialLoop:
282 case OpenACCDirectiveKind::KernelsLoop:
283 return true;
284 default:
285 return false;
286 }
287
288 case OpenACCClauseKind::Seq:
289 switch (DirectiveKind) {
290 case OpenACCDirectiveKind::Loop:
291 case OpenACCDirectiveKind::Routine:
292 case OpenACCDirectiveKind::ParallelLoop:
293 case OpenACCDirectiveKind::SerialLoop:
294 case OpenACCDirectiveKind::KernelsLoop:
295 return true;
296 default:
297 return false;
298 }
299
300 case OpenACCClauseKind::Independent:
301 case OpenACCClauseKind::Auto:
302 switch (DirectiveKind) {
303 case OpenACCDirectiveKind::Loop:
304 case OpenACCDirectiveKind::ParallelLoop:
305 case OpenACCDirectiveKind::SerialLoop:
306 case OpenACCDirectiveKind::KernelsLoop:
307 return true;
308 default:
309 return false;
310 }
311
312 case OpenACCClauseKind::Reduction:
313 switch (DirectiveKind) {
314 case OpenACCDirectiveKind::Parallel:
315 case OpenACCDirectiveKind::Serial:
316 case OpenACCDirectiveKind::Loop:
317 case OpenACCDirectiveKind::ParallelLoop:
318 case OpenACCDirectiveKind::SerialLoop:
319 case OpenACCDirectiveKind::KernelsLoop:
320 return true;
321 default:
322 return false;
323 }
324
325 case OpenACCClauseKind::DeviceType:
326 case OpenACCClauseKind::DType:
327 switch (DirectiveKind) {
328 case OpenACCDirectiveKind::Parallel:
329 case OpenACCDirectiveKind::Serial:
330 case OpenACCDirectiveKind::Kernels:
331 case OpenACCDirectiveKind::Data:
332 case OpenACCDirectiveKind::Init:
333 case OpenACCDirectiveKind::Shutdown:
334 case OpenACCDirectiveKind::Set:
335 case OpenACCDirectiveKind::Update:
336 case OpenACCDirectiveKind::Loop:
337 case OpenACCDirectiveKind::Routine:
338 case OpenACCDirectiveKind::ParallelLoop:
339 case OpenACCDirectiveKind::SerialLoop:
340 case OpenACCDirectiveKind::KernelsLoop:
341 return true;
342 default:
343 return false;
344 }
345
346 default:
347 // Do nothing so we can go to the 'unimplemented' diagnostic instead.
348 return true;
349 }
350 llvm_unreachable("Invalid clause kind");
351}
352
353bool checkAlreadyHasClauseOfKind(
354 SemaOpenACC &S, ArrayRef<const OpenACCClause *> ExistingClauses,
355 SemaOpenACC::OpenACCParsedClause &Clause) {
356 const auto *Itr = llvm::find_if(Range&: ExistingClauses, P: [&](const OpenACCClause *C) {
357 return C->getClauseKind() == Clause.getClauseKind();
358 });
359 if (Itr != ExistingClauses.end()) {
360 S.Diag(Loc: Clause.getBeginLoc(), DiagID: diag::err_acc_duplicate_clause_disallowed)
361 << Clause.getDirectiveKind() << Clause.getClauseKind();
362 S.Diag(Loc: (*Itr)->getBeginLoc(), DiagID: diag::note_acc_previous_clause_here);
363 return true;
364 }
365 return false;
366}
367
368bool checkValidAfterDeviceType(
369 SemaOpenACC &S, const OpenACCDeviceTypeClause &DeviceTypeClause,
370 const SemaOpenACC::OpenACCParsedClause &NewClause) {
371 // This is only a requirement on compute and loop constructs so far, so this
372 // is fine otherwise.
373 if (!isOpenACCComputeDirectiveKind(K: NewClause.getDirectiveKind()) &&
374 NewClause.getDirectiveKind() != OpenACCDirectiveKind::Loop)
375 return false;
376
377 // OpenACC3.3: Section 2.4: Clauses that precede any device_type clause are
378 // default clauses. Clauses that follow a device_type clause up to the end of
379 // the directive or up to the next device_type clause are device-specific
380 // clauses for the device types specified in the device_type argument.
381 //
382 // The above implies that despite what the individual text says, these are
383 // valid.
384 if (NewClause.getClauseKind() == OpenACCClauseKind::DType ||
385 NewClause.getClauseKind() == OpenACCClauseKind::DeviceType)
386 return false;
387
388 // Implement check from OpenACC3.3: section 2.5.4:
389 // Only the async, wait, num_gangs, num_workers, and vector_length clauses may
390 // follow a device_type clause.
391 if (isOpenACCComputeDirectiveKind(K: NewClause.getDirectiveKind())) {
392 switch (NewClause.getClauseKind()) {
393 case OpenACCClauseKind::Async:
394 case OpenACCClauseKind::Wait:
395 case OpenACCClauseKind::NumGangs:
396 case OpenACCClauseKind::NumWorkers:
397 case OpenACCClauseKind::VectorLength:
398 return false;
399 default:
400 break;
401 }
402 } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Loop) {
403 // Implement check from OpenACC3.3: section 2.9:
404 // Only the collapse, gang, worker, vector, seq, independent, auto, and tile
405 // clauses may follow a device_type clause.
406 switch (NewClause.getClauseKind()) {
407 case OpenACCClauseKind::Collapse:
408 case OpenACCClauseKind::Gang:
409 case OpenACCClauseKind::Worker:
410 case OpenACCClauseKind::Vector:
411 case OpenACCClauseKind::Seq:
412 case OpenACCClauseKind::Independent:
413 case OpenACCClauseKind::Auto:
414 case OpenACCClauseKind::Tile:
415 return false;
416 default:
417 break;
418 }
419 }
420 S.Diag(Loc: NewClause.getBeginLoc(), DiagID: diag::err_acc_clause_after_device_type)
421 << NewClause.getClauseKind() << DeviceTypeClause.getClauseKind()
422 << isOpenACCComputeDirectiveKind(K: NewClause.getDirectiveKind())
423 << NewClause.getDirectiveKind();
424 S.Diag(Loc: DeviceTypeClause.getBeginLoc(), DiagID: diag::note_acc_previous_clause_here);
425 return true;
426}
427
428class SemaOpenACCClauseVisitor {
429 SemaOpenACC &SemaRef;
430 ASTContext &Ctx;
431 ArrayRef<const OpenACCClause *> ExistingClauses;
432 bool NotImplemented = false;
433
434 OpenACCClause *isNotImplemented() {
435 NotImplemented = true;
436 return nullptr;
437 }
438
439public:
440 SemaOpenACCClauseVisitor(SemaOpenACC &S,
441 ArrayRef<const OpenACCClause *> ExistingClauses)
442 : SemaRef(S), Ctx(S.getASTContext()), ExistingClauses(ExistingClauses) {}
443 // Once we've implemented everything, we shouldn't need this infrastructure.
444 // But in the meantime, we use this to help decide whether the clause was
445 // handled for this directive.
446 bool diagNotImplemented() { return NotImplemented; }
447
448 OpenACCClause *Visit(SemaOpenACC::OpenACCParsedClause &Clause) {
449 switch (Clause.getClauseKind()) {
450 case OpenACCClauseKind::Gang:
451 case OpenACCClauseKind::Worker:
452 case OpenACCClauseKind::Vector: {
453 // TODO OpenACC: These are only implemented enough for the 'seq' diagnostic,
454 // otherwise treats itself as unimplemented. When we implement these, we
455 // can remove them from here.
456
457 // OpenACC 3.3 2.9:
458 // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' clause
459 // appears.
460 const auto *Itr =
461 llvm::find_if(Range&: ExistingClauses, P: llvm::IsaPred<OpenACCSeqClause>);
462
463 if (Itr != ExistingClauses.end()) {
464 SemaRef.Diag(Loc: Clause.getBeginLoc(), DiagID: diag::err_acc_clause_cannot_combine)
465 << Clause.getClauseKind() << (*Itr)->getClauseKind();
466 SemaRef.Diag(Loc: (*Itr)->getBeginLoc(), DiagID: diag::note_acc_previous_clause_here);
467 }
468 return isNotImplemented();
469 }
470
471#define VISIT_CLAUSE(CLAUSE_NAME) \
472 case OpenACCClauseKind::CLAUSE_NAME: \
473 return Visit##CLAUSE_NAME##Clause(Clause);
474#define CLAUSE_ALIAS(ALIAS, CLAUSE_NAME, DEPRECATED) \
475 case OpenACCClauseKind::ALIAS: \
476 if (DEPRECATED) \
477 SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name) \
478 << Clause.getClauseKind() << OpenACCClauseKind::CLAUSE_NAME; \
479 return Visit##CLAUSE_NAME##Clause(Clause);
480#include "clang/Basic/OpenACCClauses.def"
481 default:
482 return isNotImplemented();
483 }
484 llvm_unreachable("Invalid clause kind");
485 }
486
487#define VISIT_CLAUSE(CLAUSE_NAME) \
488 OpenACCClause *Visit##CLAUSE_NAME##Clause( \
489 SemaOpenACC::OpenACCParsedClause &Clause);
490#include "clang/Basic/OpenACCClauses.def"
491};
492
493OpenACCClause *SemaOpenACCClauseVisitor::VisitDefaultClause(
494 SemaOpenACC::OpenACCParsedClause &Clause) {
495 // Restrictions only properly implemented on 'compute' constructs, and
496 // 'compute' constructs are the only construct that can do anything with
497 // this yet, so skip/treat as unimplemented in this case.
498 if (!isOpenACCComputeDirectiveKind(K: Clause.getDirectiveKind()))
499 return isNotImplemented();
500
501 // Don't add an invalid clause to the AST.
502 if (Clause.getDefaultClauseKind() == OpenACCDefaultClauseKind::Invalid)
503 return nullptr;
504
505 // OpenACC 3.3, Section 2.5.4:
506 // At most one 'default' clause may appear, and it must have a value of
507 // either 'none' or 'present'.
508 // Second half of the sentence is diagnosed during parsing.
509 if (checkAlreadyHasClauseOfKind(S&: SemaRef, ExistingClauses, Clause))
510 return nullptr;
511
512 return OpenACCDefaultClause::Create(
513 C: Ctx, K: Clause.getDefaultClauseKind(), BeginLoc: Clause.getBeginLoc(),
514 LParenLoc: Clause.getLParenLoc(), EndLoc: Clause.getEndLoc());
515}
516
517OpenACCClause *SemaOpenACCClauseVisitor::VisitIfClause(
518 SemaOpenACC::OpenACCParsedClause &Clause) {
519 // Restrictions only properly implemented on 'compute' constructs, and
520 // 'compute' constructs are the only construct that can do anything with
521 // this yet, so skip/treat as unimplemented in this case.
522 if (!isOpenACCComputeDirectiveKind(K: Clause.getDirectiveKind()))
523 return isNotImplemented();
524
525 // There is no prose in the standard that says duplicates aren't allowed,
526 // but this diagnostic is present in other compilers, as well as makes
527 // sense.
528 if (checkAlreadyHasClauseOfKind(S&: SemaRef, ExistingClauses, Clause))
529 return nullptr;
530
531 // The parser has ensured that we have a proper condition expr, so there
532 // isn't really much to do here.
533
534 // If the 'if' clause is true, it makes the 'self' clause have no effect,
535 // diagnose that here.
536 // TODO OpenACC: When we add these two to other constructs, we might not
537 // want to warn on this (for example, 'update').
538 const auto *Itr =
539 llvm::find_if(Range&: ExistingClauses, P: llvm::IsaPred<OpenACCSelfClause>);
540 if (Itr != ExistingClauses.end()) {
541 SemaRef.Diag(Loc: Clause.getBeginLoc(), DiagID: diag::warn_acc_if_self_conflict);
542 SemaRef.Diag(Loc: (*Itr)->getBeginLoc(), DiagID: diag::note_acc_previous_clause_here);
543 }
544
545 return OpenACCIfClause::Create(C: Ctx, BeginLoc: Clause.getBeginLoc(),
546 LParenLoc: Clause.getLParenLoc(),
547 ConditionExpr: Clause.getConditionExpr(), EndLoc: Clause.getEndLoc());
548}
549
550OpenACCClause *SemaOpenACCClauseVisitor::VisitSelfClause(
551 SemaOpenACC::OpenACCParsedClause &Clause) {
552 // Restrictions only properly implemented on 'compute' constructs, and
553 // 'compute' constructs are the only construct that can do anything with
554 // this yet, so skip/treat as unimplemented in this case.
555 if (!isOpenACCComputeDirectiveKind(K: Clause.getDirectiveKind()))
556 return isNotImplemented();
557
558 // TODO OpenACC: When we implement this for 'update', this takes a
559 // 'var-list' instead of a condition expression, so semantics/handling has
560 // to happen differently here.
561
562 // There is no prose in the standard that says duplicates aren't allowed,
563 // but this diagnostic is present in other compilers, as well as makes
564 // sense.
565 if (checkAlreadyHasClauseOfKind(S&: SemaRef, ExistingClauses, Clause))
566 return nullptr;
567
568 // If the 'if' clause is true, it makes the 'self' clause have no effect,
569 // diagnose that here.
570 // TODO OpenACC: When we add these two to other constructs, we might not
571 // want to warn on this (for example, 'update').
572 const auto *Itr =
573 llvm::find_if(Range&: ExistingClauses, P: llvm::IsaPred<OpenACCIfClause>);
574 if (Itr != ExistingClauses.end()) {
575 SemaRef.Diag(Loc: Clause.getBeginLoc(), DiagID: diag::warn_acc_if_self_conflict);
576 SemaRef.Diag(Loc: (*Itr)->getBeginLoc(), DiagID: diag::note_acc_previous_clause_here);
577 }
578 return OpenACCSelfClause::Create(
579 C: Ctx, BeginLoc: Clause.getBeginLoc(), LParenLoc: Clause.getLParenLoc(),
580 ConditionExpr: Clause.getConditionExpr(), EndLoc: Clause.getEndLoc());
581}
582
583OpenACCClause *SemaOpenACCClauseVisitor::VisitNumGangsClause(
584 SemaOpenACC::OpenACCParsedClause &Clause) {
585 // Restrictions only properly implemented on 'compute' constructs, and
586 // 'compute' constructs are the only construct that can do anything with
587 // this yet, so skip/treat as unimplemented in this case.
588 if (!isOpenACCComputeDirectiveKind(K: Clause.getDirectiveKind()))
589 return isNotImplemented();
590
591 // There is no prose in the standard that says duplicates aren't allowed,
592 // but this diagnostic is present in other compilers, as well as makes
593 // sense.
594 if (checkAlreadyHasClauseOfKind(S&: SemaRef, ExistingClauses, Clause))
595 return nullptr;
596
597 // num_gangs requires at least 1 int expr in all forms. Diagnose here, but
598 // allow us to continue, an empty clause might be useful for future
599 // diagnostics.
600 if (Clause.getIntExprs().empty())
601 SemaRef.Diag(Loc: Clause.getBeginLoc(), DiagID: diag::err_acc_num_gangs_num_args)
602 << /*NoArgs=*/0;
603
604 unsigned MaxArgs =
605 (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel ||
606 Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop)
607 ? 3
608 : 1;
609 // The max number of args differs between parallel and other constructs.
610 // Again, allow us to continue for the purposes of future diagnostics.
611 if (Clause.getIntExprs().size() > MaxArgs)
612 SemaRef.Diag(Loc: Clause.getBeginLoc(), DiagID: diag::err_acc_num_gangs_num_args)
613 << /*NoArgs=*/1 << Clause.getDirectiveKind() << MaxArgs
614 << Clause.getIntExprs().size();
615
616 // OpenACC 3.3 Section 2.5.4:
617 // A reduction clause may not appear on a parallel construct with a
618 // num_gangs clause that has more than one argument.
619 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel &&
620 Clause.getIntExprs().size() > 1) {
621 auto *Parallel =
622 llvm::find_if(Range&: ExistingClauses, P: llvm::IsaPred<OpenACCReductionClause>);
623
624 if (Parallel != ExistingClauses.end()) {
625 SemaRef.Diag(Loc: Clause.getBeginLoc(),
626 DiagID: diag::err_acc_reduction_num_gangs_conflict)
627 << Clause.getIntExprs().size();
628 SemaRef.Diag(Loc: (*Parallel)->getBeginLoc(),
629 DiagID: diag::note_acc_previous_clause_here);
630 return nullptr;
631 }
632 }
633 return OpenACCNumGangsClause::Create(
634 C: Ctx, BeginLoc: Clause.getBeginLoc(), LParenLoc: Clause.getLParenLoc(), IntExprs: Clause.getIntExprs(),
635 EndLoc: Clause.getEndLoc());
636}
637
638OpenACCClause *SemaOpenACCClauseVisitor::VisitNumWorkersClause(
639 SemaOpenACC::OpenACCParsedClause &Clause) {
640 // Restrictions only properly implemented on 'compute' constructs, and
641 // 'compute' constructs are the only construct that can do anything with
642 // this yet, so skip/treat as unimplemented in this case.
643 if (!isOpenACCComputeDirectiveKind(K: Clause.getDirectiveKind()))
644 return isNotImplemented();
645
646 // There is no prose in the standard that says duplicates aren't allowed,
647 // but this diagnostic is present in other compilers, as well as makes
648 // sense.
649 if (checkAlreadyHasClauseOfKind(S&: SemaRef, ExistingClauses, Clause))
650 return nullptr;
651
652 assert(Clause.getIntExprs().size() == 1 &&
653 "Invalid number of expressions for NumWorkers");
654 return OpenACCNumWorkersClause::Create(
655 C: Ctx, BeginLoc: Clause.getBeginLoc(), LParenLoc: Clause.getLParenLoc(), IntExpr: Clause.getIntExprs()[0],
656 EndLoc: Clause.getEndLoc());
657}
658
659OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorLengthClause(
660 SemaOpenACC::OpenACCParsedClause &Clause) {
661 // Restrictions only properly implemented on 'compute' constructs, and
662 // 'compute' constructs are the only construct that can do anything with
663 // this yet, so skip/treat as unimplemented in this case.
664 if (!isOpenACCComputeDirectiveKind(K: Clause.getDirectiveKind()))
665 return isNotImplemented();
666
667 // There is no prose in the standard that says duplicates aren't allowed,
668 // but this diagnostic is present in other compilers, as well as makes
669 // sense.
670 if (checkAlreadyHasClauseOfKind(S&: SemaRef, ExistingClauses, Clause))
671 return nullptr;
672
673 assert(Clause.getIntExprs().size() == 1 &&
674 "Invalid number of expressions for NumWorkers");
675 return OpenACCVectorLengthClause::Create(
676 C: Ctx, BeginLoc: Clause.getBeginLoc(), LParenLoc: Clause.getLParenLoc(), IntExpr: Clause.getIntExprs()[0],
677 EndLoc: Clause.getEndLoc());
678}
679
680OpenACCClause *SemaOpenACCClauseVisitor::VisitAsyncClause(
681 SemaOpenACC::OpenACCParsedClause &Clause) {
682 // Restrictions only properly implemented on 'compute' constructs, and
683 // 'compute' constructs are the only construct that can do anything with
684 // this yet, so skip/treat as unimplemented in this case.
685 if (!isOpenACCComputeDirectiveKind(K: Clause.getDirectiveKind()))
686 return isNotImplemented();
687
688 // There is no prose in the standard that says duplicates aren't allowed,
689 // but this diagnostic is present in other compilers, as well as makes
690 // sense.
691 if (checkAlreadyHasClauseOfKind(S&: SemaRef, ExistingClauses, Clause))
692 return nullptr;
693
694 assert(Clause.getNumIntExprs() < 2 &&
695 "Invalid number of expressions for Async");
696 return OpenACCAsyncClause::Create(
697 C: Ctx, BeginLoc: Clause.getBeginLoc(), LParenLoc: Clause.getLParenLoc(),
698 IntExpr: Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr,
699 EndLoc: Clause.getEndLoc());
700}
701
702OpenACCClause *SemaOpenACCClauseVisitor::VisitPrivateClause(
703 SemaOpenACC::OpenACCParsedClause &Clause) {
704 // Restrictions only properly implemented on 'compute' and 'loop'
705 // constructs, and 'compute'/'loop' constructs are the only construct that
706 // can do anything with this yet, so skip/treat as unimplemented in this
707 // case.
708 if (!isOpenACCComputeDirectiveKind(K: Clause.getDirectiveKind()) &&
709 Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop)
710 return isNotImplemented();
711
712 // ActOnVar ensured that everything is a valid variable reference, so there
713 // really isn't anything to do here. GCC does some duplicate-finding, though
714 // it isn't apparent in the standard where this is justified.
715
716 return OpenACCPrivateClause::Create(C: Ctx, BeginLoc: Clause.getBeginLoc(),
717 LParenLoc: Clause.getLParenLoc(),
718 VarList: Clause.getVarList(), EndLoc: Clause.getEndLoc());
719}
720
721OpenACCClause *SemaOpenACCClauseVisitor::VisitFirstPrivateClause(
722 SemaOpenACC::OpenACCParsedClause &Clause) {
723 // Restrictions only properly implemented on 'compute' constructs, and
724 // 'compute' constructs are the only construct that can do anything with
725 // this yet, so skip/treat as unimplemented in this case.
726 if (!isOpenACCComputeDirectiveKind(K: Clause.getDirectiveKind()))
727 return isNotImplemented();
728
729 // ActOnVar ensured that everything is a valid variable reference, so there
730 // really isn't anything to do here. GCC does some duplicate-finding, though
731 // it isn't apparent in the standard where this is justified.
732
733 return OpenACCFirstPrivateClause::Create(
734 C: Ctx, BeginLoc: Clause.getBeginLoc(), LParenLoc: Clause.getLParenLoc(), VarList: Clause.getVarList(),
735 EndLoc: Clause.getEndLoc());
736}
737
738OpenACCClause *SemaOpenACCClauseVisitor::VisitNoCreateClause(
739 SemaOpenACC::OpenACCParsedClause &Clause) {
740 // Restrictions only properly implemented on 'compute' constructs, and
741 // 'compute' constructs are the only construct that can do anything with
742 // this yet, so skip/treat as unimplemented in this case.
743 if (!isOpenACCComputeDirectiveKind(K: Clause.getDirectiveKind()))
744 return isNotImplemented();
745 // ActOnVar ensured that everything is a valid variable reference, so there
746 // really isn't anything to do here. GCC does some duplicate-finding, though
747 // it isn't apparent in the standard where this is justified.
748
749 return OpenACCNoCreateClause::Create(C: Ctx, BeginLoc: Clause.getBeginLoc(),
750 LParenLoc: Clause.getLParenLoc(),
751 VarList: Clause.getVarList(), EndLoc: Clause.getEndLoc());
752}
753
754OpenACCClause *SemaOpenACCClauseVisitor::VisitPresentClause(
755 SemaOpenACC::OpenACCParsedClause &Clause) {
756 // Restrictions only properly implemented on 'compute' constructs, and
757 // 'compute' constructs are the only construct that can do anything with
758 // this yet, so skip/treat as unimplemented in this case.
759 if (!isOpenACCComputeDirectiveKind(K: Clause.getDirectiveKind()))
760 return isNotImplemented();
761 // ActOnVar ensured that everything is a valid variable reference, so there
762 // really isn't anything to do here. GCC does some duplicate-finding, though
763 // it isn't apparent in the standard where this is justified.
764
765 return OpenACCPresentClause::Create(C: Ctx, BeginLoc: Clause.getBeginLoc(),
766 LParenLoc: Clause.getLParenLoc(),
767 VarList: Clause.getVarList(), EndLoc: Clause.getEndLoc());
768}
769
770OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyClause(
771 SemaOpenACC::OpenACCParsedClause &Clause) {
772 // Restrictions only properly implemented on 'compute' constructs, and
773 // 'compute' constructs are the only construct that can do anything with
774 // this yet, so skip/treat as unimplemented in this case.
775 if (!isOpenACCComputeDirectiveKind(K: Clause.getDirectiveKind()))
776 return isNotImplemented();
777 // ActOnVar ensured that everything is a valid variable reference, so there
778 // really isn't anything to do here. GCC does some duplicate-finding, though
779 // it isn't apparent in the standard where this is justified.
780
781 return OpenACCCopyClause::Create(
782 C: Ctx, Spelling: Clause.getClauseKind(), BeginLoc: Clause.getBeginLoc(), LParenLoc: Clause.getLParenLoc(),
783 VarList: Clause.getVarList(), EndLoc: Clause.getEndLoc());
784}
785
786OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyInClause(
787 SemaOpenACC::OpenACCParsedClause &Clause) {
788 // Restrictions only properly implemented on 'compute' constructs, and
789 // 'compute' constructs are the only construct that can do anything with
790 // this yet, so skip/treat as unimplemented in this case.
791 if (!isOpenACCComputeDirectiveKind(K: Clause.getDirectiveKind()))
792 return isNotImplemented();
793 // ActOnVar ensured that everything is a valid variable reference, so there
794 // really isn't anything to do here. GCC does some duplicate-finding, though
795 // it isn't apparent in the standard where this is justified.
796
797 return OpenACCCopyInClause::Create(
798 C: Ctx, Spelling: Clause.getClauseKind(), BeginLoc: Clause.getBeginLoc(), LParenLoc: Clause.getLParenLoc(),
799 IsReadOnly: Clause.isReadOnly(), VarList: Clause.getVarList(), EndLoc: Clause.getEndLoc());
800}
801
802OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyOutClause(
803 SemaOpenACC::OpenACCParsedClause &Clause) {
804 // Restrictions only properly implemented on 'compute' constructs, and
805 // 'compute' constructs are the only construct that can do anything with
806 // this yet, so skip/treat as unimplemented in this case.
807 if (!isOpenACCComputeDirectiveKind(K: Clause.getDirectiveKind()))
808 return isNotImplemented();
809 // ActOnVar ensured that everything is a valid variable reference, so there
810 // really isn't anything to do here. GCC does some duplicate-finding, though
811 // it isn't apparent in the standard where this is justified.
812
813 return OpenACCCopyOutClause::Create(
814 C: Ctx, Spelling: Clause.getClauseKind(), BeginLoc: Clause.getBeginLoc(), LParenLoc: Clause.getLParenLoc(),
815 IsZero: Clause.isZero(), VarList: Clause.getVarList(), EndLoc: Clause.getEndLoc());
816}
817
818OpenACCClause *SemaOpenACCClauseVisitor::VisitCreateClause(
819 SemaOpenACC::OpenACCParsedClause &Clause) {
820 // Restrictions only properly implemented on 'compute' constructs, and
821 // 'compute' constructs are the only construct that can do anything with
822 // this yet, so skip/treat as unimplemented in this case.
823 if (!isOpenACCComputeDirectiveKind(K: Clause.getDirectiveKind()))
824 return isNotImplemented();
825 // ActOnVar ensured that everything is a valid variable reference, so there
826 // really isn't anything to do here. GCC does some duplicate-finding, though
827 // it isn't apparent in the standard where this is justified.
828
829 return OpenACCCreateClause::Create(
830 C: Ctx, Spelling: Clause.getClauseKind(), BeginLoc: Clause.getBeginLoc(), LParenLoc: Clause.getLParenLoc(),
831 IsZero: Clause.isZero(), VarList: Clause.getVarList(), EndLoc: Clause.getEndLoc());
832}
833
834OpenACCClause *SemaOpenACCClauseVisitor::VisitAttachClause(
835 SemaOpenACC::OpenACCParsedClause &Clause) {
836 // Restrictions only properly implemented on 'compute' constructs, and
837 // 'compute' constructs are the only construct that can do anything with
838 // this yet, so skip/treat as unimplemented in this case.
839 if (!isOpenACCComputeDirectiveKind(K: Clause.getDirectiveKind()))
840 return isNotImplemented();
841
842 // ActOnVar ensured that everything is a valid variable reference, but we
843 // still have to make sure it is a pointer type.
844 llvm::SmallVector<Expr *> VarList{Clause.getVarList()};
845 llvm::erase_if(C&: VarList, P: [&](Expr *E) {
846 return SemaRef.CheckVarIsPointerType(ClauseKind: OpenACCClauseKind::Attach, VarExpr: E);
847 });
848 Clause.setVarListDetails(VarList,
849 /*IsReadOnly=*/false, /*IsZero=*/false);
850 return OpenACCAttachClause::Create(C: Ctx, BeginLoc: Clause.getBeginLoc(),
851 LParenLoc: Clause.getLParenLoc(), VarList: Clause.getVarList(),
852 EndLoc: Clause.getEndLoc());
853}
854
855OpenACCClause *SemaOpenACCClauseVisitor::VisitDevicePtrClause(
856 SemaOpenACC::OpenACCParsedClause &Clause) {
857 // Restrictions only properly implemented on 'compute' constructs, and
858 // 'compute' constructs are the only construct that can do anything with
859 // this yet, so skip/treat as unimplemented in this case.
860 if (!isOpenACCComputeDirectiveKind(K: Clause.getDirectiveKind()))
861 return isNotImplemented();
862
863 // ActOnVar ensured that everything is a valid variable reference, but we
864 // still have to make sure it is a pointer type.
865 llvm::SmallVector<Expr *> VarList{Clause.getVarList()};
866 llvm::erase_if(C&: VarList, P: [&](Expr *E) {
867 return SemaRef.CheckVarIsPointerType(ClauseKind: OpenACCClauseKind::DevicePtr, VarExpr: E);
868 });
869 Clause.setVarListDetails(VarList,
870 /*IsReadOnly=*/false, /*IsZero=*/false);
871
872 return OpenACCDevicePtrClause::Create(
873 C: Ctx, BeginLoc: Clause.getBeginLoc(), LParenLoc: Clause.getLParenLoc(), VarList: Clause.getVarList(),
874 EndLoc: Clause.getEndLoc());
875}
876
877OpenACCClause *SemaOpenACCClauseVisitor::VisitWaitClause(
878 SemaOpenACC::OpenACCParsedClause &Clause) {
879 // Restrictions only properly implemented on 'compute' constructs, and
880 // 'compute' constructs are the only construct that can do anything with
881 // this yet, so skip/treat as unimplemented in this case.
882 if (!isOpenACCComputeDirectiveKind(K: Clause.getDirectiveKind()))
883 return isNotImplemented();
884
885 return OpenACCWaitClause::Create(
886 C: Ctx, BeginLoc: Clause.getBeginLoc(), LParenLoc: Clause.getLParenLoc(), DevNumExpr: Clause.getDevNumExpr(),
887 QueuesLoc: Clause.getQueuesLoc(), QueueIdExprs: Clause.getQueueIdExprs(), EndLoc: Clause.getEndLoc());
888}
889
890OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceTypeClause(
891 SemaOpenACC::OpenACCParsedClause &Clause) {
892 // Restrictions only properly implemented on 'compute' and 'loop'
893 // constructs, and 'compute'/'loop' constructs are the only construct that
894 // can do anything with this yet, so skip/treat as unimplemented in this
895 // case.
896 if (!isOpenACCComputeDirectiveKind(K: Clause.getDirectiveKind()) &&
897 Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop)
898 return isNotImplemented();
899
900 // TODO OpenACC: Once we get enough of the CodeGen implemented that we have
901 // a source for the list of valid architectures, we need to warn on unknown
902 // identifiers here.
903
904 return OpenACCDeviceTypeClause::Create(
905 C: Ctx, K: Clause.getClauseKind(), BeginLoc: Clause.getBeginLoc(), LParenLoc: Clause.getLParenLoc(),
906 Archs: Clause.getDeviceTypeArchitectures(), EndLoc: Clause.getEndLoc());
907}
908
909OpenACCClause *SemaOpenACCClauseVisitor::VisitAutoClause(
910 SemaOpenACC::OpenACCParsedClause &Clause) {
911 // Restrictions only properly implemented on 'loop' constructs, and it is
912 // the only construct that can do anything with this, so skip/treat as
913 // unimplemented for the combined constructs.
914 if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop)
915 return isNotImplemented();
916
917 // OpenACC 3.3 2.9:
918 // Only one of the seq, independent, and auto clauses may appear.
919 const auto *Itr =
920 llvm::find_if(Range&: ExistingClauses,
921 P: llvm::IsaPred<OpenACCIndependentClause, OpenACCSeqClause>);
922 if (Itr != ExistingClauses.end()) {
923 SemaRef.Diag(Loc: Clause.getBeginLoc(), DiagID: diag::err_acc_loop_spec_conflict)
924 << Clause.getClauseKind() << Clause.getDirectiveKind();
925 SemaRef.Diag(Loc: (*Itr)->getBeginLoc(), DiagID: diag::note_acc_previous_clause_here);
926 return nullptr;
927 }
928
929 return OpenACCAutoClause::Create(Ctx, BeginLoc: Clause.getBeginLoc(),
930 EndLoc: Clause.getEndLoc());
931}
932
933OpenACCClause *SemaOpenACCClauseVisitor::VisitIndependentClause(
934 SemaOpenACC::OpenACCParsedClause &Clause) {
935 // Restrictions only properly implemented on 'loop' constructs, and it is
936 // the only construct that can do anything with this, so skip/treat as
937 // unimplemented for the combined constructs.
938 if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop)
939 return isNotImplemented();
940
941 // OpenACC 3.3 2.9:
942 // Only one of the seq, independent, and auto clauses may appear.
943 const auto *Itr = llvm::find_if(
944 Range&: ExistingClauses, P: llvm::IsaPred<OpenACCAutoClause, OpenACCSeqClause>);
945 if (Itr != ExistingClauses.end()) {
946 SemaRef.Diag(Loc: Clause.getBeginLoc(), DiagID: diag::err_acc_loop_spec_conflict)
947 << Clause.getClauseKind() << Clause.getDirectiveKind();
948 SemaRef.Diag(Loc: (*Itr)->getBeginLoc(), DiagID: diag::note_acc_previous_clause_here);
949 return nullptr;
950 }
951
952 return OpenACCIndependentClause::Create(Ctx, BeginLoc: Clause.getBeginLoc(),
953 EndLoc: Clause.getEndLoc());
954}
955
956OpenACCClause *SemaOpenACCClauseVisitor::VisitSeqClause(
957 SemaOpenACC::OpenACCParsedClause &Clause) {
958 // Restrictions only properly implemented on 'loop' constructs, and it is
959 // the only construct that can do anything with this, so skip/treat as
960 // unimplemented for the combined constructs.
961 if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop)
962 return isNotImplemented();
963
964 // OpenACC 3.3 2.9:
965 // Only one of the seq, independent, and auto clauses may appear.
966 const auto *Itr =
967 llvm::find_if(Range&: ExistingClauses,
968 P: llvm::IsaPred<OpenACCAutoClause, OpenACCIndependentClause>);
969 if (Itr != ExistingClauses.end()) {
970 SemaRef.Diag(Loc: Clause.getBeginLoc(), DiagID: diag::err_acc_loop_spec_conflict)
971 << Clause.getClauseKind() << Clause.getDirectiveKind();
972 SemaRef.Diag(Loc: (*Itr)->getBeginLoc(), DiagID: diag::note_acc_previous_clause_here);
973 return nullptr;
974 }
975
976 // OpenACC 3.3 2.9:
977 // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' clause
978 // appears.
979 Itr = llvm::find_if(Range&: ExistingClauses,
980 P: llvm::IsaPred<OpenACCGangClause, OpenACCWorkerClause,
981 OpenACCVectorClause>);
982
983 if (Itr != ExistingClauses.end()) {
984 SemaRef.Diag(Loc: Clause.getBeginLoc(), DiagID: diag::err_acc_clause_cannot_combine)
985 << Clause.getClauseKind() << (*Itr)->getClauseKind();
986 SemaRef.Diag(Loc: (*Itr)->getBeginLoc(), DiagID: diag::note_acc_previous_clause_here);
987 return nullptr;
988 }
989
990 // TODO OpenACC: 2.9 ~ line 2010 specifies that the associated loop has some
991 // restrictions when there is a 'seq' clause in place. We probably need to
992 // implement that.
993 return OpenACCSeqClause::Create(Ctx, BeginLoc: Clause.getBeginLoc(),
994 EndLoc: Clause.getEndLoc());
995}
996
997OpenACCClause *SemaOpenACCClauseVisitor::VisitReductionClause(
998 SemaOpenACC::OpenACCParsedClause &Clause) {
999 // Restrictions only properly implemented on 'compute' constructs, and
1000 // 'compute' constructs are the only construct that can do anything with
1001 // this yet, so skip/treat as unimplemented in this case.
1002 if (!isOpenACCComputeDirectiveKind(K: Clause.getDirectiveKind()))
1003 return isNotImplemented();
1004
1005 // OpenACC 3.3 Section 2.5.4:
1006 // A reduction clause may not appear on a parallel construct with a
1007 // num_gangs clause that has more than one argument.
1008 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel) {
1009 auto NumGangsClauses = llvm::make_filter_range(
1010 Range&: ExistingClauses, Pred: llvm::IsaPred<OpenACCNumGangsClause>);
1011
1012 for (auto *NGC : NumGangsClauses) {
1013 unsigned NumExprs =
1014 cast<OpenACCNumGangsClause>(Val: NGC)->getIntExprs().size();
1015
1016 if (NumExprs > 1) {
1017 SemaRef.Diag(Loc: Clause.getBeginLoc(),
1018 DiagID: diag::err_acc_reduction_num_gangs_conflict)
1019 << NumExprs;
1020 SemaRef.Diag(Loc: NGC->getBeginLoc(), DiagID: diag::note_acc_previous_clause_here);
1021 return nullptr;
1022 }
1023 }
1024 }
1025
1026 SmallVector<Expr *> ValidVars;
1027
1028 for (Expr *Var : Clause.getVarList()) {
1029 ExprResult Res = SemaRef.CheckReductionVar(VarExpr: Var);
1030
1031 if (Res.isUsable())
1032 ValidVars.push_back(Elt: Res.get());
1033 }
1034
1035 return OpenACCReductionClause::Create(
1036 C: Ctx, BeginLoc: Clause.getBeginLoc(), LParenLoc: Clause.getLParenLoc(), Operator: Clause.getReductionOp(),
1037 VarList: ValidVars, EndLoc: Clause.getEndLoc());
1038}
1039
1040} // namespace
1041
1042SemaOpenACC::SemaOpenACC(Sema &S) : SemaBase(S) {}
1043
1044SemaOpenACC::AssociatedStmtRAII::AssociatedStmtRAII(SemaOpenACC &S,
1045 OpenACCDirectiveKind DK)
1046 : SemaRef(S), WasInsideComputeConstruct(S.InsideComputeConstruct),
1047 DirKind(DK) {
1048 // Compute constructs end up taking their 'loop'.
1049 if (DirKind == OpenACCDirectiveKind::Parallel ||
1050 DirKind == OpenACCDirectiveKind::Serial ||
1051 DirKind == OpenACCDirectiveKind::Kernels) {
1052 SemaRef.InsideComputeConstruct = true;
1053 SemaRef.ParentlessLoopConstructs.swap(RHS&: ParentlessLoopConstructs);
1054 }
1055}
1056
1057SemaOpenACC::AssociatedStmtRAII::~AssociatedStmtRAII() {
1058 SemaRef.InsideComputeConstruct = WasInsideComputeConstruct;
1059 if (DirKind == OpenACCDirectiveKind::Parallel ||
1060 DirKind == OpenACCDirectiveKind::Serial ||
1061 DirKind == OpenACCDirectiveKind::Kernels) {
1062 assert(SemaRef.ParentlessLoopConstructs.empty() &&
1063 "Didn't consume loop construct list?");
1064 SemaRef.ParentlessLoopConstructs.swap(RHS&: ParentlessLoopConstructs);
1065 }
1066}
1067
1068OpenACCClause *
1069SemaOpenACC::ActOnClause(ArrayRef<const OpenACCClause *> ExistingClauses,
1070 OpenACCParsedClause &Clause) {
1071 if (Clause.getClauseKind() == OpenACCClauseKind::Invalid)
1072 return nullptr;
1073
1074 // Diagnose that we don't support this clause on this directive.
1075 if (!doesClauseApplyToDirective(DirectiveKind: Clause.getDirectiveKind(),
1076 ClauseKind: Clause.getClauseKind())) {
1077 Diag(Loc: Clause.getBeginLoc(), DiagID: diag::err_acc_clause_appertainment)
1078 << Clause.getDirectiveKind() << Clause.getClauseKind();
1079 return nullptr;
1080 }
1081
1082 if (const auto *DevTypeClause =
1083 llvm::find_if(Range&: ExistingClauses,
1084 P: [&](const OpenACCClause *C) {
1085 return isa<OpenACCDeviceTypeClause>(Val: C);
1086 });
1087 DevTypeClause != ExistingClauses.end()) {
1088 if (checkValidAfterDeviceType(
1089 S&: *this, DeviceTypeClause: *cast<OpenACCDeviceTypeClause>(Val: *DevTypeClause), NewClause: Clause))
1090 return nullptr;
1091 }
1092
1093 SemaOpenACCClauseVisitor Visitor{*this, ExistingClauses};
1094 OpenACCClause *Result = Visitor.Visit(Clause);
1095 assert((!Result || Result->getClauseKind() == Clause.getClauseKind()) &&
1096 "Created wrong clause?");
1097
1098 if (Visitor.diagNotImplemented())
1099 Diag(Loc: Clause.getBeginLoc(), DiagID: diag::warn_acc_clause_unimplemented)
1100 << Clause.getClauseKind();
1101
1102 return Result;
1103
1104 // switch (Clause.getClauseKind()) {
1105 // case OpenACCClauseKind::PresentOrCopy:
1106 // case OpenACCClauseKind::PCopy:
1107 // Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name)
1108 // << Clause.getClauseKind() << OpenACCClauseKind::Copy;
1109 // LLVM_FALLTHROUGH;
1110 // case OpenACCClauseKind::PresentOrCreate:
1111 // case OpenACCClauseKind::PCreate:
1112 // Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name)
1113 // << Clause.getClauseKind() << OpenACCClauseKind::Create;
1114 // LLVM_FALLTHROUGH;
1115 //
1116 //
1117 //
1118 //
1119 // case OpenACCClauseKind::DType:
1120 //
1121 //
1122 //
1123 //
1124 //
1125 //
1126 //
1127 //
1128 // case OpenACCClauseKind::Gang:
1129 // case OpenACCClauseKind::Worker:
1130 // case OpenACCClauseKind::Vector: {
1131 // // OpenACC 3.3 2.9:
1132 // // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq'
1133 // clause
1134 // // appears.
1135 // const auto *Itr =
1136 // llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSeqClause>);
1137 //
1138 // if (Itr != ExistingClauses.end()) {
1139 // Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine)
1140 // << Clause.getClauseKind() << (*Itr)->getClauseKind();
1141 // Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1142 // }
1143 // // Not yet implemented, so immediately drop to the 'not yet implemented'
1144 // // diagnostic.
1145 // break;
1146 // }
1147 // */
1148
1149}
1150
1151/// OpenACC 3.3 section 2.5.15:
1152/// At a mininmum, the supported data types include ... the numerical data types
1153/// in C, C++, and Fortran.
1154///
1155/// If the reduction var is a composite variable, each
1156/// member of the composite variable must be a supported datatype for the
1157/// reduction operation.
1158ExprResult SemaOpenACC::CheckReductionVar(Expr *VarExpr) {
1159 VarExpr = VarExpr->IgnoreParenCasts();
1160
1161 auto TypeIsValid = [](QualType Ty) {
1162 return Ty->isDependentType() || Ty->isScalarType();
1163 };
1164
1165 if (isa<ArraySectionExpr>(Val: VarExpr)) {
1166 Expr *ASExpr = VarExpr;
1167 QualType BaseTy = ArraySectionExpr::getBaseOriginalType(Base: ASExpr);
1168 QualType EltTy = getASTContext().getBaseElementType(QT: BaseTy);
1169
1170 if (!TypeIsValid(EltTy)) {
1171 Diag(Loc: VarExpr->getExprLoc(), DiagID: diag::err_acc_reduction_type)
1172 << EltTy << /*Sub array base type*/ 1;
1173 return ExprError();
1174 }
1175 } else if (auto *RD = VarExpr->getType()->getAsRecordDecl()) {
1176 if (!RD->isStruct() && !RD->isClass()) {
1177 Diag(Loc: VarExpr->getExprLoc(), DiagID: diag::err_acc_reduction_composite_type)
1178 << /*not class or struct*/ 0 << VarExpr->getType();
1179 return ExprError();
1180 }
1181
1182 if (!RD->isCompleteDefinition()) {
1183 Diag(Loc: VarExpr->getExprLoc(), DiagID: diag::err_acc_reduction_composite_type)
1184 << /*incomplete*/ 1 << VarExpr->getType();
1185 return ExprError();
1186 }
1187 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(Val: RD);
1188 CXXRD && !CXXRD->isAggregate()) {
1189 Diag(Loc: VarExpr->getExprLoc(), DiagID: diag::err_acc_reduction_composite_type)
1190 << /*aggregate*/ 2 << VarExpr->getType();
1191 return ExprError();
1192 }
1193
1194 for (FieldDecl *FD : RD->fields()) {
1195 if (!TypeIsValid(FD->getType())) {
1196 Diag(Loc: VarExpr->getExprLoc(),
1197 DiagID: diag::err_acc_reduction_composite_member_type);
1198 Diag(Loc: FD->getLocation(), DiagID: diag::note_acc_reduction_composite_member_loc);
1199 return ExprError();
1200 }
1201 }
1202 } else if (!TypeIsValid(VarExpr->getType())) {
1203 Diag(Loc: VarExpr->getExprLoc(), DiagID: diag::err_acc_reduction_type)
1204 << VarExpr->getType() << /*Sub array base type*/ 0;
1205 return ExprError();
1206 }
1207
1208 return VarExpr;
1209}
1210
1211void SemaOpenACC::ActOnConstruct(OpenACCDirectiveKind K,
1212 SourceLocation DirLoc) {
1213 switch (K) {
1214 case OpenACCDirectiveKind::Invalid:
1215 // Nothing to do here, an invalid kind has nothing we can check here. We
1216 // want to continue parsing clauses as far as we can, so we will just
1217 // ensure that we can still work and don't check any construct-specific
1218 // rules anywhere.
1219 break;
1220 case OpenACCDirectiveKind::Parallel:
1221 case OpenACCDirectiveKind::Serial:
1222 case OpenACCDirectiveKind::Kernels:
1223 case OpenACCDirectiveKind::Loop:
1224 // Nothing to do here, there is no real legalization that needs to happen
1225 // here as these constructs do not take any arguments.
1226 break;
1227 default:
1228 Diag(Loc: DirLoc, DiagID: diag::warn_acc_construct_unimplemented) << K;
1229 break;
1230 }
1231}
1232
1233ExprResult SemaOpenACC::ActOnIntExpr(OpenACCDirectiveKind DK,
1234 OpenACCClauseKind CK, SourceLocation Loc,
1235 Expr *IntExpr) {
1236
1237 assert(((DK != OpenACCDirectiveKind::Invalid &&
1238 CK == OpenACCClauseKind::Invalid) ||
1239 (DK == OpenACCDirectiveKind::Invalid &&
1240 CK != OpenACCClauseKind::Invalid) ||
1241 (DK == OpenACCDirectiveKind::Invalid &&
1242 CK == OpenACCClauseKind::Invalid)) &&
1243 "Only one of directive or clause kind should be provided");
1244
1245 class IntExprConverter : public Sema::ICEConvertDiagnoser {
1246 OpenACCDirectiveKind DirectiveKind;
1247 OpenACCClauseKind ClauseKind;
1248 Expr *IntExpr;
1249
1250 // gets the index into the diagnostics so we can use this for clauses,
1251 // directives, and sub array.s
1252 unsigned getDiagKind() const {
1253 if (ClauseKind != OpenACCClauseKind::Invalid)
1254 return 0;
1255 if (DirectiveKind != OpenACCDirectiveKind::Invalid)
1256 return 1;
1257 return 2;
1258 }
1259
1260 public:
1261 IntExprConverter(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
1262 Expr *IntExpr)
1263 : ICEConvertDiagnoser(/*AllowScopedEnumerations=*/false,
1264 /*Suppress=*/false,
1265 /*SuppressConversion=*/true),
1266 DirectiveKind(DK), ClauseKind(CK), IntExpr(IntExpr) {}
1267
1268 bool match(QualType T) override {
1269 // OpenACC spec just calls this 'integer expression' as having an
1270 // 'integer type', so fall back on C99's 'integer type'.
1271 return T->isIntegerType();
1272 }
1273 SemaBase::SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
1274 QualType T) override {
1275 return S.Diag(Loc, DiagID: diag::err_acc_int_expr_requires_integer)
1276 << getDiagKind() << ClauseKind << DirectiveKind << T;
1277 }
1278
1279 SemaBase::SemaDiagnosticBuilder
1280 diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) override {
1281 return S.Diag(Loc, DiagID: diag::err_acc_int_expr_incomplete_class_type)
1282 << T << IntExpr->getSourceRange();
1283 }
1284
1285 SemaBase::SemaDiagnosticBuilder
1286 diagnoseExplicitConv(Sema &S, SourceLocation Loc, QualType T,
1287 QualType ConvTy) override {
1288 return S.Diag(Loc, DiagID: diag::err_acc_int_expr_explicit_conversion)
1289 << T << ConvTy;
1290 }
1291
1292 SemaBase::SemaDiagnosticBuilder noteExplicitConv(Sema &S,
1293 CXXConversionDecl *Conv,
1294 QualType ConvTy) override {
1295 return S.Diag(Loc: Conv->getLocation(), DiagID: diag::note_acc_int_expr_conversion)
1296 << ConvTy->isEnumeralType() << ConvTy;
1297 }
1298
1299 SemaBase::SemaDiagnosticBuilder
1300 diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) override {
1301 return S.Diag(Loc, DiagID: diag::err_acc_int_expr_multiple_conversions) << T;
1302 }
1303
1304 SemaBase::SemaDiagnosticBuilder
1305 noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
1306 return S.Diag(Loc: Conv->getLocation(), DiagID: diag::note_acc_int_expr_conversion)
1307 << ConvTy->isEnumeralType() << ConvTy;
1308 }
1309
1310 SemaBase::SemaDiagnosticBuilder
1311 diagnoseConversion(Sema &S, SourceLocation Loc, QualType T,
1312 QualType ConvTy) override {
1313 llvm_unreachable("conversion functions are permitted");
1314 }
1315 } IntExprDiagnoser(DK, CK, IntExpr);
1316
1317 ExprResult IntExprResult = SemaRef.PerformContextualImplicitConversion(
1318 Loc, FromE: IntExpr, Converter&: IntExprDiagnoser);
1319 if (IntExprResult.isInvalid())
1320 return ExprError();
1321
1322 IntExpr = IntExprResult.get();
1323 if (!IntExpr->isTypeDependent() && !IntExpr->getType()->isIntegerType())
1324 return ExprError();
1325
1326 // TODO OpenACC: Do we want to perform usual unary conversions here? When
1327 // doing codegen we might find that is necessary, but skip it for now.
1328 return IntExpr;
1329}
1330
1331bool SemaOpenACC::CheckVarIsPointerType(OpenACCClauseKind ClauseKind,
1332 Expr *VarExpr) {
1333 // We already know that VarExpr is a proper reference to a variable, so we
1334 // should be able to just take the type of the expression to get the type of
1335 // the referenced variable.
1336
1337 // We've already seen an error, don't diagnose anything else.
1338 if (!VarExpr || VarExpr->containsErrors())
1339 return false;
1340
1341 if (isa<ArraySectionExpr>(Val: VarExpr->IgnoreParenImpCasts()) ||
1342 VarExpr->hasPlaceholderType(K: BuiltinType::ArraySection)) {
1343 Diag(Loc: VarExpr->getExprLoc(), DiagID: diag::err_array_section_use) << /*OpenACC=*/0;
1344 Diag(Loc: VarExpr->getExprLoc(), DiagID: diag::note_acc_expected_pointer_var);
1345 return true;
1346 }
1347
1348 QualType Ty = VarExpr->getType();
1349 Ty = Ty.getNonReferenceType().getUnqualifiedType();
1350
1351 // Nothing we can do if this is a dependent type.
1352 if (Ty->isDependentType())
1353 return false;
1354
1355 if (!Ty->isPointerType())
1356 return Diag(Loc: VarExpr->getExprLoc(), DiagID: diag::err_acc_var_not_pointer_type)
1357 << ClauseKind << Ty;
1358 return false;
1359}
1360
1361ExprResult SemaOpenACC::ActOnVar(OpenACCClauseKind CK, Expr *VarExpr) {
1362 Expr *CurVarExpr = VarExpr->IgnoreParenImpCasts();
1363
1364 // Sub-arrays/subscript-exprs are fine as long as the base is a
1365 // VarExpr/MemberExpr. So strip all of those off.
1366 while (isa<ArraySectionExpr, ArraySubscriptExpr>(Val: CurVarExpr)) {
1367 if (auto *SubScrpt = dyn_cast<ArraySubscriptExpr>(Val: CurVarExpr))
1368 CurVarExpr = SubScrpt->getBase()->IgnoreParenImpCasts();
1369 else
1370 CurVarExpr =
1371 cast<ArraySectionExpr>(Val: CurVarExpr)->getBase()->IgnoreParenImpCasts();
1372 }
1373
1374 // References to a VarDecl are fine.
1375 if (const auto *DRE = dyn_cast<DeclRefExpr>(Val: CurVarExpr)) {
1376 if (isa<VarDecl, NonTypeTemplateParmDecl>(
1377 Val: DRE->getFoundDecl()->getCanonicalDecl()))
1378 return VarExpr;
1379 }
1380
1381 // If CK is a Reduction, this special cases for OpenACC3.3 2.5.15: "A var in a
1382 // reduction clause must be a scalar variable name, an aggregate variable
1383 // name, an array element, or a subarray.
1384 // A MemberExpr that references a Field is valid.
1385 if (CK != OpenACCClauseKind::Reduction) {
1386 if (const auto *ME = dyn_cast<MemberExpr>(Val: CurVarExpr)) {
1387 if (isa<FieldDecl>(Val: ME->getMemberDecl()->getCanonicalDecl()))
1388 return VarExpr;
1389 }
1390 }
1391
1392 // Referring to 'this' is always OK.
1393 if (isa<CXXThisExpr>(Val: CurVarExpr))
1394 return VarExpr;
1395
1396 // Nothing really we can do here, as these are dependent. So just return they
1397 // are valid.
1398 if (isa<DependentScopeDeclRefExpr>(Val: CurVarExpr) ||
1399 (CK != OpenACCClauseKind::Reduction &&
1400 isa<CXXDependentScopeMemberExpr>(Val: CurVarExpr)))
1401 return VarExpr;
1402
1403 // There isn't really anything we can do in the case of a recovery expr, so
1404 // skip the diagnostic rather than produce a confusing diagnostic.
1405 if (isa<RecoveryExpr>(Val: CurVarExpr))
1406 return ExprError();
1407
1408 Diag(Loc: VarExpr->getExprLoc(), DiagID: diag::err_acc_not_a_var_ref)
1409 << (CK != OpenACCClauseKind::Reduction);
1410 return ExprError();
1411}
1412
1413ExprResult SemaOpenACC::ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc,
1414 Expr *LowerBound,
1415 SourceLocation ColonLoc,
1416 Expr *Length,
1417 SourceLocation RBLoc) {
1418 ASTContext &Context = getASTContext();
1419
1420 // Handle placeholders.
1421 if (Base->hasPlaceholderType() &&
1422 !Base->hasPlaceholderType(K: BuiltinType::ArraySection)) {
1423 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: Base);
1424 if (Result.isInvalid())
1425 return ExprError();
1426 Base = Result.get();
1427 }
1428 if (LowerBound && LowerBound->getType()->isNonOverloadPlaceholderType()) {
1429 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: LowerBound);
1430 if (Result.isInvalid())
1431 return ExprError();
1432 Result = SemaRef.DefaultLvalueConversion(E: Result.get());
1433 if (Result.isInvalid())
1434 return ExprError();
1435 LowerBound = Result.get();
1436 }
1437 if (Length && Length->getType()->isNonOverloadPlaceholderType()) {
1438 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: Length);
1439 if (Result.isInvalid())
1440 return ExprError();
1441 Result = SemaRef.DefaultLvalueConversion(E: Result.get());
1442 if (Result.isInvalid())
1443 return ExprError();
1444 Length = Result.get();
1445 }
1446
1447 // Check the 'base' value, it must be an array or pointer type, and not to/of
1448 // a function type.
1449 QualType OriginalBaseTy = ArraySectionExpr::getBaseOriginalType(Base);
1450 QualType ResultTy;
1451 if (!Base->isTypeDependent()) {
1452 if (OriginalBaseTy->isAnyPointerType()) {
1453 ResultTy = OriginalBaseTy->getPointeeType();
1454 } else if (OriginalBaseTy->isArrayType()) {
1455 ResultTy = OriginalBaseTy->getAsArrayTypeUnsafe()->getElementType();
1456 } else {
1457 return ExprError(
1458 Diag(Loc: Base->getExprLoc(), DiagID: diag::err_acc_typecheck_subarray_value)
1459 << Base->getSourceRange());
1460 }
1461
1462 if (ResultTy->isFunctionType()) {
1463 Diag(Loc: Base->getExprLoc(), DiagID: diag::err_acc_subarray_function_type)
1464 << ResultTy << Base->getSourceRange();
1465 return ExprError();
1466 }
1467
1468 if (SemaRef.RequireCompleteType(Loc: Base->getExprLoc(), T: ResultTy,
1469 DiagID: diag::err_acc_subarray_incomplete_type,
1470 Args: Base))
1471 return ExprError();
1472
1473 if (!Base->hasPlaceholderType(K: BuiltinType::ArraySection)) {
1474 ExprResult Result = SemaRef.DefaultFunctionArrayLvalueConversion(E: Base);
1475 if (Result.isInvalid())
1476 return ExprError();
1477 Base = Result.get();
1478 }
1479 }
1480
1481 auto GetRecovery = [&](Expr *E, QualType Ty) {
1482 ExprResult Recovery =
1483 SemaRef.CreateRecoveryExpr(Begin: E->getBeginLoc(), End: E->getEndLoc(), SubExprs: E, T: Ty);
1484 return Recovery.isUsable() ? Recovery.get() : nullptr;
1485 };
1486
1487 // Ensure both of the expressions are int-exprs.
1488 if (LowerBound && !LowerBound->isTypeDependent()) {
1489 ExprResult LBRes =
1490 ActOnIntExpr(DK: OpenACCDirectiveKind::Invalid, CK: OpenACCClauseKind::Invalid,
1491 Loc: LowerBound->getExprLoc(), IntExpr: LowerBound);
1492
1493 if (LBRes.isUsable())
1494 LBRes = SemaRef.DefaultLvalueConversion(E: LBRes.get());
1495 LowerBound =
1496 LBRes.isUsable() ? LBRes.get() : GetRecovery(LowerBound, Context.IntTy);
1497 }
1498
1499 if (Length && !Length->isTypeDependent()) {
1500 ExprResult LenRes =
1501 ActOnIntExpr(DK: OpenACCDirectiveKind::Invalid, CK: OpenACCClauseKind::Invalid,
1502 Loc: Length->getExprLoc(), IntExpr: Length);
1503
1504 if (LenRes.isUsable())
1505 LenRes = SemaRef.DefaultLvalueConversion(E: LenRes.get());
1506 Length =
1507 LenRes.isUsable() ? LenRes.get() : GetRecovery(Length, Context.IntTy);
1508 }
1509
1510 // Length is required if the base type is not an array of known bounds.
1511 if (!Length && (OriginalBaseTy.isNull() ||
1512 (!OriginalBaseTy->isDependentType() &&
1513 !OriginalBaseTy->isConstantArrayType() &&
1514 !OriginalBaseTy->isDependentSizedArrayType()))) {
1515 bool IsArray = !OriginalBaseTy.isNull() && OriginalBaseTy->isArrayType();
1516 Diag(Loc: ColonLoc, DiagID: diag::err_acc_subarray_no_length) << IsArray;
1517 // Fill in a dummy 'length' so that when we instantiate this we don't
1518 // double-diagnose here.
1519 ExprResult Recovery = SemaRef.CreateRecoveryExpr(
1520 Begin: ColonLoc, End: SourceLocation(), SubExprs: ArrayRef<Expr *>{std::nullopt},
1521 T: Context.IntTy);
1522 Length = Recovery.isUsable() ? Recovery.get() : nullptr;
1523 }
1524
1525 // Check the values of each of the arguments, they cannot be negative(we
1526 // assume), and if the array bound is known, must be within range. As we do
1527 // so, do our best to continue with evaluation, we can set the
1528 // value/expression to nullptr/nullopt if they are invalid, and treat them as
1529 // not present for the rest of evaluation.
1530
1531 // We don't have to check for dependence, because the dependent size is
1532 // represented as a different AST node.
1533 std::optional<llvm::APSInt> BaseSize;
1534 if (!OriginalBaseTy.isNull() && OriginalBaseTy->isConstantArrayType()) {
1535 const auto *ArrayTy = Context.getAsConstantArrayType(T: OriginalBaseTy);
1536 BaseSize = ArrayTy->getSize();
1537 }
1538
1539 auto GetBoundValue = [&](Expr *E) -> std::optional<llvm::APSInt> {
1540 if (!E || E->isInstantiationDependent())
1541 return std::nullopt;
1542
1543 Expr::EvalResult Res;
1544 if (!E->EvaluateAsInt(Result&: Res, Ctx: Context))
1545 return std::nullopt;
1546 return Res.Val.getInt();
1547 };
1548
1549 std::optional<llvm::APSInt> LowerBoundValue = GetBoundValue(LowerBound);
1550 std::optional<llvm::APSInt> LengthValue = GetBoundValue(Length);
1551
1552 // Check lower bound for negative or out of range.
1553 if (LowerBoundValue.has_value()) {
1554 if (LowerBoundValue->isNegative()) {
1555 Diag(Loc: LowerBound->getExprLoc(), DiagID: diag::err_acc_subarray_negative)
1556 << /*LowerBound=*/0 << toString(I: *LowerBoundValue, /*Radix=*/10);
1557 LowerBoundValue.reset();
1558 LowerBound = GetRecovery(LowerBound, LowerBound->getType());
1559 } else if (BaseSize.has_value() &&
1560 llvm::APSInt::compareValues(I1: *LowerBoundValue, I2: *BaseSize) >= 0) {
1561 // Lower bound (start index) must be less than the size of the array.
1562 Diag(Loc: LowerBound->getExprLoc(), DiagID: diag::err_acc_subarray_out_of_range)
1563 << /*LowerBound=*/0 << toString(I: *LowerBoundValue, /*Radix=*/10)
1564 << toString(I: *BaseSize, /*Radix=*/10);
1565 LowerBoundValue.reset();
1566 LowerBound = GetRecovery(LowerBound, LowerBound->getType());
1567 }
1568 }
1569
1570 // Check length for negative or out of range.
1571 if (LengthValue.has_value()) {
1572 if (LengthValue->isNegative()) {
1573 Diag(Loc: Length->getExprLoc(), DiagID: diag::err_acc_subarray_negative)
1574 << /*Length=*/1 << toString(I: *LengthValue, /*Radix=*/10);
1575 LengthValue.reset();
1576 Length = GetRecovery(Length, Length->getType());
1577 } else if (BaseSize.has_value() &&
1578 llvm::APSInt::compareValues(I1: *LengthValue, I2: *BaseSize) > 0) {
1579 // Length must be lessthan or EQUAL to the size of the array.
1580 Diag(Loc: Length->getExprLoc(), DiagID: diag::err_acc_subarray_out_of_range)
1581 << /*Length=*/1 << toString(I: *LengthValue, /*Radix=*/10)
1582 << toString(I: *BaseSize, /*Radix=*/10);
1583 LengthValue.reset();
1584 Length = GetRecovery(Length, Length->getType());
1585 }
1586 }
1587
1588 // Adding two APSInts requires matching sign, so extract that here.
1589 auto AddAPSInt = [](llvm::APSInt LHS, llvm::APSInt RHS) -> llvm::APSInt {
1590 if (LHS.isSigned() == RHS.isSigned())
1591 return LHS + RHS;
1592
1593 unsigned Width = std::max(a: LHS.getBitWidth(), b: RHS.getBitWidth()) + 1;
1594 return llvm::APSInt(LHS.sext(width: Width) + RHS.sext(width: Width), /*Signed=*/true);
1595 };
1596
1597 // If we know all 3 values, we can diagnose that the total value would be out
1598 // of range.
1599 if (BaseSize.has_value() && LowerBoundValue.has_value() &&
1600 LengthValue.has_value() &&
1601 llvm::APSInt::compareValues(I1: AddAPSInt(*LowerBoundValue, *LengthValue),
1602 I2: *BaseSize) > 0) {
1603 Diag(Loc: Base->getExprLoc(),
1604 DiagID: diag::err_acc_subarray_base_plus_length_out_of_range)
1605 << toString(I: *LowerBoundValue, /*Radix=*/10)
1606 << toString(I: *LengthValue, /*Radix=*/10)
1607 << toString(I: *BaseSize, /*Radix=*/10);
1608
1609 LowerBoundValue.reset();
1610 LowerBound = GetRecovery(LowerBound, LowerBound->getType());
1611 LengthValue.reset();
1612 Length = GetRecovery(Length, Length->getType());
1613 }
1614
1615 // If any part of the expression is dependent, return a dependent sub-array.
1616 QualType ArrayExprTy = Context.ArraySectionTy;
1617 if (Base->isTypeDependent() ||
1618 (LowerBound && LowerBound->isInstantiationDependent()) ||
1619 (Length && Length->isInstantiationDependent()))
1620 ArrayExprTy = Context.DependentTy;
1621
1622 return new (Context)
1623 ArraySectionExpr(Base, LowerBound, Length, ArrayExprTy, VK_LValue,
1624 OK_Ordinary, ColonLoc, RBLoc);
1625}
1626
1627bool SemaOpenACC::ActOnStartStmtDirective(OpenACCDirectiveKind K,
1628 SourceLocation StartLoc) {
1629 return diagnoseConstructAppertainment(S&: *this, K, StartLoc, /*IsStmt=*/true);
1630}
1631
1632StmtResult SemaOpenACC::ActOnEndStmtDirective(OpenACCDirectiveKind K,
1633 SourceLocation StartLoc,
1634 SourceLocation DirLoc,
1635 SourceLocation EndLoc,
1636 ArrayRef<OpenACCClause *> Clauses,
1637 StmtResult AssocStmt) {
1638 switch (K) {
1639 default:
1640 return StmtEmpty();
1641 case OpenACCDirectiveKind::Invalid:
1642 return StmtError();
1643 case OpenACCDirectiveKind::Parallel:
1644 case OpenACCDirectiveKind::Serial:
1645 case OpenACCDirectiveKind::Kernels: {
1646 auto *ComputeConstruct = OpenACCComputeConstruct::Create(
1647 C: getASTContext(), K, BeginLoc: StartLoc, DirectiveLoc: DirLoc, EndLoc, Clauses,
1648 StructuredBlock: AssocStmt.isUsable() ? AssocStmt.get() : nullptr,
1649 AssociatedLoopConstructs: ParentlessLoopConstructs);
1650
1651 ParentlessLoopConstructs.clear();
1652 return ComputeConstruct;
1653 }
1654 case OpenACCDirectiveKind::Loop: {
1655 auto *LoopConstruct = OpenACCLoopConstruct::Create(
1656 C: getASTContext(), BeginLoc: StartLoc, DirLoc, EndLoc, Clauses,
1657 Loop: AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
1658
1659 // If we are in the scope of a compute construct, add this to the list of
1660 // loop constructs that need assigning to the next closing compute
1661 // construct.
1662 if (InsideComputeConstruct)
1663 ParentlessLoopConstructs.push_back(Elt: LoopConstruct);
1664
1665 return LoopConstruct;
1666 }
1667 }
1668 llvm_unreachable("Unhandled case in directive handling?");
1669}
1670
1671StmtResult SemaOpenACC::ActOnAssociatedStmt(SourceLocation DirectiveLoc,
1672 OpenACCDirectiveKind K,
1673 StmtResult AssocStmt) {
1674 switch (K) {
1675 default:
1676 llvm_unreachable("Unimplemented associated statement application");
1677 case OpenACCDirectiveKind::Parallel:
1678 case OpenACCDirectiveKind::Serial:
1679 case OpenACCDirectiveKind::Kernels:
1680 // There really isn't any checking here that could happen. As long as we
1681 // have a statement to associate, this should be fine.
1682 // OpenACC 3.3 Section 6:
1683 // Structured Block: in C or C++, an executable statement, possibly
1684 // compound, with a single entry at the top and a single exit at the
1685 // bottom.
1686 // FIXME: Should we reject DeclStmt's here? The standard isn't clear, and
1687 // an interpretation of it is to allow this and treat the initializer as
1688 // the 'structured block'.
1689 return AssocStmt;
1690 case OpenACCDirectiveKind::Loop:
1691 if (AssocStmt.isUsable() &&
1692 !isa<CXXForRangeStmt, ForStmt>(Val: AssocStmt.get())) {
1693 Diag(Loc: AssocStmt.get()->getBeginLoc(), DiagID: diag::err_acc_loop_not_for_loop);
1694 Diag(Loc: DirectiveLoc, DiagID: diag::note_acc_construct_here) << K;
1695 return StmtError();
1696 }
1697 // TODO OpenACC: 2.9 ~ line 2010 specifies that the associated loop has some
1698 // restrictions when there is a 'seq' clause in place. We probably need to
1699 // implement that, including piping in the clauses here.
1700 return AssocStmt;
1701 }
1702 llvm_unreachable("Invalid associated statement application");
1703}
1704
1705bool SemaOpenACC::ActOnStartDeclDirective(OpenACCDirectiveKind K,
1706 SourceLocation StartLoc) {
1707 return diagnoseConstructAppertainment(S&: *this, K, StartLoc, /*IsStmt=*/false);
1708}
1709
1710DeclGroupRef SemaOpenACC::ActOnEndDeclDirective() { return DeclGroupRef{}; }
1711