clang 19.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::Parallel:
34 case OpenACCDirectiveKind::Serial:
35 case OpenACCDirectiveKind::Kernels:
36 if (!IsStmt)
37 return S.Diag(StartLoc, diag::err_acc_construct_appertainment) << K;
38 break;
39 }
40 return false;
41}
42
43bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind,
44 OpenACCClauseKind ClauseKind) {
45 switch (ClauseKind) {
46 // FIXME: For each clause as we implement them, we can add the
47 // 'legalization' list here.
48 case OpenACCClauseKind::Default:
49 switch (DirectiveKind) {
50 case OpenACCDirectiveKind::Parallel:
51 case OpenACCDirectiveKind::Serial:
52 case OpenACCDirectiveKind::Kernels:
53 case OpenACCDirectiveKind::ParallelLoop:
54 case OpenACCDirectiveKind::SerialLoop:
55 case OpenACCDirectiveKind::KernelsLoop:
56 case OpenACCDirectiveKind::Data:
57 return true;
58 default:
59 return false;
60 }
61 case OpenACCClauseKind::If:
62 switch (DirectiveKind) {
63 case OpenACCDirectiveKind::Parallel:
64 case OpenACCDirectiveKind::Serial:
65 case OpenACCDirectiveKind::Kernels:
66 case OpenACCDirectiveKind::Data:
67 case OpenACCDirectiveKind::EnterData:
68 case OpenACCDirectiveKind::ExitData:
69 case OpenACCDirectiveKind::HostData:
70 case OpenACCDirectiveKind::Init:
71 case OpenACCDirectiveKind::Shutdown:
72 case OpenACCDirectiveKind::Set:
73 case OpenACCDirectiveKind::Update:
74 case OpenACCDirectiveKind::Wait:
75 case OpenACCDirectiveKind::ParallelLoop:
76 case OpenACCDirectiveKind::SerialLoop:
77 case OpenACCDirectiveKind::KernelsLoop:
78 return true;
79 default:
80 return false;
81 }
82 case OpenACCClauseKind::Self:
83 switch (DirectiveKind) {
84 case OpenACCDirectiveKind::Parallel:
85 case OpenACCDirectiveKind::Serial:
86 case OpenACCDirectiveKind::Kernels:
87 case OpenACCDirectiveKind::Update:
88 case OpenACCDirectiveKind::ParallelLoop:
89 case OpenACCDirectiveKind::SerialLoop:
90 case OpenACCDirectiveKind::KernelsLoop:
91 return true;
92 default:
93 return false;
94 }
95 case OpenACCClauseKind::NumGangs:
96 case OpenACCClauseKind::NumWorkers:
97 case OpenACCClauseKind::VectorLength:
98 switch (DirectiveKind) {
99 case OpenACCDirectiveKind::Parallel:
100 case OpenACCDirectiveKind::Kernels:
101 case OpenACCDirectiveKind::ParallelLoop:
102 case OpenACCDirectiveKind::KernelsLoop:
103 return true;
104 default:
105 return false;
106 }
107 case OpenACCClauseKind::FirstPrivate:
108 switch (DirectiveKind) {
109 case OpenACCDirectiveKind::Parallel:
110 case OpenACCDirectiveKind::Serial:
111 case OpenACCDirectiveKind::ParallelLoop:
112 case OpenACCDirectiveKind::SerialLoop:
113 return true;
114 default:
115 return false;
116 }
117 case OpenACCClauseKind::Private:
118 switch (DirectiveKind) {
119 case OpenACCDirectiveKind::Parallel:
120 case OpenACCDirectiveKind::Serial:
121 case OpenACCDirectiveKind::Loop:
122 case OpenACCDirectiveKind::ParallelLoop:
123 case OpenACCDirectiveKind::SerialLoop:
124 case OpenACCDirectiveKind::KernelsLoop:
125 return true;
126 default:
127 return false;
128 }
129 case OpenACCClauseKind::NoCreate:
130 switch (DirectiveKind) {
131 case OpenACCDirectiveKind::Parallel:
132 case OpenACCDirectiveKind::Serial:
133 case OpenACCDirectiveKind::Kernels:
134 case OpenACCDirectiveKind::Data:
135 case OpenACCDirectiveKind::ParallelLoop:
136 case OpenACCDirectiveKind::SerialLoop:
137 case OpenACCDirectiveKind::KernelsLoop:
138 return true;
139 default:
140 return false;
141 }
142 case OpenACCClauseKind::Present:
143 switch (DirectiveKind) {
144 case OpenACCDirectiveKind::Parallel:
145 case OpenACCDirectiveKind::Serial:
146 case OpenACCDirectiveKind::Kernels:
147 case OpenACCDirectiveKind::Data:
148 case OpenACCDirectiveKind::Declare:
149 case OpenACCDirectiveKind::ParallelLoop:
150 case OpenACCDirectiveKind::SerialLoop:
151 case OpenACCDirectiveKind::KernelsLoop:
152 return true;
153 default:
154 return false;
155 }
156
157 case OpenACCClauseKind::Copy:
158 case OpenACCClauseKind::PCopy:
159 case OpenACCClauseKind::PresentOrCopy:
160 switch (DirectiveKind) {
161 case OpenACCDirectiveKind::Parallel:
162 case OpenACCDirectiveKind::Serial:
163 case OpenACCDirectiveKind::Kernels:
164 case OpenACCDirectiveKind::Data:
165 case OpenACCDirectiveKind::Declare:
166 case OpenACCDirectiveKind::ParallelLoop:
167 case OpenACCDirectiveKind::SerialLoop:
168 case OpenACCDirectiveKind::KernelsLoop:
169 return true;
170 default:
171 return false;
172 }
173 case OpenACCClauseKind::Attach:
174 switch (DirectiveKind) {
175 case OpenACCDirectiveKind::Parallel:
176 case OpenACCDirectiveKind::Serial:
177 case OpenACCDirectiveKind::Kernels:
178 case OpenACCDirectiveKind::Data:
179 case OpenACCDirectiveKind::EnterData:
180 case OpenACCDirectiveKind::ParallelLoop:
181 case OpenACCDirectiveKind::SerialLoop:
182 case OpenACCDirectiveKind::KernelsLoop:
183 return true;
184 default:
185 return false;
186 }
187 case OpenACCClauseKind::DevicePtr:
188 switch (DirectiveKind) {
189 case OpenACCDirectiveKind::Parallel:
190 case OpenACCDirectiveKind::Serial:
191 case OpenACCDirectiveKind::Kernels:
192 case OpenACCDirectiveKind::Data:
193 case OpenACCDirectiveKind::Declare:
194 case OpenACCDirectiveKind::ParallelLoop:
195 case OpenACCDirectiveKind::SerialLoop:
196 case OpenACCDirectiveKind::KernelsLoop:
197 return true;
198 default:
199 return false;
200 }
201 case OpenACCClauseKind::Async:
202 switch (DirectiveKind) {
203 case OpenACCDirectiveKind::Parallel:
204 case OpenACCDirectiveKind::Serial:
205 case OpenACCDirectiveKind::Kernels:
206 case OpenACCDirectiveKind::Data:
207 case OpenACCDirectiveKind::EnterData:
208 case OpenACCDirectiveKind::ExitData:
209 case OpenACCDirectiveKind::Set:
210 case OpenACCDirectiveKind::Update:
211 case OpenACCDirectiveKind::Wait:
212 case OpenACCDirectiveKind::ParallelLoop:
213 case OpenACCDirectiveKind::SerialLoop:
214 case OpenACCDirectiveKind::KernelsLoop:
215 return true;
216 default:
217 return false;
218 }
219 case OpenACCClauseKind::Wait:
220 switch (DirectiveKind) {
221 case OpenACCDirectiveKind::Parallel:
222 case OpenACCDirectiveKind::Serial:
223 case OpenACCDirectiveKind::Kernels:
224 case OpenACCDirectiveKind::Data:
225 case OpenACCDirectiveKind::EnterData:
226 case OpenACCDirectiveKind::ExitData:
227 case OpenACCDirectiveKind::Update:
228 case OpenACCDirectiveKind::ParallelLoop:
229 case OpenACCDirectiveKind::SerialLoop:
230 case OpenACCDirectiveKind::KernelsLoop:
231 return true;
232 default:
233 return false;
234 }
235
236 default:
237 // Do nothing so we can go to the 'unimplemented' diagnostic instead.
238 return true;
239 }
240 llvm_unreachable("Invalid clause kind");
241}
242
243bool checkAlreadyHasClauseOfKind(
246 const auto *Itr = llvm::find_if(ExistingClauses, [&](const OpenACCClause *C) {
247 return C->getClauseKind() == Clause.getClauseKind();
248 });
249 if (Itr != ExistingClauses.end()) {
250 S.Diag(Clause.getBeginLoc(), diag::err_acc_duplicate_clause_disallowed)
251 << Clause.getDirectiveKind() << Clause.getClauseKind();
252 S.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
253 return true;
254 }
255 return false;
256}
257
258/// Implement check from OpenACC3.3: section 2.5.4:
259/// Only the async, wait, num_gangs, num_workers, and vector_length clauses may
260/// follow a device_type clause.
261bool checkValidAfterDeviceType(
262 SemaOpenACC &S, const OpenACCDeviceTypeClause &DeviceTypeClause,
263 const SemaOpenACC::OpenACCParsedClause &NewClause) {
264 // This is only a requirement on compute constructs so far, so this is fine
265 // otherwise.
266 if (!isOpenACCComputeDirectiveKind(NewClause.getDirectiveKind()))
267 return false;
268 switch (NewClause.getClauseKind()) {
269 case OpenACCClauseKind::Async:
270 case OpenACCClauseKind::Wait:
271 case OpenACCClauseKind::NumGangs:
272 case OpenACCClauseKind::NumWorkers:
273 case OpenACCClauseKind::VectorLength:
274 case OpenACCClauseKind::DType:
275 case OpenACCClauseKind::DeviceType:
276 return false;
277 default:
278 S.Diag(NewClause.getBeginLoc(), diag::err_acc_clause_after_device_type)
279 << NewClause.getClauseKind() << DeviceTypeClause.getClauseKind();
280 S.Diag(DeviceTypeClause.getBeginLoc(), diag::note_acc_previous_clause_here);
281 return true;
282 }
283}
284
285} // namespace
286
288
291 OpenACCParsedClause &Clause) {
293 return nullptr;
294
295 // Diagnose that we don't support this clause on this directive.
296 if (!doesClauseApplyToDirective(Clause.getDirectiveKind(),
297 Clause.getClauseKind())) {
298 Diag(Clause.getBeginLoc(), diag::err_acc_clause_appertainment)
299 << Clause.getDirectiveKind() << Clause.getClauseKind();
300 return nullptr;
301 }
302
303 if (const auto *DevTypeClause =
304 llvm::find_if(ExistingClauses,
305 [&](const OpenACCClause *C) {
306 return isa<OpenACCDeviceTypeClause>(C);
307 });
308 DevTypeClause != ExistingClauses.end()) {
309 if (checkValidAfterDeviceType(
310 *this, *cast<OpenACCDeviceTypeClause>(*DevTypeClause), Clause))
311 return nullptr;
312 }
313
314 switch (Clause.getClauseKind()) {
316 // Restrictions only properly implemented on 'compute' constructs, and
317 // 'compute' constructs are the only construct that can do anything with
318 // this yet, so skip/treat as unimplemented in this case.
320 break;
321
322 // Don't add an invalid clause to the AST.
324 return nullptr;
325
326 // OpenACC 3.3, Section 2.5.4:
327 // At most one 'default' clause may appear, and it must have a value of
328 // either 'none' or 'present'.
329 // Second half of the sentence is diagnosed during parsing.
330 if (checkAlreadyHasClauseOfKind(*this, ExistingClauses, Clause))
331 return nullptr;
332
334 getASTContext(), Clause.getDefaultClauseKind(), Clause.getBeginLoc(),
335 Clause.getLParenLoc(), Clause.getEndLoc());
336 }
337
339 // Restrictions only properly implemented on 'compute' constructs, and
340 // 'compute' constructs are the only construct that can do anything with
341 // this yet, so skip/treat as unimplemented in this case.
343 break;
344
345 // There is no prose in the standard that says duplicates aren't allowed,
346 // but this diagnostic is present in other compilers, as well as makes
347 // sense.
348 if (checkAlreadyHasClauseOfKind(*this, ExistingClauses, Clause))
349 return nullptr;
350
351 // The parser has ensured that we have a proper condition expr, so there
352 // isn't really much to do here.
353
354 // If the 'if' clause is true, it makes the 'self' clause have no effect,
355 // diagnose that here.
356 // TODO OpenACC: When we add these two to other constructs, we might not
357 // want to warn on this (for example, 'update').
358 const auto *Itr =
359 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSelfClause>);
360 if (Itr != ExistingClauses.end()) {
361 Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict);
362 Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
363 }
364
366 getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(),
367 Clause.getConditionExpr(), Clause.getEndLoc());
368 }
369
371 // Restrictions only properly implemented on 'compute' constructs, and
372 // 'compute' constructs are the only construct that can do anything with
373 // this yet, so skip/treat as unimplemented in this case.
375 break;
376
377 // TODO OpenACC: When we implement this for 'update', this takes a
378 // 'var-list' instead of a condition expression, so semantics/handling has
379 // to happen differently here.
380
381 // There is no prose in the standard that says duplicates aren't allowed,
382 // but this diagnostic is present in other compilers, as well as makes
383 // sense.
384 if (checkAlreadyHasClauseOfKind(*this, ExistingClauses, Clause))
385 return nullptr;
386
387 // If the 'if' clause is true, it makes the 'self' clause have no effect,
388 // diagnose that here.
389 // TODO OpenACC: When we add these two to other constructs, we might not
390 // want to warn on this (for example, 'update').
391 const auto *Itr =
392 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCIfClause>);
393 if (Itr != ExistingClauses.end()) {
394 Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict);
395 Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
396 }
397
399 getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(),
400 Clause.getConditionExpr(), Clause.getEndLoc());
401 }
403 // Restrictions only properly implemented on 'compute' constructs, and
404 // 'compute' constructs are the only construct that can do anything with
405 // this yet, so skip/treat as unimplemented in this case.
407 break;
408
409 // There is no prose in the standard that says duplicates aren't allowed,
410 // but this diagnostic is present in other compilers, as well as makes
411 // sense.
412 if (checkAlreadyHasClauseOfKind(*this, ExistingClauses, Clause))
413 return nullptr;
414
415 if (Clause.getIntExprs().empty())
416 Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args)
417 << /*NoArgs=*/0;
418
419 unsigned MaxArgs =
422 ? 3
423 : 1;
424 if (Clause.getIntExprs().size() > MaxArgs)
425 Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args)
426 << /*NoArgs=*/1 << Clause.getDirectiveKind() << MaxArgs
427 << Clause.getIntExprs().size();
428
429 // Create the AST node for the clause even if the number of expressions is
430 // incorrect.
432 getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(),
433 Clause.getIntExprs(), Clause.getEndLoc());
434 break;
435 }
437 // Restrictions only properly implemented on 'compute' constructs, and
438 // 'compute' constructs are the only construct that can do anything with
439 // this yet, so skip/treat as unimplemented in this case.
441 break;
442
443 // There is no prose in the standard that says duplicates aren't allowed,
444 // but this diagnostic is present in other compilers, as well as makes
445 // sense.
446 if (checkAlreadyHasClauseOfKind(*this, ExistingClauses, Clause))
447 return nullptr;
448
449 assert(Clause.getIntExprs().size() == 1 &&
450 "Invalid number of expressions for NumWorkers");
452 getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(),
453 Clause.getIntExprs()[0], Clause.getEndLoc());
454 }
456 // Restrictions only properly implemented on 'compute' constructs, and
457 // 'compute' constructs are the only construct that can do anything with
458 // this yet, so skip/treat as unimplemented in this case.
460 break;
461
462 // There is no prose in the standard that says duplicates aren't allowed,
463 // but this diagnostic is present in other compilers, as well as makes
464 // sense.
465 if (checkAlreadyHasClauseOfKind(*this, ExistingClauses, Clause))
466 return nullptr;
467
468 assert(Clause.getIntExprs().size() == 1 &&
469 "Invalid number of expressions for VectorLength");
471 getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(),
472 Clause.getIntExprs()[0], Clause.getEndLoc());
473 }
475 // Restrictions only properly implemented on 'compute' constructs, and
476 // 'compute' constructs are the only construct that can do anything with
477 // this yet, so skip/treat as unimplemented in this case.
479 break;
480
481 // There is no prose in the standard that says duplicates aren't allowed,
482 // but this diagnostic is present in other compilers, as well as makes
483 // sense.
484 if (checkAlreadyHasClauseOfKind(*this, ExistingClauses, Clause))
485 return nullptr;
486
487 assert(Clause.getNumIntExprs() < 2 &&
488 "Invalid number of expressions for Async");
489
491 getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(),
492 Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr,
493 Clause.getEndLoc());
494 }
496 // Restrictions only properly implemented on 'compute' constructs, and
497 // 'compute' constructs are the only construct that can do anything with
498 // this yet, so skip/treat as unimplemented in this case.
500 break;
501
502 // ActOnVar ensured that everything is a valid variable reference, so there
503 // really isn't anything to do here. GCC does some duplicate-finding, though
504 // it isn't apparent in the standard where this is justified.
505
507 getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(),
508 Clause.getVarList(), Clause.getEndLoc());
509 }
511 // Restrictions only properly implemented on 'compute' constructs, and
512 // 'compute' constructs are the only construct that can do anything with
513 // this yet, so skip/treat as unimplemented in this case.
515 break;
516
517 // ActOnVar ensured that everything is a valid variable reference, so there
518 // really isn't anything to do here. GCC does some duplicate-finding, though
519 // it isn't apparent in the standard where this is justified.
520
522 getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(),
523 Clause.getVarList(), Clause.getEndLoc());
524 }
526 // Restrictions only properly implemented on 'compute' constructs, and
527 // 'compute' constructs are the only construct that can do anything with
528 // this yet, so skip/treat as unimplemented in this case.
530 break;
531
532 // ActOnVar ensured that everything is a valid variable reference, so there
533 // really isn't anything to do here. GCC does some duplicate-finding, though
534 // it isn't apparent in the standard where this is justified.
535
537 getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(),
538 Clause.getVarList(), Clause.getEndLoc());
539 }
541 // Restrictions only properly implemented on 'compute' constructs, and
542 // 'compute' constructs are the only construct that can do anything with
543 // this yet, so skip/treat as unimplemented in this case.
545 break;
546
547 // ActOnVar ensured that everything is a valid variable reference, so there
548 // really isn't anything to do here. GCC does some duplicate-finding, though
549 // it isn't apparent in the standard where this is justified.
550
552 getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(),
553 Clause.getVarList(), Clause.getEndLoc());
554 }
557 Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name)
559 LLVM_FALLTHROUGH;
561 // Restrictions only properly implemented on 'compute' constructs, and
562 // 'compute' constructs are the only construct that can do anything with
563 // this yet, so skip/treat as unimplemented in this case.
565 break;
566
567 // ActOnVar ensured that everything is a valid variable reference, so there
568 // really isn't anything to do here. GCC does some duplicate-finding, though
569 // it isn't apparent in the standard where this is justified.
570
572 getASTContext(), Clause.getClauseKind(), Clause.getBeginLoc(),
573 Clause.getLParenLoc(), Clause.getVarList(), Clause.getEndLoc());
574 }
577 Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name)
579 LLVM_FALLTHROUGH;
581 // Restrictions only properly implemented on 'compute' constructs, and
582 // 'compute' constructs are the only construct that can do anything with
583 // this yet, so skip/treat as unimplemented in this case.
585 break;
586
587 // ActOnVar ensured that everything is a valid variable reference, so there
588 // really isn't anything to do here. GCC does some duplicate-finding, though
589 // it isn't apparent in the standard where this is justified.
590
592 getASTContext(), Clause.getClauseKind(), Clause.getBeginLoc(),
593 Clause.getLParenLoc(), Clause.isReadOnly(), Clause.getVarList(),
594 Clause.getEndLoc());
595 }
598 Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name)
600 LLVM_FALLTHROUGH;
602 // Restrictions only properly implemented on 'compute' constructs, and
603 // 'compute' constructs are the only construct that can do anything with
604 // this yet, so skip/treat as unimplemented in this case.
606 break;
607
608 // ActOnVar ensured that everything is a valid variable reference, so there
609 // really isn't anything to do here. GCC does some duplicate-finding, though
610 // it isn't apparent in the standard where this is justified.
611
613 getASTContext(), Clause.getClauseKind(), Clause.getBeginLoc(),
614 Clause.getLParenLoc(), Clause.isZero(), Clause.getVarList(),
615 Clause.getEndLoc());
616 }
619 Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name)
621 LLVM_FALLTHROUGH;
623 // Restrictions only properly implemented on 'compute' constructs, and
624 // 'compute' constructs are the only construct that can do anything with
625 // this yet, so skip/treat as unimplemented in this case.
627 break;
628
629 // ActOnVar ensured that everything is a valid variable reference, so there
630 // really isn't anything to do here. GCC does some duplicate-finding, though
631 // it isn't apparent in the standard where this is justified.
632
634 Clause.getBeginLoc(),
635 Clause.getLParenLoc(), Clause.isZero(),
636 Clause.getVarList(), Clause.getEndLoc());
637 }
639 // Restrictions only properly implemented on 'compute' constructs, and
640 // 'compute' constructs are the only construct that can do anything with
641 // this yet, so skip/treat as unimplemented in this case.
643 break;
644
645 // ActOnVar ensured that everything is a valid variable reference, but we
646 // still have to make sure it is a pointer type.
647 llvm::SmallVector<Expr *> VarList{Clause.getVarList().begin(),
648 Clause.getVarList().end()};
649 VarList.erase(std::remove_if(VarList.begin(), VarList.end(), [&](Expr *E) {
650 return CheckVarIsPointerType(OpenACCClauseKind::Attach, E);
651 }), VarList.end());
652 Clause.setVarListDetails(VarList,
653 /*IsReadOnly=*/false, /*IsZero=*/false);
654
656 Clause.getLParenLoc(),
657 Clause.getVarList(), Clause.getEndLoc());
658 }
660 // Restrictions only properly implemented on 'compute' constructs, and
661 // 'compute' constructs are the only construct that can do anything with
662 // this yet, so skip/treat as unimplemented in this case.
664 break;
665
666 // ActOnVar ensured that everything is a valid variable reference, but we
667 // still have to make sure it is a pointer type.
668 llvm::SmallVector<Expr *> VarList{Clause.getVarList().begin(),
669 Clause.getVarList().end()};
670 VarList.erase(std::remove_if(VarList.begin(), VarList.end(), [&](Expr *E) {
671 return CheckVarIsPointerType(OpenACCClauseKind::DevicePtr, E);
672 }), VarList.end());
673 Clause.setVarListDetails(VarList,
674 /*IsReadOnly=*/false, /*IsZero=*/false);
675
677 getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(),
678 Clause.getVarList(), Clause.getEndLoc());
679 }
681 // Restrictions only properly implemented on 'compute' constructs, and
682 // 'compute' constructs are the only construct that can do anything with
683 // this yet, so skip/treat as unimplemented in this case.
685 break;
686
688 getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(),
689 Clause.getDevNumExpr(), Clause.getQueuesLoc(), Clause.getQueueIdExprs(),
690 Clause.getEndLoc());
691 }
694 // Restrictions only properly implemented on 'compute' constructs, and
695 // 'compute' constructs are the only construct that can do anything with
696 // this yet, so skip/treat as unimplemented in this case.
698 break;
699
700 // TODO OpenACC: Once we get enough of the CodeGen implemented that we have
701 // a source for the list of valid architectures, we need to warn on unknown
702 // identifiers here.
703
705 getASTContext(), Clause.getClauseKind(), Clause.getBeginLoc(),
706 Clause.getLParenLoc(), Clause.getDeviceTypeArchitectures(),
707 Clause.getEndLoc());
708 }
709 default:
710 break;
711 }
712
713 Diag(Clause.getBeginLoc(), diag::warn_acc_clause_unimplemented)
714 << Clause.getClauseKind();
715 return nullptr;
716}
717
719 SourceLocation StartLoc) {
720 switch (K) {
722 // Nothing to do here, an invalid kind has nothing we can check here. We
723 // want to continue parsing clauses as far as we can, so we will just
724 // ensure that we can still work and don't check any construct-specific
725 // rules anywhere.
726 break;
730 // Nothing to do here, there is no real legalization that needs to happen
731 // here as these constructs do not take any arguments.
732 break;
733 default:
734 Diag(StartLoc, diag::warn_acc_construct_unimplemented) << K;
735 break;
736 }
737}
738
741 Expr *IntExpr) {
742
743 assert(((DK != OpenACCDirectiveKind::Invalid &&
749 "Only one of directive or clause kind should be provided");
750
751 class IntExprConverter : public Sema::ICEConvertDiagnoser {
752 OpenACCDirectiveKind DirectiveKind;
753 OpenACCClauseKind ClauseKind;
754 Expr *IntExpr;
755
756 // gets the index into the diagnostics so we can use this for clauses,
757 // directives, and sub array.s
758 unsigned getDiagKind() const {
759 if (ClauseKind != OpenACCClauseKind::Invalid)
760 return 0;
761 if (DirectiveKind != OpenACCDirectiveKind::Invalid)
762 return 1;
763 return 2;
764 }
765
766 public:
767 IntExprConverter(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
768 Expr *IntExpr)
769 : ICEConvertDiagnoser(/*AllowScopedEnumerations=*/false,
770 /*Suppress=*/false,
771 /*SuppressConversion=*/true),
772 DirectiveKind(DK), ClauseKind(CK), IntExpr(IntExpr) {}
773
774 bool match(QualType T) override {
775 // OpenACC spec just calls this 'integer expression' as having an
776 // 'integer type', so fall back on C99's 'integer type'.
777 return T->isIntegerType();
778 }
780 QualType T) override {
781 return S.Diag(Loc, diag::err_acc_int_expr_requires_integer)
782 << getDiagKind() << ClauseKind << DirectiveKind << T;
783 }
784
786 diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) override {
787 return S.Diag(Loc, diag::err_acc_int_expr_incomplete_class_type)
788 << T << IntExpr->getSourceRange();
789 }
790
792 diagnoseExplicitConv(Sema &S, SourceLocation Loc, QualType T,
793 QualType ConvTy) override {
794 return S.Diag(Loc, diag::err_acc_int_expr_explicit_conversion)
795 << T << ConvTy;
796 }
797
798 SemaBase::SemaDiagnosticBuilder noteExplicitConv(Sema &S,
799 CXXConversionDecl *Conv,
800 QualType ConvTy) override {
801 return S.Diag(Conv->getLocation(), diag::note_acc_int_expr_conversion)
802 << ConvTy->isEnumeralType() << ConvTy;
803 }
804
806 diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) override {
807 return S.Diag(Loc, diag::err_acc_int_expr_multiple_conversions) << T;
808 }
809
811 noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
812 return S.Diag(Conv->getLocation(), diag::note_acc_int_expr_conversion)
813 << ConvTy->isEnumeralType() << ConvTy;
814 }
815
817 diagnoseConversion(Sema &S, SourceLocation Loc, QualType T,
818 QualType ConvTy) override {
819 llvm_unreachable("conversion functions are permitted");
820 }
821 } IntExprDiagnoser(DK, CK, IntExpr);
822
824 Loc, IntExpr, IntExprDiagnoser);
825 if (IntExprResult.isInvalid())
826 return ExprError();
827
828 IntExpr = IntExprResult.get();
829 if (!IntExpr->isTypeDependent() && !IntExpr->getType()->isIntegerType())
830 return ExprError();
831
832 // TODO OpenACC: Do we want to perform usual unary conversions here? When
833 // doing codegen we might find that is necessary, but skip it for now.
834 return IntExpr;
835}
836
838 Expr *VarExpr) {
839 // We already know that VarExpr is a proper reference to a variable, so we
840 // should be able to just take the type of the expression to get the type of
841 // the referenced variable.
842
843 // We've already seen an error, don't diagnose anything else.
844 if (!VarExpr || VarExpr->containsErrors())
845 return false;
846
847 if (isa<ArraySectionExpr>(VarExpr->IgnoreParenImpCasts()) ||
848 VarExpr->hasPlaceholderType(BuiltinType::ArraySection)) {
849 Diag(VarExpr->getExprLoc(), diag::err_array_section_use) << /*OpenACC=*/0;
850 Diag(VarExpr->getExprLoc(), diag::note_acc_expected_pointer_var);
851 return true;
852 }
853
854 QualType Ty = VarExpr->getType();
856
857 // Nothing we can do if this is a dependent type.
858 if (Ty->isDependentType())
859 return false;
860
861 if (!Ty->isPointerType())
862 return Diag(VarExpr->getExprLoc(), diag::err_acc_var_not_pointer_type)
863 << ClauseKind << Ty;
864 return false;
865}
866
868 // We still need to retain the array subscript/subarray exprs, so work on a
869 // copy.
870 Expr *CurVarExpr = VarExpr->IgnoreParenImpCasts();
871
872 // Sub-arrays/subscript-exprs are fine as long as the base is a
873 // VarExpr/MemberExpr. So strip all of those off.
874 while (isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
875 if (auto *SubScrpt = dyn_cast<ArraySubscriptExpr>(CurVarExpr))
876 CurVarExpr = SubScrpt->getBase()->IgnoreParenImpCasts();
877 else
878 CurVarExpr =
879 cast<ArraySectionExpr>(CurVarExpr)->getBase()->IgnoreParenImpCasts();
880 }
881
882 // References to a VarDecl are fine.
883 if (const auto *DRE = dyn_cast<DeclRefExpr>(CurVarExpr)) {
884 if (isa<VarDecl, NonTypeTemplateParmDecl>(
885 DRE->getDecl()->getCanonicalDecl()))
886 return VarExpr;
887 }
888
889 // A MemberExpr that references a Field is valid.
890 if (const auto *ME = dyn_cast<MemberExpr>(CurVarExpr)) {
891 if (isa<FieldDecl>(ME->getMemberDecl()->getCanonicalDecl()))
892 return VarExpr;
893 }
894
895 // Referring to 'this' is always OK.
896 if (isa<CXXThisExpr>(CurVarExpr))
897 return VarExpr;
898
899 // Nothing really we can do here, as these are dependent. So just return they
900 // are valid.
901 if (isa<DependentScopeDeclRefExpr, CXXDependentScopeMemberExpr>(CurVarExpr))
902 return VarExpr;
903
904 // There isn't really anything we can do in the case of a recovery expr, so
905 // skip the diagnostic rather than produce a confusing diagnostic.
906 if (isa<RecoveryExpr>(CurVarExpr))
907 return ExprError();
908
909 Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref);
910 return ExprError();
911}
912
914 Expr *LowerBound,
915 SourceLocation ColonLoc,
916 Expr *Length,
917 SourceLocation RBLoc) {
918 ASTContext &Context = getASTContext();
919
920 // Handle placeholders.
921 if (Base->hasPlaceholderType() &&
922 !Base->hasPlaceholderType(BuiltinType::ArraySection)) {
924 if (Result.isInvalid())
925 return ExprError();
926 Base = Result.get();
927 }
928 if (LowerBound && LowerBound->getType()->isNonOverloadPlaceholderType()) {
930 if (Result.isInvalid())
931 return ExprError();
933 if (Result.isInvalid())
934 return ExprError();
935 LowerBound = Result.get();
936 }
937 if (Length && Length->getType()->isNonOverloadPlaceholderType()) {
939 if (Result.isInvalid())
940 return ExprError();
942 if (Result.isInvalid())
943 return ExprError();
944 Length = Result.get();
945 }
946
947 // Check the 'base' value, it must be an array or pointer type, and not to/of
948 // a function type.
950 QualType ResultTy;
951 if (!Base->isTypeDependent()) {
952 if (OriginalBaseTy->isAnyPointerType()) {
953 ResultTy = OriginalBaseTy->getPointeeType();
954 } else if (OriginalBaseTy->isArrayType()) {
955 ResultTy = OriginalBaseTy->getAsArrayTypeUnsafe()->getElementType();
956 } else {
957 return ExprError(
958 Diag(Base->getExprLoc(), diag::err_acc_typecheck_subarray_value)
959 << Base->getSourceRange());
960 }
961
962 if (ResultTy->isFunctionType()) {
963 Diag(Base->getExprLoc(), diag::err_acc_subarray_function_type)
964 << ResultTy << Base->getSourceRange();
965 return ExprError();
966 }
967
968 if (SemaRef.RequireCompleteType(Base->getExprLoc(), ResultTy,
969 diag::err_acc_subarray_incomplete_type,
970 Base))
971 return ExprError();
972
973 if (!Base->hasPlaceholderType(BuiltinType::ArraySection)) {
975 if (Result.isInvalid())
976 return ExprError();
977 Base = Result.get();
978 }
979 }
980
981 auto GetRecovery = [&](Expr *E, QualType Ty) {
982 ExprResult Recovery =
984 return Recovery.isUsable() ? Recovery.get() : nullptr;
985 };
986
987 // Ensure both of the expressions are int-exprs.
988 if (LowerBound && !LowerBound->isTypeDependent()) {
989 ExprResult LBRes =
991 LowerBound->getExprLoc(), LowerBound);
992
993 if (LBRes.isUsable())
994 LBRes = SemaRef.DefaultLvalueConversion(LBRes.get());
995 LowerBound =
996 LBRes.isUsable() ? LBRes.get() : GetRecovery(LowerBound, Context.IntTy);
997 }
998
999 if (Length && !Length->isTypeDependent()) {
1000 ExprResult LenRes =
1002 Length->getExprLoc(), Length);
1003
1004 if (LenRes.isUsable())
1005 LenRes = SemaRef.DefaultLvalueConversion(LenRes.get());
1006 Length =
1007 LenRes.isUsable() ? LenRes.get() : GetRecovery(Length, Context.IntTy);
1008 }
1009
1010 // Length is required if the base type is not an array of known bounds.
1011 if (!Length && (OriginalBaseTy.isNull() ||
1012 (!OriginalBaseTy->isDependentType() &&
1013 !OriginalBaseTy->isConstantArrayType() &&
1014 !OriginalBaseTy->isDependentSizedArrayType()))) {
1015 bool IsArray = !OriginalBaseTy.isNull() && OriginalBaseTy->isArrayType();
1016 Diag(ColonLoc, diag::err_acc_subarray_no_length) << IsArray;
1017 // Fill in a dummy 'length' so that when we instantiate this we don't
1018 // double-diagnose here.
1020 ColonLoc, SourceLocation(), ArrayRef<Expr *>{std::nullopt},
1021 Context.IntTy);
1022 Length = Recovery.isUsable() ? Recovery.get() : nullptr;
1023 }
1024
1025 // Check the values of each of the arguments, they cannot be negative(we
1026 // assume), and if the array bound is known, must be within range. As we do
1027 // so, do our best to continue with evaluation, we can set the
1028 // value/expression to nullptr/nullopt if they are invalid, and treat them as
1029 // not present for the rest of evaluation.
1030
1031 // We don't have to check for dependence, because the dependent size is
1032 // represented as a different AST node.
1033 std::optional<llvm::APSInt> BaseSize;
1034 if (!OriginalBaseTy.isNull() && OriginalBaseTy->isConstantArrayType()) {
1035 const auto *ArrayTy = Context.getAsConstantArrayType(OriginalBaseTy);
1036 BaseSize = ArrayTy->getSize();
1037 }
1038
1039 auto GetBoundValue = [&](Expr *E) -> std::optional<llvm::APSInt> {
1040 if (!E || E->isInstantiationDependent())
1041 return std::nullopt;
1042
1043 Expr::EvalResult Res;
1044 if (!E->EvaluateAsInt(Res, Context))
1045 return std::nullopt;
1046 return Res.Val.getInt();
1047 };
1048
1049 std::optional<llvm::APSInt> LowerBoundValue = GetBoundValue(LowerBound);
1050 std::optional<llvm::APSInt> LengthValue = GetBoundValue(Length);
1051
1052 // Check lower bound for negative or out of range.
1053 if (LowerBoundValue.has_value()) {
1054 if (LowerBoundValue->isNegative()) {
1055 Diag(LowerBound->getExprLoc(), diag::err_acc_subarray_negative)
1056 << /*LowerBound=*/0 << toString(*LowerBoundValue, /*Radix=*/10);
1057 LowerBoundValue.reset();
1058 LowerBound = GetRecovery(LowerBound, LowerBound->getType());
1059 } else if (BaseSize.has_value() &&
1060 llvm::APSInt::compareValues(*LowerBoundValue, *BaseSize) >= 0) {
1061 // Lower bound (start index) must be less than the size of the array.
1062 Diag(LowerBound->getExprLoc(), diag::err_acc_subarray_out_of_range)
1063 << /*LowerBound=*/0 << toString(*LowerBoundValue, /*Radix=*/10)
1064 << toString(*BaseSize, /*Radix=*/10);
1065 LowerBoundValue.reset();
1066 LowerBound = GetRecovery(LowerBound, LowerBound->getType());
1067 }
1068 }
1069
1070 // Check length for negative or out of range.
1071 if (LengthValue.has_value()) {
1072 if (LengthValue->isNegative()) {
1073 Diag(Length->getExprLoc(), diag::err_acc_subarray_negative)
1074 << /*Length=*/1 << toString(*LengthValue, /*Radix=*/10);
1075 LengthValue.reset();
1076 Length = GetRecovery(Length, Length->getType());
1077 } else if (BaseSize.has_value() &&
1078 llvm::APSInt::compareValues(*LengthValue, *BaseSize) > 0) {
1079 // Length must be lessthan or EQUAL to the size of the array.
1080 Diag(Length->getExprLoc(), diag::err_acc_subarray_out_of_range)
1081 << /*Length=*/1 << toString(*LengthValue, /*Radix=*/10)
1082 << toString(*BaseSize, /*Radix=*/10);
1083 LengthValue.reset();
1084 Length = GetRecovery(Length, Length->getType());
1085 }
1086 }
1087
1088 // Adding two APSInts requires matching sign, so extract that here.
1089 auto AddAPSInt = [](llvm::APSInt LHS, llvm::APSInt RHS) -> llvm::APSInt {
1090 if (LHS.isSigned() == RHS.isSigned())
1091 return LHS + RHS;
1092
1093 unsigned Width = std::max(LHS.getBitWidth(), RHS.getBitWidth()) + 1;
1094 return llvm::APSInt(LHS.sext(Width) + RHS.sext(Width), /*Signed=*/true);
1095 };
1096
1097 // If we know all 3 values, we can diagnose that the total value would be out
1098 // of range.
1099 if (BaseSize.has_value() && LowerBoundValue.has_value() &&
1100 LengthValue.has_value() &&
1101 llvm::APSInt::compareValues(AddAPSInt(*LowerBoundValue, *LengthValue),
1102 *BaseSize) > 0) {
1103 Diag(Base->getExprLoc(),
1104 diag::err_acc_subarray_base_plus_length_out_of_range)
1105 << toString(*LowerBoundValue, /*Radix=*/10)
1106 << toString(*LengthValue, /*Radix=*/10)
1107 << toString(*BaseSize, /*Radix=*/10);
1108
1109 LowerBoundValue.reset();
1110 LowerBound = GetRecovery(LowerBound, LowerBound->getType());
1111 LengthValue.reset();
1112 Length = GetRecovery(Length, Length->getType());
1113 }
1114
1115 // If any part of the expression is dependent, return a dependent sub-array.
1116 QualType ArrayExprTy = Context.ArraySectionTy;
1117 if (Base->isTypeDependent() ||
1118 (LowerBound && LowerBound->isInstantiationDependent()) ||
1119 (Length && Length->isInstantiationDependent()))
1120 ArrayExprTy = Context.DependentTy;
1121
1122 return new (Context)
1123 ArraySectionExpr(Base, LowerBound, Length, ArrayExprTy, VK_LValue,
1124 OK_Ordinary, ColonLoc, RBLoc);
1125}
1126
1128 SourceLocation StartLoc) {
1129 return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/true);
1130}
1131
1133 SourceLocation StartLoc,
1134 SourceLocation EndLoc,
1136 StmtResult AssocStmt) {
1137 switch (K) {
1138 default:
1139 return StmtEmpty();
1141 return StmtError();
1145 // TODO OpenACC: Add clauses to the construct here.
1147 getASTContext(), K, StartLoc, EndLoc, Clauses,
1148 AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
1149 }
1150 llvm_unreachable("Unhandled case in directive handling?");
1151}
1152
1154 StmtResult AssocStmt) {
1155 switch (K) {
1156 default:
1157 llvm_unreachable("Unimplemented associated statement application");
1161 // There really isn't any checking here that could happen. As long as we
1162 // have a statement to associate, this should be fine.
1163 // OpenACC 3.3 Section 6:
1164 // Structured Block: in C or C++, an executable statement, possibly
1165 // compound, with a single entry at the top and a single exit at the
1166 // bottom.
1167 // FIXME: Should we reject DeclStmt's here? The standard isn't clear, and
1168 // an interpretation of it is to allow this and treat the initializer as
1169 // the 'structured block'.
1170 return AssocStmt;
1171 }
1172 llvm_unreachable("Invalid associated statement application");
1173}
1174
1176 SourceLocation StartLoc) {
1177 return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/false);
1178}
1179
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.
SourceLocation Loc
Definition: SemaObjC.cpp:755
This file declares semantic analysis for OpenACC constructs and clauses.
This file defines OpenACC AST classes for statement-level contructs.
APSInt & getInt()
Definition: APValue.h:423
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
const ConstantArrayType * getAsConstantArrayType(QualType T) const
Definition: ASTContext.h:2768
CanQualType DependentTy
Definition: ASTContext.h:1119
CanQualType ArraySectionTy
Definition: ASTContext.h:1131
CanQualType IntTy
Definition: ASTContext.h:1100
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:6734
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
Definition: Expr.cpp:5068
QualType getElementType() const
Definition: Type.h:3530
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2862
llvm::APInt getSize() const
Return the constant array size as an APInt.
Definition: Type.h:3612
SourceLocation getLocation() const
Definition: DeclBase.h:445
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,...
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:3059
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
QualType getType() const
Definition: Expr.h:142
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
Definition: Expr.h:516
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)
This is the base type for all OpenACC Clauses.
Definition: OpenACCClause.h:24
OpenACCClauseKind getClauseKind() const
Definition: OpenACCClause.h:37
SourceLocation getBeginLoc() const
Definition: OpenACCClause.h:38
static OpenACCComputeConstruct * Create(const ASTContext &C, OpenACCDirectiveKind K, SourceLocation BeginLoc, 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 OpenACCDefaultClause * Create(const ASTContext &C, OpenACCDefaultClauseKind K, SourceLocation BeginLoc, SourceLocation LParenLoc, 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.
Definition: OpenACCClause.h:86
static OpenACCDeviceTypeClause * Create(const ASTContext &C, OpenACCClauseKind K, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< DeviceTypeArgument > Archs, SourceLocation EndLoc)
static OpenACCFirstPrivateClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCIfClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *ConditionExpr, SourceLocation EndLoc)
static 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 OpenACCSelfClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *ConditionExpr, 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)
A (possibly-)qualified type.
Definition: Type.h:940
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:1007
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:7560
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition: Type.h:7453
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:56
ASTContext & getASTContext() const
Definition: SemaBase.cpp:9
Sema & SemaRef
Definition: SemaBase.h:40
A type to represent all the data for an OpenACC Clause that has been parsed, but not yet created/sema...
Definition: SemaOpenACC.h:36
ArrayRef< Expr * > getQueueIdExprs() const
Definition: SemaOpenACC.h:149
OpenACCDirectiveKind getDirectiveKind() const
Definition: SemaOpenACC.h:79
SourceLocation getEndLoc() const
Definition: SemaOpenACC.h:87
OpenACCClauseKind getClauseKind() const
Definition: SemaOpenACC.h:81
const Expr * getConditionExpr() const
Definition: SemaOpenACC.h:95
SourceLocation getLParenLoc() const
Definition: SemaOpenACC.h:85
ArrayRef< DeviceTypeArgument > getDeviceTypeArchitectures() const
Definition: SemaOpenACC.h:219
SourceLocation getBeginLoc() const
Definition: SemaOpenACC.h:83
SourceLocation getQueuesLoc() const
Definition: SemaOpenACC.h:129
void setVarListDetails(ArrayRef< Expr * > VarList, bool IsReadOnly, bool IsZero)
Definition: SemaOpenACC.h:266
OpenACCDefaultClauseKind getDefaultClauseKind() const
Definition: SemaOpenACC.h:89
ExprResult ActOnVar(Expr *VarExpr)
Called when encountering a 'var' for OpenACC, ensures it is actually a declaration reference to a var...
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'.
StmtResult ActOnEndStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses, StmtResult AssocStmt)
Called after the directive has been completely parsed, including the declaration group or associated ...
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' ...
bool ActOnStartStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc)
Called after the directive, including its clauses, have been parsed and parsing has consumed the 'ann...
DeclGroupRef ActOnEndDeclDirective()
Called after the directive has been completely parsed, including the declaration group or associated ...
void ActOnConstruct(OpenACCDirectiveKind K, SourceLocation StartLoc)
Called after the construct has been parsed, but clauses haven't been parsed.
StmtResult ActOnAssociatedStmt(OpenACCDirectiveKind K, StmtResult AssocStmt)
Called when we encounter an associated statement for our construct, this should check legality of the...
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.
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:451
ExprResult PerformContextualImplicitConversion(SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter)
Perform a contextual implicit conversion.
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
Definition: SemaExpr.cpp:764
ExprResult DefaultLvalueConversion(Expr *E)
Definition: SemaExpr.cpp:652
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
Definition: SemaExpr.cpp:20806
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Definition: SemaType.cpp:8831
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:20999
Encodes a location in the source.
SourceLocation getEndLoc() const LLVM_READONLY
Definition: Stmt.cpp:350
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:326
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:338
bool isDependentSizedArrayType() const
Definition: Type.h:7698
bool isConstantArrayType() const
Definition: Type.h:7682
bool isArrayType() const
Definition: Type.h:7678
bool isPointerType() const
Definition: Type.h:7612
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition: Type.h:7945
bool isEnumeralType() const
Definition: Type.h:7710
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:695
bool isNonOverloadPlaceholderType() const
Test for a placeholder type other than Overload; see BuiltinType::isNonOverloadPlaceholderType.
Definition: Type.h:7899
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2653
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition: Type.h:8179
bool isFunctionType() const
Definition: Type.h:7608
bool isAnyPointerType() const
Definition: Type.h:7616
SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)
Returns the results of matching Matcher on Node.
The JSON file list parser is used to communicate input to InstallAPI.
OpenACCClauseKind
Represents the kind of an OpenACC clause.
Definition: OpenACCKinds.h:164
@ Wait
'wait' clause, allowed on Compute, Data, 'update', and Combined constructs.
@ DevicePtr
'deviceptr' clause, allowed on Compute and Combined Constructs, plus 'data' and 'declare'.
@ PCopyOut
'copyout' clause alias 'pcopyout'. Preserved for diagnostic purposes.
@ VectorLength
'vector_length' clause, allowed on 'parallel', 'kernels', 'parallel loop', and 'kernels loop' constru...
@ Async
'async' clause, allowed on Compute, Data, 'update', 'wait', and Combined constructs.
@ PresentOrCreate
'create' clause alias 'present_or_create'.
@ PresentOrCopy
'copy' clause alias 'present_or_copy'. Preserved for diagnostic purposes.
@ Private
'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...
@ Invalid
Represents an invalid clause, for the purposes of parsing.
@ Copy
'copy' clause, allowed on Compute and Combined Constructs, plus 'data' and 'declare'.
@ Create
'create' clause, allowed on Compute and Combined constructs, plus 'data', 'enter data',...
@ DeviceType
'device_type' clause, allowed on Compute, 'data', 'init', 'shutdown', 'set', update',...
@ Attach
'attach' clause, allowed on Compute and Combined constructs, plus 'data' and 'enter data'.
@ NumGangs
'num_gangs' clause, allowed on 'parallel', 'kernels', parallel loop', and 'kernels loop' constructs.
@ If
'if' clause, allowed on all the Compute Constructs, Data Constructs, Executable Constructs,...
@ Default
'default' clause, allowed on parallel, serial, kernel (and compound) constructs.
@ NoCreate
'no_create' clause, allowed on allowed on Compute and Combined constructs, plus 'data'.
@ PresentOrCopyOut
'copyout' clause alias 'present_or_copyout'.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ CopyOut
'copyout' clause, allowed on Compute and Combined constructs, plus 'data', 'exit data',...
@ FirstPrivate
'firstprivate' clause, allowed on 'parallel', 'serial', 'parallel loop', and 'serial loop' constructs...
@ PCopy
'copy' clause alias 'pcopy'. Preserved for diagnostic purposes.
@ PCopyIn
'copyin' clause alias 'pcopyin'. Preserved for diagnostic purposes.
@ PCreate
'create' clause alias 'pcreate'. Preserved for diagnostic purposes.
@ Present
'present' clause, allowed on Compute and Combined constructs, plus 'data' and 'declare'.
@ DType
'dtype' clause, an alias for 'device_type', stored separately for diagnostic purposes.
@ CopyIn
'copyin' clause, allowed on Compute and Combined constructs, plus 'data', 'enter data',...
@ NumWorkers
'num_workers' clause, allowed on 'parallel', 'kernels', parallel loop', and 'kernels loop' constructs...
@ PresentOrCopyIn
'copyin' clause alias 'present_or_copyin'.
bool isOpenACCComputeDirectiveKind(OpenACCDirectiveKind K)
Definition: OpenACCKinds.h:149
@ OK_Ordinary
An ordinary object is located at an address in memory.
Definition: Specifiers.h:148
StmtResult StmtError()
Definition: Ownership.h:265
@ Result
The result type of a method or function.
@ Invalid
Not a valid option.
OpenACCDirectiveKind
Definition: OpenACCKinds.h:25
ExprResult ExprError()
Definition: Ownership.h:264
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
Definition: Specifiers.h:136
const FunctionProtoType * T
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