19#include "llvm/ADT/StringExtras.h"
20#include "llvm/Support/Casting.h"
29 case OpenACCDirectiveKind::Invalid:
33 case OpenACCDirectiveKind::Parallel:
34 case OpenACCDirectiveKind::Serial:
35 case OpenACCDirectiveKind::Kernels:
36 case OpenACCDirectiveKind::Loop:
38 return S.
Diag(StartLoc, diag::err_acc_construct_appertainment) << K;
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:
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:
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:
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:
108 case OpenACCClauseKind::FirstPrivate:
109 switch (DirectiveKind) {
110 case OpenACCDirectiveKind::Parallel:
111 case OpenACCDirectiveKind::Serial:
112 case OpenACCDirectiveKind::ParallelLoop:
113 case OpenACCDirectiveKind::SerialLoop:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
350 llvm_unreachable(
"Invalid clause kind");
353bool checkAlreadyHasClauseOfKind(
356 const auto *Itr = llvm::find_if(ExistingClauses, [&](
const OpenACCClause *
C) {
359 if (Itr != ExistingClauses.end()) {
360 S.
Diag(Clause.
getBeginLoc(), diag::err_acc_duplicate_clause_disallowed)
362 S.
Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
368bool checkValidAfterDeviceType(
374 NewClause.getDirectiveKind() != OpenACCDirectiveKind::Loop)
393 case OpenACCClauseKind::Async:
394 case OpenACCClauseKind::Wait:
395 case OpenACCClauseKind::NumGangs:
396 case OpenACCClauseKind::NumWorkers:
397 case OpenACCClauseKind::VectorLength:
402 }
else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Loop) {
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:
420 S.
Diag(NewClause.
getBeginLoc(), diag::err_acc_clause_after_device_type)
423 << NewClause.getDirectiveKind();
424 S.
Diag(DeviceTypeClause.
getBeginLoc(), diag::note_acc_previous_clause_here);
428class SemaOpenACCClauseVisitor {
432 bool NotImplemented =
false;
435 NotImplemented =
true;
442 : SemaRef(S), Ctx(S.getASTContext()), ExistingClauses(ExistingClauses) {}
446 bool diagNotImplemented() {
return NotImplemented; }
450 case OpenACCClauseKind::Gang:
451 case OpenACCClauseKind::Worker:
452 case OpenACCClauseKind::Vector: {
461 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSeqClause>);
463 if (Itr != ExistingClauses.end()) {
464 SemaRef.
Diag(Clause.
getBeginLoc(), diag::err_acc_clause_cannot_combine)
466 SemaRef.
Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
468 return isNotImplemented();
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: \
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"
482 return isNotImplemented();
484 llvm_unreachable(
"Invalid clause kind");
487#define VISIT_CLAUSE(CLAUSE_NAME) \
488 OpenACCClause *Visit##CLAUSE_NAME##Clause( \
489 SemaOpenACC::OpenACCParsedClause &Clause);
490#include "clang/Basic/OpenACCClauses.def"
499 return isNotImplemented();
509 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
523 return isNotImplemented();
528 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
539 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSelfClause>);
540 if (Itr != ExistingClauses.end()) {
542 SemaRef.
Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
556 return isNotImplemented();
565 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
573 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCIfClause>);
574 if (Itr != ExistingClauses.end()) {
576 SemaRef.
Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
589 return isNotImplemented();
594 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
622 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>);
624 if (
Parallel != ExistingClauses.end()) {
626 diag::err_acc_reduction_num_gangs_conflict)
628 SemaRef.
Diag((*Parallel)->getBeginLoc(),
629 diag::note_acc_previous_clause_here);
638OpenACCClause *SemaOpenACCClauseVisitor::VisitNumWorkersClause(
644 return isNotImplemented();
649 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
653 "Invalid number of expressions for NumWorkers");
659OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorLengthClause(
665 return isNotImplemented();
670 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
674 "Invalid number of expressions for NumWorkers");
686 return isNotImplemented();
691 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
695 "Invalid number of expressions for Async");
710 return isNotImplemented();
721OpenACCClause *SemaOpenACCClauseVisitor::VisitFirstPrivateClause(
727 return isNotImplemented();
744 return isNotImplemented();
760 return isNotImplemented();
776 return isNotImplemented();
792 return isNotImplemented();
808 return isNotImplemented();
824 return isNotImplemented();
840 return isNotImplemented();
845 llvm::erase_if(VarList, [&](
Expr *
E) {
855OpenACCClause *SemaOpenACCClauseVisitor::VisitDevicePtrClause(
861 return isNotImplemented();
866 llvm::erase_if(VarList, [&](
Expr *
E) {
883 return isNotImplemented();
890OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceTypeClause(
898 return isNotImplemented();
915 return isNotImplemented();
920 llvm::find_if(ExistingClauses,
921 llvm::IsaPred<OpenACCIndependentClause, OpenACCSeqClause>);
922 if (Itr != ExistingClauses.end()) {
925 SemaRef.
Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
933OpenACCClause *SemaOpenACCClauseVisitor::VisitIndependentClause(
939 return isNotImplemented();
943 const auto *Itr = llvm::find_if(
944 ExistingClauses, llvm::IsaPred<OpenACCAutoClause, OpenACCSeqClause>);
945 if (Itr != ExistingClauses.end()) {
948 SemaRef.
Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
962 return isNotImplemented();
967 llvm::find_if(ExistingClauses,
968 llvm::IsaPred<OpenACCAutoClause, OpenACCIndependentClause>);
969 if (Itr != ExistingClauses.end()) {
972 SemaRef.
Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
979 Itr = llvm::find_if(ExistingClauses,
983 if (Itr != ExistingClauses.end()) {
984 SemaRef.
Diag(Clause.
getBeginLoc(), diag::err_acc_clause_cannot_combine)
986 SemaRef.
Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
997OpenACCClause *SemaOpenACCClauseVisitor::VisitReductionClause(
1003 return isNotImplemented();
1009 auto NumGangsClauses = llvm::make_filter_range(
1010 ExistingClauses, llvm::IsaPred<OpenACCNumGangsClause>);
1012 for (
auto *NGC : NumGangsClauses) {
1014 cast<OpenACCNumGangsClause>(NGC)->getIntExprs().size();
1018 diag::err_acc_reduction_num_gangs_conflict)
1020 SemaRef.
Diag(NGC->getBeginLoc(), diag::note_acc_previous_clause_here);
1032 ValidVars.push_back(Res.
get());
1046 : SemaRef(S), WasInsideComputeConstruct(S.InsideComputeConstruct),
1052 SemaRef.InsideComputeConstruct =
true;
1053 SemaRef.ParentlessLoopConstructs.swap(ParentlessLoopConstructs);
1058 SemaRef.InsideComputeConstruct = WasInsideComputeConstruct;
1062 assert(
SemaRef.ParentlessLoopConstructs.empty() &&
1063 "Didn't consume loop construct list?");
1064 SemaRef.ParentlessLoopConstructs.swap(ParentlessLoopConstructs);
1082 if (
const auto *DevTypeClause =
1083 llvm::find_if(ExistingClauses,
1085 return isa<OpenACCDeviceTypeClause>(
C);
1087 DevTypeClause != ExistingClauses.end()) {
1088 if (checkValidAfterDeviceType(
1089 *
this, *cast<OpenACCDeviceTypeClause>(*DevTypeClause), Clause))
1093 SemaOpenACCClauseVisitor Visitor{*
this, ExistingClauses};
1096 "Created wrong clause?");
1098 if (Visitor.diagNotImplemented())
1161 auto TypeIsValid = [](
QualType Ty) {
1162 return Ty->isDependentType() || Ty->isScalarType();
1165 if (isa<ArraySectionExpr>(VarExpr)) {
1166 Expr *ASExpr = VarExpr;
1170 if (!TypeIsValid(EltTy)) {
1176 if (!RD->isStruct() && !RD->isClass()) {
1177 Diag(VarExpr->
getExprLoc(), diag::err_acc_reduction_composite_type)
1182 if (!RD->isCompleteDefinition()) {
1183 Diag(VarExpr->
getExprLoc(), diag::err_acc_reduction_composite_type)
1187 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
1188 CXXRD && !CXXRD->isAggregate()) {
1189 Diag(VarExpr->
getExprLoc(), diag::err_acc_reduction_composite_type)
1195 if (!TypeIsValid(FD->getType())) {
1197 diag::err_acc_reduction_composite_member_type);
1198 Diag(FD->getLocation(), diag::note_acc_reduction_composite_member_loc);
1202 }
else if (!TypeIsValid(VarExpr->
getType())) {
1228 Diag(DirLoc, diag::warn_acc_construct_unimplemented) << K;
1243 "Only one of directive or clause kind should be provided");
1252 unsigned getDiagKind()
const {
1253 if (ClauseKind != OpenACCClauseKind::Invalid)
1255 if (DirectiveKind != OpenACCDirectiveKind::Invalid)
1263 : ICEConvertDiagnoser(
false,
1266 DirectiveKind(DK), ClauseKind(CK), IntExpr(IntExpr) {}
1275 return S.
Diag(
Loc, diag::err_acc_int_expr_requires_integer)
1276 << getDiagKind() << ClauseKind << DirectiveKind <<
T;
1281 return S.
Diag(
Loc, diag::err_acc_int_expr_incomplete_class_type)
1288 return S.
Diag(
Loc, diag::err_acc_int_expr_explicit_conversion)
1295 return S.
Diag(Conv->
getLocation(), diag::note_acc_int_expr_conversion)
1301 return S.
Diag(
Loc, diag::err_acc_int_expr_multiple_conversions) <<
T;
1306 return S.
Diag(Conv->
getLocation(), diag::note_acc_int_expr_conversion)
1313 llvm_unreachable(
"conversion functions are permitted");
1315 } IntExprDiagnoser(DK, CK, IntExpr);
1318 Loc, IntExpr, IntExprDiagnoser);
1322 IntExpr = IntExprResult.
get();
1344 Diag(VarExpr->
getExprLoc(), diag::note_acc_expected_pointer_var);
1356 return Diag(VarExpr->
getExprLoc(), diag::err_acc_var_not_pointer_type)
1357 << ClauseKind << Ty;
1366 while (isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
1367 if (
auto *SubScrpt = dyn_cast<ArraySubscriptExpr>(CurVarExpr))
1375 if (
const auto *DRE = dyn_cast<DeclRefExpr>(CurVarExpr)) {
1376 if (isa<VarDecl, NonTypeTemplateParmDecl>(
1377 DRE->getFoundDecl()->getCanonicalDecl()))
1386 if (
const auto *ME = dyn_cast<MemberExpr>(CurVarExpr)) {
1387 if (isa<FieldDecl>(ME->getMemberDecl()->getCanonicalDecl()))
1393 if (isa<CXXThisExpr>(CurVarExpr))
1398 if (isa<DependentScopeDeclRefExpr>(CurVarExpr) ||
1400 isa<CXXDependentScopeMemberExpr>(CurVarExpr)))
1405 if (isa<RecoveryExpr>(CurVarExpr))
1421 if (
Base->hasPlaceholderType() &&
1422 !
Base->hasPlaceholderType(BuiltinType::ArraySection)) {
1435 LowerBound =
Result.get();
1437 if (Length && Length->getType()->isNonOverloadPlaceholderType()) {
1451 if (!
Base->isTypeDependent()) {
1458 Diag(
Base->getExprLoc(), diag::err_acc_typecheck_subarray_value)
1459 <<
Base->getSourceRange());
1463 Diag(
Base->getExprLoc(), diag::err_acc_subarray_function_type)
1464 << ResultTy <<
Base->getSourceRange();
1469 diag::err_acc_subarray_incomplete_type,
1473 if (!
Base->hasPlaceholderType(BuiltinType::ArraySection)) {
1484 return Recovery.
isUsable() ? Recovery.
get() :
nullptr;
1499 if (Length && !Length->isTypeDependent()) {
1502 Length->getExprLoc(), Length);
1511 if (!Length && (OriginalBaseTy.
isNull() ||
1516 Diag(ColonLoc, diag::err_acc_subarray_no_length) << IsArray;
1522 Length = Recovery.
isUsable() ? Recovery.
get() :
nullptr;
1533 std::optional<llvm::APSInt> BaseSize;
1536 BaseSize = ArrayTy->
getSize();
1539 auto GetBoundValue = [&](
Expr *
E) -> std::optional<llvm::APSInt> {
1541 return std::nullopt;
1545 return std::nullopt;
1549 std::optional<llvm::APSInt> LowerBoundValue = GetBoundValue(LowerBound);
1550 std::optional<llvm::APSInt> LengthValue = GetBoundValue(Length);
1553 if (LowerBoundValue.has_value()) {
1554 if (LowerBoundValue->isNegative()) {
1556 << 0 <<
toString(*LowerBoundValue, 10);
1557 LowerBoundValue.reset();
1558 LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
1559 }
else if (BaseSize.has_value() &&
1560 llvm::APSInt::compareValues(*LowerBoundValue, *BaseSize) >= 0) {
1562 Diag(LowerBound->
getExprLoc(), diag::err_acc_subarray_out_of_range)
1563 << 0 <<
toString(*LowerBoundValue, 10)
1565 LowerBoundValue.reset();
1566 LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
1571 if (LengthValue.has_value()) {
1572 if (LengthValue->isNegative()) {
1573 Diag(Length->getExprLoc(), diag::err_acc_subarray_negative)
1574 << 1 <<
toString(*LengthValue, 10);
1575 LengthValue.reset();
1576 Length = GetRecovery(Length, Length->getType());
1577 }
else if (BaseSize.has_value() &&
1578 llvm::APSInt::compareValues(*LengthValue, *BaseSize) > 0) {
1580 Diag(Length->getExprLoc(), diag::err_acc_subarray_out_of_range)
1583 LengthValue.reset();
1584 Length = GetRecovery(Length, Length->getType());
1589 auto AddAPSInt = [](llvm::APSInt LHS, llvm::APSInt RHS) -> llvm::APSInt {
1590 if (LHS.isSigned() == RHS.isSigned())
1593 unsigned Width = std::max(LHS.getBitWidth(), RHS.getBitWidth()) + 1;
1594 return llvm::APSInt(LHS.sext(Width) + RHS.sext(Width),
true);
1599 if (BaseSize.has_value() && LowerBoundValue.has_value() &&
1600 LengthValue.has_value() &&
1601 llvm::APSInt::compareValues(AddAPSInt(*LowerBoundValue, *LengthValue),
1604 diag::err_acc_subarray_base_plus_length_out_of_range)
1609 LowerBoundValue.reset();
1610 LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
1611 LengthValue.reset();
1612 Length = GetRecovery(Length, Length->getType());
1617 if (
Base->isTypeDependent() ||
1619 (Length && Length->isInstantiationDependent()))
1622 return new (Context)
1629 return diagnoseConstructAppertainment(*
this, K, StartLoc,
true);
1649 ParentlessLoopConstructs);
1651 ParentlessLoopConstructs.clear();
1652 return ComputeConstruct;
1657 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
1662 if (InsideComputeConstruct)
1663 ParentlessLoopConstructs.push_back(LoopConstruct);
1665 return LoopConstruct;
1668 llvm_unreachable(
"Unhandled case in directive handling?");
1676 llvm_unreachable(
"Unimplemented associated statement application");
1692 !isa<CXXForRangeStmt, ForStmt>(AssocStmt.
get())) {
1694 Diag(DirectiveLoc, diag::note_acc_construct_here) << K;
1702 llvm_unreachable(
"Invalid associated statement application");
1707 return diagnoseConstructAppertainment(*
this, K, StartLoc,
false);
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.
This file declares semantic analysis for OpenACC constructs and clauses.
This file defines OpenACC AST classes for statement-level contructs.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
CanQualType ArraySectionTy
This class represents BOTH the OpenMP Array Section and OpenACC 'subarray', with a boolean differenti...
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
QualType getElementType() const
Represents a C++ conversion function within a class.
llvm::APInt getSize() const
Return the constant array size as an APInt.
SourceLocation getLocation() const
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
Represents a member of a struct/union/class.
static OpenACCAsyncClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static OpenACCAttachClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCAutoClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)
This is the base type for all OpenACC Clauses.
OpenACCClauseKind getClauseKind() const
SourceLocation getBeginLoc() const
static OpenACCComputeConstruct * Create(const ASTContext &C, OpenACCDirectiveKind K, SourceLocation BeginLoc, SourceLocation DirectiveLoc, SourceLocation EndLoc, ArrayRef< const OpenACCClause * > Clauses, Stmt *StructuredBlock, ArrayRef< OpenACCLoopConstruct * > AssociatedLoopConstructs)
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.
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 OpenACCIndependentClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)
static OpenACCLoopConstruct * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation EndLoc, ArrayRef< const OpenACCClause * > Clauses, Stmt *Loop)
static OpenACCNoCreateClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCNumGangsClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > IntExprs, SourceLocation EndLoc)
static OpenACCNumWorkersClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static OpenACCPresentClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCPrivateClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCReductionClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, OpenACCReductionOperator Operator, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCSelfClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *ConditionExpr, SourceLocation EndLoc)
static OpenACCSeqClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)
static 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.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
A generic diagnostic builder for errors which may or may not be deferred.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
ASTContext & getASTContext() const
AssociatedStmtRAII(SemaOpenACC &, OpenACCDirectiveKind)
A type to represent all the data for an OpenACC Clause that has been parsed, but not yet created/sema...
ArrayRef< Expr * > getIntExprs()
ArrayRef< Expr * > getQueueIdExprs() const
OpenACCDirectiveKind getDirectiveKind() const
OpenACCReductionOperator getReductionOp() const
SourceLocation getEndLoc() const
OpenACCClauseKind getClauseKind() const
const Expr * getConditionExpr() const
SourceLocation getLParenLoc() const
ArrayRef< DeviceTypeArgument > getDeviceTypeArchitectures() const
SourceLocation getBeginLoc() const
SourceLocation getQueuesLoc() const
void setVarListDetails(ArrayRef< Expr * > VarList, bool IsReadOnly, bool IsZero)
Expr * getDevNumExpr() const
ArrayRef< Expr * > getVarList()
unsigned getNumIntExprs() const
OpenACCDefaultClauseKind getDefaultClauseKind() const
ExprResult ActOnVar(OpenACCClauseKind CK, 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'.
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' ...
StmtResult ActOnAssociatedStmt(SourceLocation DirectiveLoc, OpenACCDirectiveKind K, StmtResult AssocStmt)
Called when we encounter an associated statement for our construct, this should check legality of the...
StmtResult ActOnEndStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses, StmtResult AssocStmt)
Called after the directive has been completely parsed, including the declaration group or associated ...
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 ...
ExprResult CheckReductionVar(Expr *VarExpr)
Called while semantically analyzing the reduction clause, ensuring the var is the correct kind of ref...
void ActOnConstruct(OpenACCDirectiveKind K, SourceLocation DirLoc)
Called after the construct has been parsed, but clauses haven't been parsed.
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.
ExprResult PerformContextualImplicitConversion(SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter)
Perform a contextual implicit conversion.
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
ExprResult DefaultLvalueConversion(Expr *E)
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
ExprResult CreateRecoveryExpr(SourceLocation Begin, SourceLocation End, ArrayRef< Expr * > SubExprs, QualType T=QualType())
Attempts to produce a RecoveryExpr after some AST node cannot be created.
Encodes a location in the source.
SourceLocation getEndLoc() const LLVM_READONLY
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
bool isDependentSizedArrayType() const
bool isConstantArrayType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
bool isEnumeralType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isNonOverloadPlaceholderType() const
Test for a placeholder type other than Overload; see BuiltinType::isNonOverloadPlaceholderType.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isFunctionType() const
bool isAnyPointerType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
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.
@ Invalid
Represents an invalid clause, for the purposes of parsing.
@ Reduction
'reduction' clause, allowed on Parallel, Serial, Loop, and the combined constructs.
bool isOpenACCComputeDirectiveKind(OpenACCDirectiveKind K)
@ OK_Ordinary
An ordinary object is located at an address in memory.
@ Result
The result type of a method or function.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
const FunctionProtoType * T
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.