19#include "llvm/ADT/StringExtras.h"
20#include "llvm/Support/Casting.h"
29 case OpenACCDirectiveKind::Invalid:
33 case OpenACCDirectiveKind::ParallelLoop:
34 case OpenACCDirectiveKind::SerialLoop:
35 case OpenACCDirectiveKind::KernelsLoop:
36 case OpenACCDirectiveKind::Parallel:
37 case OpenACCDirectiveKind::Serial:
38 case OpenACCDirectiveKind::Kernels:
39 case OpenACCDirectiveKind::Loop:
40 case OpenACCDirectiveKind::Data:
41 case OpenACCDirectiveKind::EnterData:
42 case OpenACCDirectiveKind::ExitData:
43 case OpenACCDirectiveKind::HostData:
44 case OpenACCDirectiveKind::Wait:
46 return S.
Diag(StartLoc, diag::err_acc_construct_appertainment) << K;
52void CollectActiveReductionClauses(
55 for (
auto *CurClause : CurClauses) {
56 if (
auto *RedClause = dyn_cast<OpenACCReductionClause>(CurClause);
57 RedClause && !RedClause->getVarList().empty())
58 ActiveClauses.push_back(RedClause);
66 case OpenACCDirectiveKind::Parallel:
67 case OpenACCDirectiveKind::ParallelLoop:
68 case OpenACCDirectiveKind::Serial:
69 case OpenACCDirectiveKind::SerialLoop:
70 case OpenACCDirectiveKind::Kernels:
71 case OpenACCDirectiveKind::KernelsLoop:
72 case OpenACCDirectiveKind::Loop:
74 case OpenACCDirectiveKind::Data:
75 case OpenACCDirectiveKind::HostData:
77 case OpenACCDirectiveKind::EnterData:
78 case OpenACCDirectiveKind::ExitData:
79 case OpenACCDirectiveKind::Wait:
80 case OpenACCDirectiveKind::Init:
81 case OpenACCDirectiveKind::Shutdown:
82 case OpenACCDirectiveKind::Set:
83 case OpenACCDirectiveKind::Update:
84 llvm_unreachable(
"Doesn't have an associated stmt");
86 case OpenACCDirectiveKind::Invalid:
87 llvm_unreachable(
"Unhandled directive kind?");
89 llvm_unreachable(
"Unhandled directive kind?");
100 : SemaRef(S), OldActiveComputeConstructInfo(S.ActiveComputeConstructInfo),
101 DirKind(DK), OldLoopGangClauseOnKernel(S.LoopGangClauseOnKernel),
102 OldLoopWorkerClauseLoc(S.LoopWorkerClauseLoc),
103 OldLoopVectorClauseLoc(S.LoopVectorClauseLoc),
104 OldLoopWithoutSeqInfo(S.LoopWithoutSeqInfo),
105 ActiveReductionClauses(S.ActiveReductionClauses),
106 LoopRAII(SemaRef, PreserveLoopRAIIDepthInAssociatedStmtRAII(DirKind)) {
112 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
113 SemaRef.ActiveComputeConstructInfo.Kind = DirKind;
114 SemaRef.ActiveComputeConstructInfo.Clauses = Clauses;
129 SemaRef.ActiveComputeConstructInfo.Kind = DirKind;
130 SemaRef.ActiveComputeConstructInfo.Clauses = Clauses;
132 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
144 llvm::find_if(Clauses, llvm::IsaPred<OpenACCSeqClause>))
157 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCGangClause>);
158 if (Itr != Clauses.end())
162 if (UnInstClauses.empty()) {
163 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCWorkerClause>);
164 if (Itr != Clauses.end())
167 auto *Itr2 = llvm::find_if(Clauses, llvm::IsaPred<OpenACCVectorClause>);
168 if (Itr2 != Clauses.end())
172 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
180 llvm::find_if(Clauses, llvm::IsaPred<OpenACCSeqClause>))
193 UnInstClauses.empty()) {
195 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCGangClause>);
196 if (Itr != Clauses.end())
201 if (UnInstClauses.empty()) {
202 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCWorkerClause>);
203 if (Itr != Clauses.end())
206 auto *Itr2 = llvm::find_if(Clauses, llvm::IsaPred<OpenACCVectorClause>);
207 if (Itr2 != Clauses.end())
218 SemaRef.LoopInfo.CurLevelHasLoopAlready =
false;
219 SemaRef.CollapseInfo.CollapseDepthSatisfied =
true;
220 SemaRef.TileInfo.TileDepthSatisfied =
true;
227 auto *CollapseClauseItr =
228 llvm::find_if(Clauses, llvm::IsaPred<OpenACCCollapseClause>);
229 auto *UnInstCollapseClauseItr =
230 llvm::find_if(UnInstClauses, llvm::IsaPred<OpenACCCollapseClause>);
232 if (Clauses.end() == CollapseClauseItr)
236 cast<OpenACCCollapseClause>(*CollapseClauseItr);
238 SemaRef.CollapseInfo.ActiveCollapse = CollapseClause;
248 if (UnInstCollapseClauseItr != UnInstClauses.end() &&
249 !cast<OpenACCCollapseClause>(*UnInstCollapseClauseItr)
251 ->isInstantiationDependent())
254 SemaRef.CollapseInfo.CollapseDepthSatisfied =
false;
255 SemaRef.CollapseInfo.CurCollapseCount =
256 cast<ConstantExpr>(LoopCount)->getResultAsAPSInt();
257 SemaRef.CollapseInfo.DirectiveKind = DirKind;
266 if (UnInstClauses.size() > 0)
268 auto *TileClauseItr =
269 llvm::find_if(Clauses, llvm::IsaPred<OpenACCTileClause>);
271 if (Clauses.end() == TileClauseItr)
275 SemaRef.TileInfo.ActiveTile = TileClause;
276 SemaRef.TileInfo.TileDepthSatisfied =
false;
278 SemaRef.TileInfo.DirectiveKind = DirKind;
289 SemaRef.ActiveComputeConstructInfo = OldActiveComputeConstructInfo;
290 SemaRef.LoopGangClauseOnKernel = OldLoopGangClauseOnKernel;
291 SemaRef.LoopWorkerClauseLoc = OldLoopWorkerClauseLoc;
292 SemaRef.LoopVectorClauseLoc = OldLoopVectorClauseLoc;
293 SemaRef.LoopWithoutSeqInfo = OldLoopWithoutSeqInfo;
294 SemaRef.ActiveReductionClauses.swap(ActiveReductionClauses);
338 Diag(DirLoc, diag::warn_acc_construct_unimplemented) << K;
353 "Only one of directive or clause kind should be provided");
362 unsigned getDiagKind()
const {
363 if (ClauseKind != OpenACCClauseKind::Invalid)
365 if (DirectiveKind != OpenACCDirectiveKind::Invalid)
373 : ICEConvertDiagnoser(
false,
376 DirectiveKind(DK), ClauseKind(CK), IntExpr(IntExpr) {}
385 return S.
Diag(
Loc, diag::err_acc_int_expr_requires_integer)
386 << getDiagKind() << ClauseKind << DirectiveKind <<
T;
391 return S.
Diag(
Loc, diag::err_acc_int_expr_incomplete_class_type)
398 return S.
Diag(
Loc, diag::err_acc_int_expr_explicit_conversion)
411 return S.
Diag(
Loc, diag::err_acc_int_expr_multiple_conversions) <<
T;
423 llvm_unreachable(
"conversion functions are permitted");
425 } IntExprDiagnoser(DK, CK, IntExpr);
431 Loc, IntExpr, IntExprDiagnoser);
435 IntExpr = IntExprResult.
get();
469 return Diag(VarExpr->
getExprLoc(), diag::err_acc_var_not_pointer_type)
481 isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
482 Diag(VarExpr->
getExprLoc(), diag::err_acc_not_a_var_ref_use_device);
488 while (isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
489 if (
auto *SubScrpt = dyn_cast<ArraySubscriptExpr>(CurVarExpr))
497 if (
const auto *DRE = dyn_cast<DeclRefExpr>(CurVarExpr)) {
498 if (isa<VarDecl, NonTypeTemplateParmDecl>(
499 DRE->getFoundDecl()->getCanonicalDecl()))
511 if (
const auto *ME = dyn_cast<MemberExpr>(CurVarExpr)) {
512 if (isa<FieldDecl>(ME->getMemberDecl()->getCanonicalDecl()))
524 if (isa<DependentScopeDeclRefExpr>(CurVarExpr) ||
526 isa<CXXDependentScopeMemberExpr>(CurVarExpr)))
531 if (isa<RecoveryExpr>(CurVarExpr))
535 Diag(VarExpr->
getExprLoc(), diag::err_acc_not_a_var_ref_use_device);
550 if (
Base->hasPlaceholderType() &&
551 !
Base->hasPlaceholderType(BuiltinType::ArraySection)) {
564 LowerBound =
Result.get();
566 if (Length && Length->getType()->isNonOverloadPlaceholderType()) {
580 if (!
Base->isTypeDependent()) {
587 Diag(
Base->getExprLoc(), diag::err_acc_typecheck_subarray_value)
588 <<
Base->getSourceRange());
592 Diag(
Base->getExprLoc(), diag::err_acc_subarray_function_type)
593 << ResultTy <<
Base->getSourceRange();
598 diag::err_acc_subarray_incomplete_type,
602 if (!
Base->hasPlaceholderType(BuiltinType::ArraySection)) {
613 return Recovery.
isUsable() ? Recovery.
get() :
nullptr;
628 if (Length && !Length->isTypeDependent()) {
631 Length->getExprLoc(), Length);
640 if (!Length && (OriginalBaseTy.
isNull() ||
645 Diag(ColonLoc, diag::err_acc_subarray_no_length) << IsArray;
650 Length = Recovery.
isUsable() ? Recovery.
get() :
nullptr;
661 std::optional<llvm::APSInt> BaseSize;
667 auto GetBoundValue = [&](
Expr *
E) -> std::optional<llvm::APSInt> {
677 std::optional<llvm::APSInt> LowerBoundValue = GetBoundValue(LowerBound);
678 std::optional<llvm::APSInt> LengthValue = GetBoundValue(Length);
681 if (LowerBoundValue.has_value()) {
682 if (LowerBoundValue->isNegative()) {
684 << 0 <<
toString(*LowerBoundValue, 10);
685 LowerBoundValue.reset();
686 LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
687 }
else if (BaseSize.has_value() &&
688 llvm::APSInt::compareValues(*LowerBoundValue, *BaseSize) >= 0) {
690 Diag(LowerBound->
getExprLoc(), diag::err_acc_subarray_out_of_range)
691 << 0 <<
toString(*LowerBoundValue, 10)
693 LowerBoundValue.reset();
694 LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
699 if (LengthValue.has_value()) {
700 if (LengthValue->isNegative()) {
701 Diag(Length->getExprLoc(), diag::err_acc_subarray_negative)
704 Length = GetRecovery(Length, Length->getType());
705 }
else if (BaseSize.has_value() &&
706 llvm::APSInt::compareValues(*LengthValue, *BaseSize) > 0) {
708 Diag(Length->getExprLoc(), diag::err_acc_subarray_out_of_range)
712 Length = GetRecovery(Length, Length->getType());
717 auto AddAPSInt = [](llvm::APSInt LHS, llvm::APSInt RHS) -> llvm::APSInt {
718 if (LHS.isSigned() == RHS.isSigned())
721 unsigned Width = std::max(LHS.getBitWidth(), RHS.getBitWidth()) + 1;
722 return llvm::APSInt(LHS.sext(Width) + RHS.sext(Width),
true);
727 if (BaseSize.has_value() && LowerBoundValue.has_value() &&
728 LengthValue.has_value() &&
729 llvm::APSInt::compareValues(AddAPSInt(*LowerBoundValue, *LengthValue),
732 diag::err_acc_subarray_base_plus_length_out_of_range)
737 LowerBoundValue.reset();
738 LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
740 Length = GetRecovery(Length, Length->getType());
745 if (
Base->isTypeDependent() ||
747 (Length && Length->isInstantiationDependent()))
759 if (!LoopInfo.TopLevelLoopSeen)
762 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
763 Diag(WhileLoc, diag::err_acc_invalid_in_loop)
764 << 1 << CollapseInfo.DirectiveKind
766 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
767 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
768 diag::note_acc_active_clause_here)
773 CollapseInfo.CurCollapseCount = std::nullopt;
776 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
777 Diag(WhileLoc, diag::err_acc_invalid_in_loop)
778 << 1 << TileInfo.DirectiveKind
780 assert(TileInfo.ActiveTile &&
"tile count without object?");
781 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
786 TileInfo.CurTileCount = std::nullopt;
794 if (!LoopInfo.TopLevelLoopSeen)
797 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
798 Diag(DoLoc, diag::err_acc_invalid_in_loop)
799 << 2 << CollapseInfo.DirectiveKind
801 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
802 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
803 diag::note_acc_active_clause_here)
808 CollapseInfo.CurCollapseCount = std::nullopt;
811 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
812 Diag(DoLoc, diag::err_acc_invalid_in_loop)
814 assert(TileInfo.ActiveTile &&
"tile count without object?");
815 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
820 TileInfo.CurTileCount = std::nullopt;
825 ForStmtBeginChecker &
C) {
826 assert(
getLangOpts().OpenACC &&
"Check enabled when not OpenACC?");
829 LoopInfo.TopLevelLoopSeen =
true;
831 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
839 if (LoopInfo.CurLevelHasLoopAlready) {
840 Diag(ForLoc, diag::err_acc_clause_multiple_loops)
842 assert(CollapseInfo.ActiveCollapse &&
"No collapse object?");
843 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
844 diag::note_acc_active_clause_here)
847 --(*CollapseInfo.CurCollapseCount);
851 if (*CollapseInfo.CurCollapseCount == 0)
852 CollapseInfo.CollapseDepthSatisfied =
true;
856 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
859 if (LoopInfo.CurLevelHasLoopAlready) {
860 Diag(ForLoc, diag::err_acc_clause_multiple_loops)
862 assert(TileInfo.ActiveTile &&
"No tile object?");
863 Diag(TileInfo.ActiveTile->getBeginLoc(),
864 diag::note_acc_active_clause_here)
867 --(*TileInfo.CurTileCount);
870 if (*TileInfo.CurTileCount == 0)
871 TileInfo.TileDepthSatisfied =
true;
877 LoopInfo.CurLevelHasLoopAlready =
false;
881bool isValidLoopVariableType(
QualType LoopVarTy) {
904 for (
const auto *TD :
905 llvm::make_filter_range(RD->decls(), llvm::IsaPred<TypedefNameDecl>)) {
906 const auto *TDND = cast<TypedefNameDecl>(TD)->getCanonicalDecl();
908 if (TDND->getName() !=
"iterator_category")
912 if (TDND->getUnderlyingType().isNull())
916 TDND->getUnderlyingType()->getAsCXXRecordDecl();
919 if (!ItrCategoryDecl)
922 auto IsRandomAccessIteratorTag = [](
const CXXRecordDecl *RD) {
923 if (RD->getName() !=
"random_access_iterator_tag")
929 if (IsRandomAccessIteratorTag(ItrCategoryDecl))
936 if (IsRandomAccessIteratorTag(BS.getType()->getAsCXXRecordDecl()))
949void SemaOpenACC::ForStmtBeginChecker::check() {
955 AlreadyChecked =
true;
975 if (!RangeFor.has_value())
979 const DeclStmt *RangeStmt = (*RangeFor)->getBeginStmt();
988 if (!isValidLoopVariableType(VarType)) {
990 <<
SemaRef.LoopWithoutSeqInfo.Kind << VarType;
992 diag::note_acc_construct_here)
993 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1002 if (Cond.has_value())
1004 if (
Inc.has_value())
1007const ValueDecl *SemaOpenACC::ForStmtBeginChecker::checkInit() {
1011 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1013 diag::note_acc_construct_here)
1014 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1019 auto DiagLoopVar = [&]() {
1022 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1024 diag::note_acc_construct_here)
1025 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1030 if (
const auto *ExprTemp = dyn_cast<ExprWithCleanups>(
Init))
1031 Init = ExprTemp->getSubExpr();
1032 if (
const auto *
E = dyn_cast<Expr>(
Init))
1037 if (
const auto *BO = dyn_cast<BinaryOperator>(
Init)) {
1040 if (!BO->isAssignmentOp())
1041 return DiagLoopVar();
1045 if (
const auto *DRE = dyn_cast<DeclRefExpr>(LHS))
1046 InitVar = DRE->getDecl();
1047 }
else if (
const auto *DS = dyn_cast<DeclStmt>(
Init)) {
1049 if (!DS->isSingleDecl())
1050 return DiagLoopVar();
1052 InitVar = dyn_cast<ValueDecl>(DS->getSingleDecl());
1057 if (!isa<VarDecl>(InitVar))
1058 return DiagLoopVar();
1062 !cast<VarDecl>(InitVar)->hasInit())
1063 return DiagLoopVar();
1065 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(
Init)) {
1067 if (CE->getOperator() != OO_Equal)
1068 return DiagLoopVar();
1072 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
1073 InitVar = DRE->getDecl();
1074 }
else if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
1075 if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
1076 InitVar = ME->getMemberDecl();
1081 return DiagLoopVar();
1087 if (!isValidLoopVariableType(VarType)) {
1090 <<
SemaRef.LoopWithoutSeqInfo.Kind << VarType;
1092 diag::note_acc_construct_here)
1093 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1100void SemaOpenACC::ForStmtBeginChecker::checkCond() {
1102 SemaRef.
Diag(ForLoc, diag::err_acc_loop_terminating_condition)
1103 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1105 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1114void SemaOpenACC::ForStmtBeginChecker::checkInc(
const ValueDecl *
Init) {
1117 SemaRef.
Diag(ForLoc, diag::err_acc_loop_not_monotonic)
1118 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1120 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1123 auto DiagIncVar = [
this] {
1124 SemaRef.
Diag((*Inc)->getBeginLoc(), diag::err_acc_loop_not_monotonic)
1125 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1127 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1131 if (
const auto *ExprTemp = dyn_cast<ExprWithCleanups>(*Inc))
1132 Inc = ExprTemp->getSubExpr();
1133 if (
const auto *
E = dyn_cast<Expr>(*Inc))
1138 if (
const auto *FE = dyn_cast<FullExpr>(
E))
1139 E = FE->getSubExpr();
1145 if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E))
1146 return dyn_cast<ValueDecl>(DRE->getDecl());
1148 if (
const auto *ME = dyn_cast<MemberExpr>(
E))
1149 if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
1150 return ME->getMemberDecl();
1158 if (
const auto *UO = dyn_cast<UnaryOperator>(*Inc)) {
1160 if (!UO->isIncrementDecrementOp())
1161 return DiagIncVar();
1163 }
else if (
const auto *BO = dyn_cast<BinaryOperator>(*Inc)) {
1164 switch (BO->getOpcode()) {
1166 return DiagIncVar();
1180 }
else if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(*Inc)) {
1181 switch (CE->getOperator()) {
1183 return DiagIncVar();
1201 }
else if (
const auto *ME = dyn_cast<CXXMemberCallExpr>(*Inc)) {
1208 return DiagIncVar();
1214 return DiagIncVar();
1221 const Stmt *Second,
const Stmt *OldThird,
1222 const Stmt *Third) {
1226 std::optional<const Stmt *> S;
1227 if (OldSecond == Second)
1231 std::optional<const Stmt *>
T;
1232 if (OldThird == Third)
1237 bool InitChanged =
false;
1238 if (OldFirst !=
First) {
1246 if (
const auto *DS = dyn_cast<DeclStmt>(OldFirst))
1247 if (
const VarDecl *VD = dyn_cast_if_present<VarDecl>(
1248 DS->isSingleDecl() ? DS->getSingleDecl() :
nullptr))
1249 OldVDTy = VD->getType();
1250 if (
const auto *DS = dyn_cast<DeclStmt>(
First))
1251 if (
const VarDecl *VD = dyn_cast_if_present<VarDecl>(
1252 DS->isSingleDecl() ? DS->getSingleDecl() :
nullptr))
1253 NewVDTy = VD->getType();
1260 ForStmtBeginChecker FSBC{*
this, ForLoc,
First, InitChanged, S,
T};
1261 if (!LoopInfo.TopLevelLoopSeen) {
1265 ForStmtBeginHelper(ForLoc, FSBC);
1269 const Stmt *Second,
const Stmt *Third) {
1273 ForStmtBeginChecker FSBC{*
this, ForLoc,
First,
true,
1275 if (!LoopInfo.TopLevelLoopSeen) {
1279 ForStmtBeginHelper(ForLoc, FSBC);
1283 const Stmt *OldRangeFor,
1284 const Stmt *RangeFor) {
1288 std::optional<const CXXForRangeStmt *> RF;
1290 if (OldRangeFor == RangeFor)
1293 RF = cast<CXXForRangeStmt>(RangeFor);
1295 ForStmtBeginChecker FSBC{*
this, ForLoc, RF};
1296 if (!LoopInfo.TopLevelLoopSeen) {
1299 ForStmtBeginHelper(ForLoc, FSBC);
1303 const Stmt *RangeFor) {
1307 ForStmtBeginChecker FSBC{*
this, ForLoc, cast<CXXForRangeStmt>(RangeFor)};
1308 if (!LoopInfo.TopLevelLoopSeen) {
1311 ForStmtBeginHelper(ForLoc, FSBC);
1321 isa<ForStmt, NullStmt, ForStmt, CXXForRangeStmt, WhileStmt, DoStmt>(
1326 if (isa<OpenACCConstructStmt>(CurStmt))
1331 if (
const auto *CS = dyn_cast<CompoundStmt>(CurStmt)) {
1332 for (
const auto *ChildStmt : CS->children()) {
1333 SourceLocation ChildStmtLoc = FindInterveningCodeInLoop(ChildStmt);
1335 return ChildStmtLoc;
1349 LoopInfo.CurLevelHasLoopAlready =
true;
1354 bool IsActiveCollapse = CollapseInfo.CurCollapseCount &&
1355 *CollapseInfo.CurCollapseCount > 0 &&
1356 !CollapseInfo.ActiveCollapse->hasForce();
1357 bool IsActiveTile = TileInfo.CurTileCount && *TileInfo.CurTileCount > 0;
1359 if (IsActiveCollapse || IsActiveTile) {
1362 if (OtherStmtLoc.
isValid() && IsActiveCollapse) {
1363 Diag(OtherStmtLoc, diag::err_acc_intervening_code)
1365 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1366 diag::note_acc_active_clause_here)
1370 if (OtherStmtLoc.
isValid() && IsActiveTile) {
1371 Diag(OtherStmtLoc, diag::err_acc_intervening_code)
1373 Diag(TileInfo.ActiveTile->getBeginLoc(),
1374 diag::note_acc_active_clause_here)
1384 assert(!Clauses.empty() &&
"empty clause list not supported");
1387 llvm::raw_string_ostream OS{Output};
1389 if (Clauses.size() == 1) {
1390 OS <<
'\'' << Clauses[0] <<
'\'';
1399 [&] { OS <<
", "; });
1401 OS <<
" or \'" << Clauses.back() <<
'\'';
1417 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
1418 Diag(StartLoc, diag::err_acc_invalid_in_loop)
1419 << 0 << CollapseInfo.DirectiveKind
1421 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
1422 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1423 diag::note_acc_active_clause_here)
1426 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
1427 Diag(StartLoc, diag::err_acc_invalid_in_loop)
1428 << 0 << TileInfo.DirectiveKind
1430 assert(TileInfo.ActiveTile &&
"Tile count without object?");
1431 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
1439 llvm::find_if(Clauses,
1445 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1447 << GetListOfClauses(
1457 llvm::find_if(Clauses,
1460 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1462 << GetListOfClauses({
1470 llvm::find_if(Clauses,
1473 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1475 << GetListOfClauses({
1483 llvm::find_if(Clauses, llvm::IsaPred<OpenACCUseDeviceClause>) ==
1485 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1496 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1509 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1515 return diagnoseConstructAppertainment(*
this, K, StartLoc,
true);
1533 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
1540 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
1544 getASTContext(), ActiveComputeConstructInfo.Kind, StartLoc, DirLoc,
1545 EndLoc, Clauses, AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
1550 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
1563 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
1567 getASTContext(), StartLoc, DirLoc, LParenLoc, Exprs.front(), MiscLoc,
1568 Exprs.drop_front(), RParenLoc, EndLoc, Clauses);
1587 llvm_unreachable(
"Unhandled case in directive handling?");
1595 llvm_unreachable(
"Unimplemented associated statement application");
1603 "these don't have associated statements, so shouldn't get here");
1626 if (!isa<CXXForRangeStmt, ForStmt>(AssocStmt.
get())) {
1629 Diag(DirectiveLoc, diag::note_acc_construct_here) << K;
1633 if (!CollapseInfo.CollapseDepthSatisfied || !TileInfo.TileDepthSatisfied) {
1634 if (!CollapseInfo.CollapseDepthSatisfied) {
1635 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
1637 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
1638 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1639 diag::note_acc_active_clause_here)
1643 if (!TileInfo.TileDepthSatisfied) {
1644 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
1646 assert(TileInfo.ActiveTile &&
"Collapse count without object?");
1647 Diag(TileInfo.ActiveTile->getBeginLoc(),
1648 diag::note_acc_active_clause_here)
1654 return AssocStmt.
get();
1656 llvm_unreachable(
"Invalid associated statement application");
1666 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.
static NamedDecl * getDeclFromExpr(Expr *E)
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
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 base class of a C++ class.
Represents a C++ conversion function within a class.
Represents a C++ struct/union/class.
llvm::APInt getSize() const
Return the constant array size as an APInt.
bool isStdNamespace() const
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
const Decl * getSingleDecl() const
SourceLocation getLocation() const
SourceLocation getBeginLoc() const LLVM_READONLY
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
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,...
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.
static OpenACCAsteriskSizeExpr * Create(const ASTContext &C, SourceLocation Loc)
Represents a 'collapse' clause on a 'loop' construct.
const Expr * getLoopCount() const
static OpenACCCombinedConstruct * Create(const ASTContext &C, OpenACCDirectiveKind K, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses, Stmt *StructuredBlock)
static OpenACCComputeConstruct * Create(const ASTContext &C, OpenACCDirectiveKind K, SourceLocation BeginLoc, SourceLocation DirectiveLoc, SourceLocation EndLoc, ArrayRef< const OpenACCClause * > Clauses, Stmt *StructuredBlock)
static OpenACCDataConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses, Stmt *StructuredBlock)
A 'default' clause, has the optional 'none' or 'present' argument.
A 'device_type' or 'dtype' clause, takes a list of either an 'asterisk' or an identifier.
static OpenACCEnterDataConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses)
static OpenACCExitDataConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses)
static OpenACCHostDataConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses, Stmt *StructuredBlock)
An 'if' clause, which has a required condition expression.
static OpenACCInitConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses)
static OpenACCLoopConstruct * Create(const ASTContext &C, OpenACCDirectiveKind ParentKind, SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation EndLoc, ArrayRef< const OpenACCClause * > Clauses, Stmt *Loop)
A 'self' clause, which has an optional condition expression, or, in the event of an 'update' directiv...
static OpenACCSetConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses)
static OpenACCShutdownConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses)
llvm::ArrayRef< Expr * > getSizeExprs()
static OpenACCUpdateConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses)
static OpenACCWaitConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation LParenLoc, Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef< Expr * > QueueIdExprs, SourceLocation RParenLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses)
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
const LangOptions & getLangOpts() const
AssociatedStmtRAII(SemaOpenACC &, OpenACCDirectiveKind, SourceLocation, ArrayRef< const OpenACCClause * >, ArrayRef< OpenACCClause * >)
void SetTileInfoBeforeAssociatedStmt(ArrayRef< const OpenACCClause * > UnInstClauses, ArrayRef< OpenACCClause * > Clauses)
void SetCollapseInfoBeforeAssociatedStmt(ArrayRef< const OpenACCClause * > UnInstClauses, ArrayRef< OpenACCClause * > Clauses)
ExprResult ActOnVar(OpenACCClauseKind CK, Expr *VarExpr)
Called when encountering a 'var' for OpenACC, ensures it is actually a declaration reference to a var...
ComputeConstructInfo & getActiveComputeConstructInfo()
bool ActOnStartStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, ArrayRef< const OpenACCClause * > Clauses)
Called after the directive, including its clauses, have been parsed and parsing has consumed the 'ann...
ExprResult BuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc)
ExprResult ActOnIntExpr(OpenACCDirectiveKind DK, OpenACCClauseKind CK, SourceLocation Loc, Expr *IntExpr)
Called when encountering an 'int-expr' for OpenACC, and manages conversions and diagnostics to 'int'.
void ActOnWhileStmt(SourceLocation WhileLoc)
SourceLocation LoopWorkerClauseLoc
If there is a current 'active' loop construct with a 'worker' clause on it (on any sort of construct)...
bool ActOnStartDeclDirective(OpenACCDirectiveKind K, SourceLocation StartLoc)
Called after the directive, including its clauses, have been parsed and parsing has consumed the 'ann...
bool CheckVarIsPointerType(OpenACCClauseKind ClauseKind, Expr *VarExpr)
Called to check the 'var' type is a variable of pointer type, necessary for 'deviceptr' and 'attach' ...
struct clang::SemaOpenACC::LoopGangOnKernelTy LoopGangClauseOnKernel
struct clang::SemaOpenACC::LoopWithoutSeqCheckingInfo LoopWithoutSeqInfo
StmtResult ActOnEndStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc, SourceLocation LParenLoc, SourceLocation MiscLoc, ArrayRef< Expr * > Exprs, SourceLocation RParenLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses, StmtResult AssocStmt)
Called after the directive has been completely parsed, including the declaration group or associated ...
DeclGroupRef ActOnEndDeclDirective()
Called after the directive has been completely parsed, including the declaration group or associated ...
SourceLocation LoopVectorClauseLoc
If there is a current 'active' loop construct with a 'vector' clause on it (on any sort of construct)...
void ActOnConstruct(OpenACCDirectiveKind K, SourceLocation DirLoc)
Called after the construct has been parsed, but clauses haven't been parsed.
ExprResult ActOnOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc)
void ActOnDoStmt(SourceLocation DoLoc)
void ActOnRangeForStmtBegin(SourceLocation ForLoc, const Stmt *OldRangeFor, const Stmt *RangeFor)
void ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body)
StmtResult ActOnAssociatedStmt(SourceLocation DirectiveLoc, OpenACCDirectiveKind K, ArrayRef< const OpenACCClause * > Clauses, StmtResult AssocStmt)
Called when we encounter an associated statement for our construct, this should check legality of the...
void ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *First, const Stmt *Second, const Stmt *Third)
ExprResult ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc, Expr *LowerBound, SourceLocation ColonLocFirst, Expr *Length, SourceLocation RBLoc)
Checks and creates an Array Section used in an OpenACC construct/clause.
Sema - This implements semantic analysis and AST building for C.
void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl=nullptr, ExpressionEvaluationContextRecord::ExpressionKind Type=ExpressionEvaluationContextRecord::EK_Other)
ExprResult PerformContextualImplicitConversion(SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter)
Perform a contextual implicit conversion.
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
void PopExpressionEvaluationContext()
ExprResult DefaultLvalueConversion(Expr *E)
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
void DiscardCleanupsInEvaluationContext()
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.
bool isValid() const
Return true if this is a valid SourceLocation object.
Stmt - This represents one statement.
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
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
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 isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
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
bool isRecordType() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)
Returns the results of matching Matcher on Node.
bool Inc(InterpState &S, CodePtr OpPC)
1) Pops a pointer from the stack 2) Load the value from the pointer 3) Writes the value increased by ...
The JSON file list parser is used to communicate input to InstallAPI.
@ OK_Ordinary
An ordinary object is located at an address in memory.
OpenACCClauseKind
Represents the kind of an OpenACC clause.
@ DevicePtr
'deviceptr' clause, allowed on Compute and Combined Constructs, plus 'data' and 'declare'.
@ Collapse
'collapse' clause, allowed on 'loop' and Combined constructs.
@ DeviceNum
'device_num' clause, allowed on 'init', 'shutdown', and 'set' constructs.
@ Invalid
Represents an invalid clause, for the purposes of parsing.
@ Copy
'copy' clause, allowed on Compute and Combined Constructs, plus 'data' and 'declare'.
@ Create
'create' clause, allowed on Compute and Combined constructs, plus 'data', 'enter data',...
@ DeviceType
'device_type' clause, allowed on Compute, 'data', 'init', 'shutdown', 'set', update',...
@ DefaultAsync
'default_async' clause, allowed on 'set' construct.
@ Attach
'attach' clause, allowed on Compute and Combined constructs, plus 'data' and 'enter data'.
@ If
'if' clause, allowed on all the Compute Constructs, Data Constructs, Executable Constructs,...
@ Default
'default' clause, allowed on parallel, serial, kernel (and compound) constructs.
@ UseDevice
'use_device' clause, allowed on 'host_data' construct.
@ NoCreate
'no_create' clause, allowed on allowed on Compute and Combined constructs, plus 'data'.
@ Reduction
'reduction' clause, allowed on Parallel, Serial, Loop, and the combined constructs.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ CopyOut
'copyout' clause, allowed on Compute and Combined constructs, plus 'data', 'exit data',...
@ Host
'host' clause, allowed on 'update' construct.
@ Tile
'tile' clause, allowed on 'loop' and Combined constructs.
@ Present
'present' clause, allowed on Compute and Combined constructs, plus 'data' and 'declare'.
@ CopyIn
'copyin' clause, allowed on Compute and Combined constructs, plus 'data', 'enter data',...
@ Device
'device' clause, allowed on the 'update' construct.
@ Detach
'detach' clause, allowed on the 'exit data' construct.
@ Delete
'delete' clause, allowed on the 'exit data' construct.
@ 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.