23#include "llvm/ADT/StringExtras.h"
24#include "llvm/Support/Casting.h"
55 return S.
Diag(StartLoc, diag::err_acc_construct_appertainment) << K;
61void CollectActiveReductionClauses(
64 for (
auto *CurClause : CurClauses) {
65 if (
auto *RedClause = dyn_cast<OpenACCReductionClause>(CurClause);
66 RedClause && !RedClause->getVarList().empty())
67 ActiveClauses.push_back(RedClause);
97 llvm_unreachable(
"Doesn't have an associated stmt");
99 llvm_unreachable(
"Unhandled directive kind?");
101 llvm_unreachable(
"Unhandled directive kind?");
112 : SemaRef(S), OldActiveComputeConstructInfo(S.ActiveComputeConstructInfo),
117 ActiveReductionClauses(S.ActiveReductionClauses),
118 LoopRAII(SemaRef, PreserveLoopRAIIDepthInAssociatedStmtRAII(DirKind)) {
124 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
125 SemaRef.ActiveComputeConstructInfo.Kind = DirKind;
126 SemaRef.ActiveComputeConstructInfo.Clauses = Clauses;
134 SemaRef.LoopGangClauseOnKernel = {};
135 SemaRef.LoopWorkerClauseLoc = {};
136 SemaRef.LoopVectorClauseLoc = {};
137 SemaRef.LoopWithoutSeqInfo = {};
141 SemaRef.ActiveComputeConstructInfo.Kind = DirKind;
142 SemaRef.ActiveComputeConstructInfo.Clauses = Clauses;
144 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
148 SemaRef.LoopGangClauseOnKernel = {};
149 SemaRef.LoopWorkerClauseLoc = {};
150 SemaRef.LoopVectorClauseLoc = {};
154 SemaRef.LoopWithoutSeqInfo = {};
156 llvm::find_if(Clauses, llvm::IsaPred<OpenACCSeqClause>))
157 SemaRef.LoopWithoutSeqInfo = {DirKind, DirLoc};
169 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCGangClause>);
170 if (Itr != Clauses.end())
171 SemaRef.LoopGangClauseOnKernel = {(*Itr)->getBeginLoc(), DirKind};
174 if (UnInstClauses.empty()) {
175 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCWorkerClause>);
176 if (Itr != Clauses.end())
177 SemaRef.LoopWorkerClauseLoc = (*Itr)->getBeginLoc();
179 auto *Itr2 = llvm::find_if(Clauses, llvm::IsaPred<OpenACCVectorClause>);
180 if (Itr2 != Clauses.end())
181 SemaRef.LoopVectorClauseLoc = (*Itr2)->getBeginLoc();
184 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
190 SemaRef.LoopWithoutSeqInfo = {};
192 llvm::find_if(Clauses, llvm::IsaPred<OpenACCSeqClause>))
193 SemaRef.LoopWithoutSeqInfo = {DirKind, DirLoc};
203 if (SemaRef.getActiveComputeConstructInfo().Kind ==
205 UnInstClauses.empty()) {
207 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCGangClause>);
208 if (Itr != Clauses.end())
209 SemaRef.LoopGangClauseOnKernel = {(*Itr)->getBeginLoc(),
213 if (UnInstClauses.empty()) {
214 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCWorkerClause>);
215 if (Itr != Clauses.end())
216 SemaRef.LoopWorkerClauseLoc = (*Itr)->getBeginLoc();
218 auto *Itr2 = llvm::find_if(Clauses, llvm::IsaPred<OpenACCVectorClause>);
219 if (Itr2 != Clauses.end())
220 SemaRef.LoopVectorClauseLoc = (*Itr2)->getBeginLoc();
235 if (!
New->getLoopCount())
239 if (!
New->getLoopCount())
243 if (
New->getLoopCount()->isInstantiationDependent())
272 SemaRef.LoopInfo.CurLevelHasLoopAlready =
false;
273 SemaRef.CollapseInfo.CollapseDepthSatisfied =
true;
274 SemaRef.CollapseInfo.CurCollapseCount = 0;
275 SemaRef.TileInfo.TileDepthSatisfied =
true;
286 auto *UnInstClauseItr =
287 llvm::find_if(UnInstClauses, llvm::IsaPred<OpenACCCollapseClause>);
289 llvm::find_if(Clauses, llvm::IsaPred<OpenACCCollapseClause>);
298 while (ClauseItr != Clauses.end()) {
302 UnInstClauseItr == UnInstClauses.end()
307 getBestCollapseCandidate(FoundClause, CurClause, UnInstCurClause);
310 UnInstClauseItr == UnInstClauses.end()
312 : std::find_if(std::next(UnInstClauseItr), UnInstClauses.end(),
313 llvm::IsaPred<OpenACCCollapseClause>);
314 ClauseItr = std::find_if(std::next(ClauseItr), Clauses.end(),
315 llvm::IsaPred<OpenACCCollapseClause>);
321 SemaRef.CollapseInfo.ActiveCollapse = FoundClause;
322 SemaRef.CollapseInfo.CollapseDepthSatisfied =
false;
323 SemaRef.CollapseInfo.CurCollapseCount =
325 SemaRef.CollapseInfo.DirectiveKind = DirKind;
334 if (UnInstClauses.size() > 0)
336 auto *TileClauseItr =
337 llvm::find_if(Clauses, llvm::IsaPred<OpenACCTileClause>);
339 if (Clauses.end() == TileClauseItr)
346 while (Clauses.end() !=
347 (TileClauseItr = std::find_if(std::next(TileClauseItr), Clauses.end(),
348 llvm::IsaPred<OpenACCTileClause>))) {
351 TileClause = NewClause;
354 SemaRef.TileInfo.ActiveTile = TileClause;
355 SemaRef.TileInfo.TileDepthSatisfied =
false;
356 SemaRef.TileInfo.CurTileCount =
357 static_cast<unsigned>(TileClause->
getSizeExprs().size());
358 SemaRef.TileInfo.DirectiveKind = DirKind;
369 SemaRef.ActiveComputeConstructInfo = OldActiveComputeConstructInfo;
370 SemaRef.LoopGangClauseOnKernel = OldLoopGangClauseOnKernel;
371 SemaRef.LoopWorkerClauseLoc = OldLoopWorkerClauseLoc;
372 SemaRef.LoopVectorClauseLoc = OldLoopVectorClauseLoc;
373 SemaRef.LoopWithoutSeqInfo = OldLoopWithoutSeqInfo;
374 SemaRef.ActiveReductionClauses.swap(ActiveReductionClauses);
385 SemaRef.PushExpressionEvaluationContext(
402 "Only one of directive or clause kind should be provided");
411 unsigned getDiagKind()
const {
422 : ICEConvertDiagnoser(
false,
425 DirectiveKind(DK), ClauseKind(CK), IntExpr(IntExpr) {}
430 return T->isIntegerType();
434 return S.
Diag(Loc, diag::err_acc_int_expr_requires_integer)
435 << getDiagKind() << ClauseKind << DirectiveKind <<
T;
440 return S.
Diag(Loc, diag::err_acc_int_expr_incomplete_class_type)
447 return S.
Diag(Loc, diag::err_acc_int_expr_explicit_conversion)
460 return S.
Diag(Loc, diag::err_acc_int_expr_multiple_conversions) <<
T;
472 llvm_unreachable(
"conversion functions are permitted");
474 } IntExprDiagnoser(DK, CK, IntExpr);
480 Loc, IntExpr, IntExprDiagnoser);
484 IntExpr = IntExprResult.
get();
518 return Diag(VarExpr->
getExprLoc(), diag::err_acc_var_not_pointer_type)
526 CacheInfo.ParsingCacheVarList =
true;
527 CacheInfo.IsInvalidCacheRef =
false;
532 CacheInfo.ParsingCacheVarList =
false;
533 CacheInfo.IsInvalidCacheRef =
false;
543 bool WasParsingInvalidCacheRef =
544 CacheInfo.ParsingCacheVarList && CacheInfo.IsInvalidCacheRef;
545 CacheInfo.ParsingCacheVarList =
false;
546 CacheInfo.IsInvalidCacheRef =
false;
556 if (
auto *SubScrpt = dyn_cast<ArraySubscriptExpr>(CurVarExpr))
564 if (
const auto *DRE = dyn_cast<DeclRefExpr>(CurVarExpr)) {
566 DRE->getFoundDecl()->getCanonicalDecl()))
567 return WasParsingInvalidCacheRef ?
ExprEmpty() : VarExpr;
570 if (
const auto *ME = dyn_cast<MemberExpr>(CurVarExpr)) {
572 return WasParsingInvalidCacheRef ?
ExprEmpty() : VarExpr;
579 return WasParsingInvalidCacheRef ?
ExprEmpty() : VarExpr;
591 if (!
getLangOpts().OpenACC || !CacheInfo.ParsingCacheVarList || !D ||
617 Diag(Loc, diag::warn_acc_cache_var_not_outside_loop);
619 CacheInfo.IsInvalidCacheRef =
true;
652 if (!ArrTy->isConstantArrayType()) {
653 S.
Diag(InnerLoc, clang::diag::warn_acc_var_referenced_non_const_array)
658 return CheckVarType(S, CK, VarExpr, InnerLoc, ArrTy->getElementType());
669 bool HasNonDeletedDefaultCtor =
670 llvm::find_if(RD->ctors(), [](
const CXXConstructorDecl *CD) {
671 return CD->isDefaultConstructor() && !CD->isDeleted();
672 }) != RD->ctors().end();
673 if (!HasNonDeletedDefaultCtor && !RD->needsImplicitDefaultConstructor()) {
674 S.
Diag(InnerLoc, clang::diag::warn_acc_var_referenced_lacks_op)
675 << InnerTy << CK << clang::diag::AccVarReferencedReason::DefCtor;
679 if (!RD->hasSimpleCopyConstructor()) {
687 S.
Diag(InnerLoc, clang::diag::warn_acc_var_referenced_lacks_op)
688 << InnerTy << CK << clang::diag::AccVarReferencedReason::CopyCtor;
699 bool DestructorDeleted =
700 RD->getDestructor() && RD->getDestructor()->isDeleted();
701 if (DestructorDeleted && !RD->needsImplicitDestructor()) {
702 S.
Diag(InnerLoc, clang::diag::warn_acc_var_referenced_lacks_op)
703 << InnerTy << CK << clang::diag::AccVarReferencedReason::Dtor;
713 return CheckVarType(S, CK, VarExpr, InnerExpr->
getBeginLoc(),
736 diag::err_acc_not_a_var_ref_use_device_declare)
744 diag::ext_acc_array_section_use_device_declare)
751 if (
auto *SubScrpt = dyn_cast<ArraySubscriptExpr>(CurVarExpr))
759 if (
const auto *DRE = dyn_cast<DeclRefExpr>(CurVarExpr)) {
761 DRE->getFoundDecl()->getCanonicalDecl()))
762 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
771 if (
const auto *ME = dyn_cast<MemberExpr>(CurVarExpr)) {
779 const auto *
This = dyn_cast<CXXThisExpr>(ME->getBase());
781 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
783 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
792 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
799 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
807 Diag(VarExpr->
getExprLoc(), diag::err_acc_not_a_var_ref_use_device_declare)
810 Diag(VarExpr->
getExprLoc(), diag::err_acc_not_a_var_ref_use_device_declare)
826 if (
Base->hasPlaceholderType() &&
827 !
Base->hasPlaceholderType(BuiltinType::ArraySection)) {
840 LowerBound =
Result.get();
842 if (Length && Length->getType()->isNonOverloadPlaceholderType()) {
856 if (!
Base->isTypeDependent()) {
863 Diag(
Base->getExprLoc(), diag::err_acc_typecheck_subarray_value)
864 <<
Base->getSourceRange());
868 Diag(
Base->getExprLoc(), diag::err_acc_subarray_function_type)
869 << ResultTy <<
Base->getSourceRange();
873 if (
SemaRef.RequireCompleteType(
Base->getExprLoc(), ResultTy,
874 diag::err_acc_subarray_incomplete_type,
878 if (!
Base->hasPlaceholderType(BuiltinType::ArraySection)) {
889 return Recovery.
isUsable() ? Recovery.
get() :
nullptr;
899 LBRes =
SemaRef.DefaultLvalueConversion(LBRes.
get());
901 LBRes.
isUsable() ? LBRes.
get() : GetRecovery(LowerBound, Context.IntTy);
904 if (Length && !Length->isTypeDependent()) {
907 Length->getExprLoc(), Length);
910 LenRes =
SemaRef.DefaultLvalueConversion(LenRes.
get());
912 LenRes.
isUsable() ? LenRes.
get() : GetRecovery(Length, Context.IntTy);
916 if (!Length && (OriginalBaseTy.
isNull() ||
922 Diag(DiagLoc, diag::err_acc_subarray_no_length) << IsArray;
927 Length = Recovery.
isUsable() ? Recovery.
get() :
nullptr;
938 std::optional<llvm::APSInt> BaseSize;
940 const auto *ArrayTy = Context.getAsConstantArrayType(OriginalBaseTy);
941 BaseSize = ArrayTy->getSize();
944 auto GetBoundValue = [&](
Expr *E) -> std::optional<llvm::APSInt> {
954 std::optional<llvm::APSInt> LowerBoundValue = GetBoundValue(LowerBound);
955 std::optional<llvm::APSInt> LengthValue = GetBoundValue(Length);
958 if (LowerBoundValue.has_value()) {
959 if (LowerBoundValue->isNegative()) {
961 << 0 <<
toString(*LowerBoundValue, 10);
962 LowerBoundValue.reset();
963 LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
964 }
else if (BaseSize.has_value() &&
965 llvm::APSInt::compareValues(*LowerBoundValue, *BaseSize) >= 0) {
967 Diag(LowerBound->
getExprLoc(), diag::err_acc_subarray_out_of_range)
968 << 0 <<
toString(*LowerBoundValue, 10)
970 LowerBoundValue.reset();
971 LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
976 if (LengthValue.has_value()) {
977 if (LengthValue->isNegative()) {
978 Diag(Length->getExprLoc(), diag::err_acc_subarray_negative)
981 Length = GetRecovery(Length, Length->getType());
982 }
else if (BaseSize.has_value() &&
983 llvm::APSInt::compareValues(*LengthValue, *BaseSize) > 0) {
985 Diag(Length->getExprLoc(), diag::err_acc_subarray_out_of_range)
989 Length = GetRecovery(Length, Length->getType());
994 auto AddAPSInt = [](llvm::APSInt LHS, llvm::APSInt RHS) -> llvm::APSInt {
995 if (LHS.isSigned() == RHS.isSigned())
998 unsigned Width = std::max(LHS.getBitWidth(), RHS.getBitWidth()) + 1;
999 return llvm::APSInt(LHS.sext(Width) + RHS.sext(Width),
true);
1004 if (BaseSize.has_value() && LowerBoundValue.has_value() &&
1005 LengthValue.has_value() &&
1006 llvm::APSInt::compareValues(AddAPSInt(*LowerBoundValue, *LengthValue),
1009 diag::err_acc_subarray_base_plus_length_out_of_range)
1014 LowerBoundValue.reset();
1015 LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
1016 LengthValue.reset();
1017 Length = GetRecovery(Length, Length->getType());
1021 QualType ArrayExprTy = Context.ArraySectionTy;
1022 if (
Base->isTypeDependent() ||
1024 (Length && Length->isTypeDependent()))
1025 ArrayExprTy = Context.DependentTy;
1027 return new (Context)
1036 if (!LoopInfo.TopLevelLoopSeen)
1039 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
1040 Diag(WhileLoc, diag::err_acc_invalid_in_loop)
1041 << 1 << CollapseInfo.DirectiveKind
1043 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
1044 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1045 diag::note_acc_active_clause_here)
1050 CollapseInfo.CurCollapseCount = std::nullopt;
1053 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
1054 Diag(WhileLoc, diag::err_acc_invalid_in_loop)
1055 << 1 << TileInfo.DirectiveKind
1057 assert(TileInfo.ActiveTile &&
"tile count without object?");
1058 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
1063 TileInfo.CurTileCount = std::nullopt;
1071 if (!LoopInfo.TopLevelLoopSeen)
1074 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
1075 Diag(DoLoc, diag::err_acc_invalid_in_loop)
1076 << 2 << CollapseInfo.DirectiveKind
1078 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
1079 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1080 diag::note_acc_active_clause_here)
1085 CollapseInfo.CurCollapseCount = std::nullopt;
1088 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
1089 Diag(DoLoc, diag::err_acc_invalid_in_loop)
1091 assert(TileInfo.ActiveTile &&
"tile count without object?");
1092 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
1097 TileInfo.CurTileCount = std::nullopt;
1102 ForStmtBeginChecker &
C) {
1103 assert(
getLangOpts().OpenACC &&
"Check enabled when not OpenACC?");
1106 LoopInfo.TopLevelLoopSeen =
true;
1108 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
1117 if (LoopInfo.CurLevelHasLoopAlready) {
1118 Diag(ForLoc, diag::err_acc_clause_multiple_loops)
1120 assert(CollapseInfo.ActiveCollapse &&
"No collapse object?");
1122 diag::note_acc_active_clause_here)
1125 --(*CollapseInfo.CurCollapseCount);
1129 if (*CollapseInfo.CurCollapseCount == 0)
1130 CollapseInfo.CollapseDepthSatisfied =
true;
1134 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
1138 if (LoopInfo.CurLevelHasLoopAlready) {
1139 Diag(ForLoc, diag::err_acc_clause_multiple_loops)
1141 assert(TileInfo.ActiveTile &&
"No tile object?");
1142 Diag(TileInfo.ActiveTile->getBeginLoc(),
1143 diag::note_acc_active_clause_here)
1146 TileInfo.CurTileCount = *TileInfo.CurTileCount - 1;
1149 if (*TileInfo.CurTileCount == 0)
1150 TileInfo.TileDepthSatisfied =
true;
1156 LoopInfo.CurLevelHasLoopAlready =
false;
1160bool isValidLoopVariableType(QualType LoopVarTy) {
1183 for (
const auto *TD :
1184 llvm::make_filter_range(RD->decls(), llvm::IsaPred<TypedefNameDecl>)) {
1187 if (TDND->getName() !=
"iterator_category")
1191 if (TDND->getUnderlyingType().isNull())
1194 const CXXRecordDecl *ItrCategoryDecl =
1195 TDND->getUnderlyingType()->getAsCXXRecordDecl();
1198 if (!ItrCategoryDecl)
1201 auto IsRandomAccessIteratorTag = [](
const CXXRecordDecl *RD) {
1202 if (RD->getName() !=
"random_access_iterator_tag")
1205 return RD->getEnclosingNamespaceContext()->isStdNamespace();
1208 if (IsRandomAccessIteratorTag(ItrCategoryDecl))
1213 for (CXXBaseSpecifier BS : ItrCategoryDecl->
bases())
1214 if (IsRandomAccessIteratorTag(BS.getType()->getAsCXXRecordDecl()))
1223const ValueDecl *getDeclFromExpr(
const Expr *E) {
1225 if (
const auto *FE = dyn_cast<FullExpr>(E))
1226 E = FE->getSubExpr();
1232 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
1233 return dyn_cast<ValueDecl>(DRE->getDecl());
1235 if (
const auto *ME = dyn_cast<MemberExpr>(E))
1237 return ME->getMemberDecl();
1243void SemaOpenACC::ForStmtBeginChecker::checkRangeFor() {
1244 const RangeForInfo &RFI = std::get<RangeForInfo>(Info);
1246 if (RFI.Uninstantiated == RFI.CurrentVersion)
1249 const DeclStmt *UninstRangeStmt =
1250 IsInstantiation ? RFI.Uninstantiated->getBeginStmt() :
nullptr;
1251 const DeclStmt *RangeStmt = RFI.CurrentVersion->getBeginStmt();
1255 if (UninstRangeStmt) {
1256 const ValueDecl *InitVar =
1260 if (!isValidLoopVariableType(VarType))
1270 if (!isValidLoopVariableType(VarType)) {
1272 <<
SemaRef.LoopWithoutSeqInfo.Kind << VarType;
1274 diag::note_acc_construct_here)
1275 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1280bool SemaOpenACC::ForStmtBeginChecker::checkForInit(
const Stmt *InitStmt,
1281 const ValueDecl *&InitVar,
1286 SemaRef.Diag(ForLoc, diag::err_acc_loop_variable)
1287 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1289 diag::note_acc_construct_here)
1290 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1294 auto DiagLoopVar = [
this,
Diag, InitStmt]() {
1297 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1299 diag::note_acc_construct_here)
1300 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1305 if (
const auto *ExprTemp = dyn_cast<ExprWithCleanups>(InitStmt))
1306 InitStmt = ExprTemp->getSubExpr();
1307 if (
const auto *E = dyn_cast<Expr>(InitStmt))
1311 if (
const auto *BO = dyn_cast<BinaryOperator>(InitStmt)) {
1314 if (!BO->isAssignmentOp())
1315 return DiagLoopVar();
1317 const Expr *LHS = BO->getLHS()->IgnoreParenImpCasts();
1318 if (
const auto *DRE = dyn_cast<DeclRefExpr>(LHS))
1319 InitVar = DRE->getDecl();
1320 }
else if (
const auto *DS = dyn_cast<DeclStmt>(InitStmt)) {
1322 if (!DS->isSingleDecl())
1323 return DiagLoopVar();
1324 InitVar = dyn_cast<ValueDecl>(DS->getSingleDecl());
1329 return DiagLoopVar();
1334 return DiagLoopVar();
1336 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(InitStmt)) {
1338 if (CE->getOperator() != OO_Equal)
1339 return DiagLoopVar();
1342 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
1343 InitVar = DRE->getDecl();
1344 }
else if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
1346 InitVar = ME->getMemberDecl();
1352 return DiagLoopVar();
1358 if (!isValidLoopVariableType(VarType)) {
1361 <<
SemaRef.LoopWithoutSeqInfo.Kind << VarType;
1363 diag::note_acc_construct_here)
1364 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1372bool SemaOpenACC::ForStmtBeginChecker::checkForCond(
const Stmt *CondStmt,
1373 const ValueDecl *InitVar,
1378 SemaRef.Diag(ForLoc, diag::err_acc_loop_terminating_condition)
1379 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1381 diag::note_acc_construct_here)
1382 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1387 auto DiagCondVar = [
this,
Diag, CondStmt] {
1390 diag::err_acc_loop_terminating_condition)
1391 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1393 diag::note_acc_construct_here)
1394 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1399 if (
const auto *ExprTemp = dyn_cast<ExprWithCleanups>(CondStmt))
1400 CondStmt = ExprTemp->getSubExpr();
1401 if (
const auto *E = dyn_cast<Expr>(CondStmt))
1404 const ValueDecl *CondVar =
nullptr;
1405 if (
const auto *BO = dyn_cast<BinaryOperator>(CondStmt)) {
1406 switch (BO->getOpcode()) {
1408 return DiagCondVar();
1421 CondVar = getDeclFromExpr(BO->getLHS());
1424 CondVar = getDeclFromExpr(BO->getRHS());
1426 }
else if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(CondStmt)) {
1429 if (!CE->isComparisonOp() || CE->getOperator() == OO_Spaceship)
1430 return DiagCondVar();
1434 CondVar = getDeclFromExpr(CE->getArg(0));
1438 CE->getNumArgs() > 1))
1439 CondVar = getDeclFromExpr(CE->getArg(1));
1441 return DiagCondVar();
1445 return DiagCondVar();
1450 return DiagCondVar();
1459bool isValidForIncRHSAssign(
const ValueDecl *InitVar,
const Expr *RHS) {
1461 auto isValid = [](
const ValueDecl *InitVar,
const Expr *InnerLHS,
1462 const Expr *InnerRHS,
bool IsAddition) {
1464 if (!InnerLHS->getType()->isIntegerType() &&
1465 !InnerRHS->getType()->isIntegerType())
1473 const ValueDecl *LHSDecl = getDeclFromExpr(InnerLHS);
1474 const ValueDecl *RHSDecl = getDeclFromExpr(InnerRHS);
1476 if (!LHSDecl || !RHSDecl)
1492 if (
const auto *BO = dyn_cast<BinaryOperator>(RHS)) {
1494 if (OpC != BO_Add && OpC != BO_Sub)
1496 return isValid(InitVar, BO->getLHS(), BO->getRHS(), OpC == BO_Add);
1497 }
else if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
1499 if (Op != OO_Plus && Op != OO_Minus)
1501 return isValid(InitVar, CE->getArg(0), CE->getArg(1), Op == OO_Plus);
1508bool SemaOpenACC::ForStmtBeginChecker::checkForInc(
const Stmt *IncStmt,
1509 const ValueDecl *InitVar,
1513 SemaRef.Diag(ForLoc, diag::err_acc_loop_not_monotonic)
1514 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1516 diag::note_acc_construct_here)
1517 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1521 auto DiagIncVar = [
this,
Diag, IncStmt] {
1524 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1526 diag::note_acc_construct_here)
1527 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1532 if (
const auto *ExprTemp = dyn_cast<ExprWithCleanups>(IncStmt))
1533 IncStmt = ExprTemp->getSubExpr();
1534 if (
const auto *E = dyn_cast<Expr>(IncStmt))
1537 const ValueDecl *IncVar =
nullptr;
1539 if (
const auto *UO = dyn_cast<UnaryOperator>(IncStmt)) {
1541 if (!UO->isIncrementDecrementOp())
1542 return DiagIncVar();
1543 IncVar = getDeclFromExpr(UO->getSubExpr());
1544 }
else if (
const auto *BO = dyn_cast<BinaryOperator>(IncStmt)) {
1545 switch (BO->getOpcode()) {
1547 return DiagIncVar();
1554 if (!isValidForIncRHSAssign(InitVar, BO->getRHS()))
1555 return DiagIncVar();
1558 IncVar = getDeclFromExpr(BO->getLHS());
1559 }
else if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(IncStmt)) {
1560 switch (CE->getOperator()) {
1562 return DiagIncVar();
1571 if (!isValidForIncRHSAssign(InitVar, CE->getArg(1)))
1572 return DiagIncVar();
1576 IncVar = getDeclFromExpr(CE->getArg(0));
1578 return DiagIncVar();
1582 return DiagIncVar();
1588 return DiagIncVar();
1593void SemaOpenACC::ForStmtBeginChecker::checkFor() {
1594 const CheckForInfo &CFI = std::get<CheckForInfo>(Info);
1596 if (!IsInstantiation) {
1599 const ValueDecl *CurInitVar =
nullptr;
1600 checkForInit(CFI.Current.Init, CurInitVar,
true);
1601 checkForCond(CFI.Current.Condition, CurInitVar,
true);
1602 checkForInc(CFI.Current.Increment, CurInitVar,
true);
1604 const ValueDecl *UninstInitVar =
nullptr;
1608 bool UninstInitFailed =
1609 checkForInit(CFI.Uninst.Init, UninstInitVar,
false);
1615 auto InitChanged = [=]() {
1616 if (CFI.Uninst.Init == CFI.Current.Init)
1622 if (
const auto *DS = dyn_cast<DeclStmt>(CFI.Uninst.Init))
1623 if (
const VarDecl *VD = dyn_cast_if_present<VarDecl>(
1624 DS->isSingleDecl() ? DS->getSingleDecl() :
nullptr))
1625 OldVDTy = VD->getType();
1626 if (
const auto *DS = dyn_cast<DeclStmt>(CFI.Current.Init))
1627 if (
const VarDecl *VD = dyn_cast_if_present<VarDecl>(
1628 DS->isSingleDecl() ? DS->getSingleDecl() :
nullptr))
1629 NewVDTy = VD->getType();
1640 bool ShouldDiagNewInit = !UninstInitFailed && InitChanged();
1641 const ValueDecl *CurInitVar =
nullptr;
1642 checkForInit(CFI.Current.Init, CurInitVar, ShouldDiagNewInit);
1646 if (CFI.Uninst.Condition != CFI.Current.Condition &&
1647 !checkForCond(CFI.Uninst.Condition, UninstInitVar,
false))
1648 checkForCond(CFI.Current.Condition, CurInitVar,
true);
1649 if (CFI.Uninst.Increment != CFI.Current.Increment &&
1650 !checkForInc(CFI.Uninst.Increment, UninstInitVar,
false))
1651 checkForInc(CFI.Current.Increment, CurInitVar,
true);
1655void SemaOpenACC::ForStmtBeginChecker::check() {
1666 AlreadyChecked =
true;
1683 if (std::holds_alternative<RangeForInfo>(Info))
1684 return checkRangeFor();
1691 const Stmt *Second,
const Stmt *OldThird,
1692 const Stmt *Third) {
1696 ForStmtBeginChecker FSBC{*
this, ForLoc, OldFirst, OldSecond,
1697 OldThird,
First, Second, Third};
1700 if (!LoopInfo.TopLevelLoopSeen) {
1704 ForStmtBeginHelper(ForLoc, FSBC);
1708 const Stmt *Second,
const Stmt *Third) {
1712 ForStmtBeginChecker FSBC{*
this, ForLoc,
First, Second, Third};
1716 if (!LoopInfo.TopLevelLoopSeen)
1719 ForStmtBeginHelper(ForLoc, FSBC);
1723 const Stmt *OldRangeFor,
1724 const Stmt *RangeFor) {
1725 if (!
getLangOpts().OpenACC || OldRangeFor ==
nullptr || RangeFor ==
nullptr)
1728 ForStmtBeginChecker FSBC{*
this, ForLoc,
1729 cast_if_present<CXXForRangeStmt>(OldRangeFor),
1730 cast_if_present<CXXForRangeStmt>(RangeFor)};
1733 if (!LoopInfo.TopLevelLoopSeen) {
1736 ForStmtBeginHelper(ForLoc, FSBC);
1740 const Stmt *RangeFor) {
1741 if (!
getLangOpts().OpenACC || RangeFor ==
nullptr)
1744 ForStmtBeginChecker FSBC = {*
this, ForLoc,
1745 cast_if_present<CXXForRangeStmt>(RangeFor)};
1749 if (!LoopInfo.TopLevelLoopSeen)
1752 ForStmtBeginHelper(ForLoc, FSBC);
1772 if (
const auto *CS = dyn_cast<CompoundStmt>(CurStmt)) {
1773 for (
const auto *ChildStmt : CS->children()) {
1774 SourceLocation ChildStmtLoc = FindInterveningCodeInLoop(ChildStmt);
1776 return ChildStmtLoc;
1779 return SourceLocation{};
1790 LoopInfo.CurLevelHasLoopAlready =
true;
1795 bool IsActiveCollapse = CollapseInfo.CurCollapseCount &&
1796 *CollapseInfo.CurCollapseCount > 0 &&
1797 !CollapseInfo.ActiveCollapse->hasForce();
1798 bool IsActiveTile = TileInfo.CurTileCount && *TileInfo.CurTileCount > 0;
1800 if (IsActiveCollapse || IsActiveTile) {
1803 if (OtherStmtLoc.
isValid() && IsActiveCollapse) {
1804 Diag(OtherStmtLoc, diag::err_acc_intervening_code)
1806 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1807 diag::note_acc_active_clause_here)
1811 if (OtherStmtLoc.
isValid() && IsActiveTile) {
1812 Diag(OtherStmtLoc, diag::err_acc_intervening_code)
1814 Diag(TileInfo.ActiveTile->getBeginLoc(),
1815 diag::note_acc_active_clause_here)
1835 }
else if (
auto *DRE = dyn_cast<DeclRefExpr>(RoutineName)) {
1836 ValueDecl *VD = DRE->getDecl();
1838 if (
auto *FD = dyn_cast<FunctionDecl>(VD))
1842 if (
auto *VarD = dyn_cast<VarDecl>(VD)) {
1843 QualType VarDTy = VarD->getType();
1846 if (RD->isGenericLambda())
1849 return RD->getLambdaCallOperator();
1865 assert(RoutineName &&
"Routine name cannot be null here");
1876 }
else if (
const auto *DRE = dyn_cast<DeclRefExpr>(RoutineName)) {
1883 if (
const auto *VarD = dyn_cast<VarDecl>(VD)) {
1887 if (RD->isGenericLambda()) {
1927 auto *ContextDecl = dyn_cast<FunctionDecl>(
getCurContext());
1935 for (
const auto *A : ContextDecl->attrs()) {
1938 Diag(A->getLocation(), diag::note_acc_construct_here)
1944 MagicStaticLocs.insert({ContextDecl->getCanonicalDecl(), VD->
getBeginLoc()});
1946void SemaOpenACC::CheckLastRoutineDeclNameConflict(
const NamedDecl *ND) {
1955 if (!LastRoutineDecl)
1988 if (NDLine - LastLine > 1)
1996 diag::warn_acc_confusing_routine_name);
2012 if (!RD || !RD->isLambda())
2015 CheckLastRoutineDeclNameConflict(VD);
2021 CheckLastRoutineDeclNameConflict(FD);
2033 SemaRef.DiscardCleanupsInEvaluationContext();
2034 SemaRef.PopExpressionEvaluationContext();
2041 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
2042 Diag(StartLoc, diag::err_acc_invalid_in_loop)
2043 << 0 << CollapseInfo.DirectiveKind
2045 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
2046 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
2047 diag::note_acc_active_clause_here)
2050 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
2051 Diag(StartLoc, diag::err_acc_invalid_in_loop)
2052 << 0 << TileInfo.DirectiveKind
2054 assert(TileInfo.ActiveTile &&
"Tile count without object?");
2055 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
2059 if (DiagnoseRequiredClauses(K, StartLoc, Clauses))
2061 return diagnoseConstructAppertainment(*
this, K, StartLoc,
true);
2076 return OpenACCComputeConstruct::Create(
2078 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2085 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2089 getASTContext(), ActiveComputeConstructInfo.Kind, StartLoc, DirLoc,
2090 EndLoc, Clauses, AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2095 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2108 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2112 getASTContext(), StartLoc, DirLoc, LParenLoc, Exprs.front(), MiscLoc,
2113 Exprs.drop_front(), RParenLoc, EndLoc, Clauses);
2133 getASTContext(), StartLoc, DirLoc, AtomicKind, EndLoc, Clauses,
2134 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2137 assert(Clauses.empty() &&
"Cache doesn't allow clauses");
2139 LParenLoc, MiscLoc, Exprs, RParenLoc,
2143 llvm_unreachable(
"routine shouldn't handled here");
2148 RParenLoc, EndLoc, Clauses);
2153 llvm_unreachable(
"Unhandled case in directive handling?");
2162 llvm_unreachable(
"Unimplemented associated statement application");
2171 "these don't have associated statements, so shouldn't get here");
2199 Diag(DirectiveLoc, diag::note_acc_construct_here) << K;
2203 if (!CollapseInfo.CollapseDepthSatisfied || !TileInfo.TileDepthSatisfied) {
2204 if (!CollapseInfo.CollapseDepthSatisfied) {
2205 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
2207 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
2208 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
2209 diag::note_acc_active_clause_here)
2213 if (!TileInfo.TileDepthSatisfied) {
2214 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
2216 assert(TileInfo.ActiveTile &&
"Collapse count without object?");
2217 Diag(TileInfo.ActiveTile->getBeginLoc(),
2218 diag::note_acc_active_clause_here)
2224 return AssocStmt.
get();
2226 llvm_unreachable(
"Invalid associated statement application");
2234bool CheckValidRoutineGangWorkerVectorSeqClauses(
2246 auto *FirstDeviceType =
2247 llvm::find_if(Clauses, llvm::IsaPred<OpenACCDeviceTypeClause>);
2252 std::find_if(Clauses.begin(), FirstDeviceType, RequiredPred);
2254 if (ClauseItr != FirstDeviceType)
2258 if (FirstDeviceType == Clauses.end())
2259 return SemaRef.
Diag(DirectiveLoc, diag::err_acc_construct_one_clause_of)
2261 <<
"'gang', 'seq', 'vector', or 'worker'";
2265 auto *PrevDeviceType = FirstDeviceType;
2267 while (PrevDeviceType != Clauses.end()) {
2268 auto *NextDeviceType =
2269 std::find_if(std::next(PrevDeviceType), Clauses.end(),
2270 llvm::IsaPred<OpenACCDeviceTypeClause>);
2272 ClauseItr = std::find_if(PrevDeviceType, NextDeviceType, RequiredPred);
2274 if (ClauseItr == NextDeviceType)
2275 return SemaRef.
Diag((*PrevDeviceType)->getBeginLoc(),
2276 diag::err_acc_clause_routine_one_of_in_region);
2278 PrevDeviceType = NextDeviceType;
2291 SemaRef.DiscardCleanupsInEvaluationContext();
2292 SemaRef.PopExpressionEvaluationContext();
2294 if (DiagnoseRequiredClauses(K, StartLoc, Clauses))
2297 CheckValidRoutineGangWorkerVectorSeqClauses(*
this, StartLoc, Clauses))
2300 return diagnoseConstructAppertainment(*
this, K, StartLoc,
false);
2313 if (Clauses.empty()) {
2314 Diag(EndLoc, diag::err_acc_declare_required_clauses);
2328 llvm_unreachable(
"routine shouldn't be handled here");
2330 llvm_unreachable(
"unhandled case in directive handling?");
2341 if (
auto *FD = dyn_cast<FunctionDecl>(D))
2345 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
2346 return FTD->getTemplatedDecl();
2348 if (
auto *FD = dyn_cast<FieldDecl>(D)) {
2350 FD->getType().isNull() ?
nullptr : FD->getType()->getAsCXXRecordDecl();
2352 if (RD && RD->isGenericLambda())
2353 return RD->getDependentLambdaCallOperator()->getTemplatedDecl();
2354 if (RD && RD->isLambda())
2355 return RD->getLambdaCallOperator();
2359 if (
auto *VD = dyn_cast<VarDecl>(D)) {
2361 if (!
Init ||
Init->getType().isNull())
2364 const auto *RD =
Init->getType()->getAsCXXRecordDecl();
2365 if (RD && RD->isGenericLambda())
2366 return RD->getDependentLambdaCallOperator()->getTemplatedDecl();
2367 if (RD && RD->isLambda())
2368 return RD->getLambdaCallOperator();
2383 ArrayRef<const OpenACCClause *> Clauses,
2385 OpenACCRoutineDeclAttr *A =
2386 OpenACCRoutineDeclAttr::Create(
SemaRef.getASTContext(), DirLoc);
2387 A->Clauses.assign(Clauses.begin(), Clauses.end());
2395 Decl *NextParsedDecl) {
2397 FunctionDecl *NextParsedFDecl = LegalizeNextParsedDecl(NextParsedDecl);
2399 if (!NextParsedFDecl) {
2401 SemaRef.Diag(DirLoc, diag::err_acc_decl_for_routine);
2409 Itr != MagicStaticLocs.end()) {
2410 Diag(Itr->second, diag::err_acc_magic_static_in_routine);
2411 Diag(DirLoc, diag::note_acc_construct_here)
2417 auto BindItr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCBindClause>);
2418 for (
auto *A : NextParsedFDecl->
attrs()) {
2422 if (
auto *RA = dyn_cast<OpenACCRoutineDeclAttr>(A)) {
2424 llvm::find_if(RA->Clauses, llvm::IsaPred<OpenACCBindClause>);
2425 if (OtherBindItr != RA->Clauses.end() &&
2428 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_unnamed_bind);
2429 Diag((*OtherBindItr)->getEndLoc(), diag::note_acc_previous_clause_here)
2430 << (*BindItr)->getClauseKind();
2441 if (
auto *RA = dyn_cast<OpenACCRoutineAnnotAttr>(A);
2442 RA && RA->getRange().getEnd().isValid()) {
2443 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
2444 Diag(RA->getRange().getEnd(), diag::note_acc_previous_clause_here)
2450 CreateRoutineDeclAttr(*
this, DirLoc, Clauses, NextParsedFDecl);
2460 if (
FunctionDecl *FD = getFunctionFromRoutineName(FuncRef)) {
2464 if (
auto Itr = MagicStaticLocs.find(FD->getCanonicalDecl());
2465 Itr != MagicStaticLocs.end()) {
2466 Diag(Itr->second, diag::err_acc_magic_static_in_routine);
2467 Diag(DirLoc, diag::note_acc_construct_here)
2476 auto BindItr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCBindClause>);
2478 if (BindItr != Clauses.end()) {
2479 BindLoc = (*BindItr)->getBeginLoc();
2483 for (
auto *A : FD->attrs()) {
2484 if (
auto *RA = dyn_cast<OpenACCRoutineDeclAttr>(A)) {
2486 llvm::find_if(RA->Clauses, llvm::IsaPred<OpenACCBindClause>);
2487 if (OtherBindItr != RA->Clauses.end()) {
2488 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
2489 Diag((*OtherBindItr)->getEndLoc(),
2490 diag::note_acc_previous_clause_here)
2491 << (*BindItr)->getClauseKind();
2496 if (
auto *RA = dyn_cast<OpenACCRoutineAnnotAttr>(A);
2497 RA && RA->getRange().getEnd().isValid()) {
2498 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
2499 Diag(RA->getRange().getEnd(), diag::note_acc_previous_clause_here)
2500 << (*BindItr)->getClauseKind();
2508 auto *RAA = OpenACCRoutineAnnotAttr::CreateImplicit(
getASTContext(),
2513 while (FD != FD->getMostRecentDecl()) {
2514 FD = FD->getMostRecentDecl();
2521 RParenLoc, EndLoc, Clauses);
2525 return LastRoutineDecl;
2533 assert((!ReferencedFunc || !NextDecl) &&
2534 "Only one of these should be filled");
2537 Decl *NextLineDecl =
nullptr;
2543 return NextDecl.
get();
2547 StartLoc, DirLoc, LParenLoc, ReferencedFunc, RParenLoc, Clauses, EndLoc)};
2555 assert((!ReferencedFunc || !NextStmt) &&
2556 "Only one of these should be filled");
2559 Decl *NextLineDecl =
nullptr;
2562 NextLineDecl = DS->getSingleDecl();
2569 RParenLoc, Clauses, EndLoc)};
2573OpenACCRoutineDeclAttr *
2575 OpenACCRoutineDeclAttr *
New =
2576 OpenACCRoutineDeclAttr::Create(
getASTContext(), Old.getLocation());
2579 New->Clauses = Old.Clauses;
2593enum class InitKind {
Invalid,
Zero, One, AllOnes, Least, Largest };
2596 case InitKind::Invalid:
2597 llvm_unreachable(
"invalid init kind");
2598 case InitKind::Zero:
2599 return llvm::APFloat::getZero(Context.getFloatTypeSemantics(Ty));
2601 return llvm::APFloat::getOne(Context.getFloatTypeSemantics(Ty));
2602 case InitKind::AllOnes:
2603 return llvm::APFloat::getAllOnesValue(Context.getFloatTypeSemantics(Ty));
2604 case InitKind::Least:
2605 return llvm::APFloat::getLargest(Context.getFloatTypeSemantics(Ty),
2607 case InitKind::Largest:
2608 return llvm::APFloat::getLargest(Context.getFloatTypeSemantics(Ty));
2610 llvm_unreachable(
"unknown init kind");
2613llvm::APInt getInitIntValue(ASTContext &Context, InitKind IK, QualType Ty) {
2615 case InitKind::Invalid:
2616 llvm_unreachable(
"invalid init kind");
2617 case InitKind::Zero:
2621 case InitKind::AllOnes:
2622 return llvm::APInt::getAllOnes(Context.
getIntWidth(Ty));
2623 case InitKind::Least:
2625 return llvm::APInt::getSignedMinValue(Context.
getIntWidth(Ty));
2626 return llvm::APInt::getMinValue(Context.
getIntWidth(Ty));
2627 case InitKind::Largest:
2629 return llvm::APInt::getSignedMaxValue(Context.
getIntWidth(Ty));
2630 return llvm::APInt::getMaxValue(Context.
getIntWidth(Ty));
2632 llvm_unreachable(
"unknown init kind");
2637Expr *GenerateReductionInitRecipeExpr(ASTContext &Context,
2638 SourceRange ExprRange, QualType Ty,
2640 if (IK == InitKind::Invalid)
2643 if (IK == InitKind::Zero) {
2644 Expr *InitExpr =
new (Context)
2645 InitListExpr(Context, ExprRange.
getBegin(), {}, ExprRange.
getEnd());
2651 llvm::SmallVector<Expr *> Exprs;
2654 for (
auto *F : RD->fields()) {
2655 if (Expr *NewExpr = GenerateReductionInitRecipeExpr(Context, ExprRange,
2657 Exprs.push_back(NewExpr);
2662 for (uint64_t Idx = 0; Idx < AT->getZExtSize(); ++Idx) {
2663 if (Expr *NewExpr = GenerateReductionInitRecipeExpr(
2664 Context, ExprRange, AT->getElementType(), IK))
2665 Exprs.push_back(NewExpr);
2683 if (
const auto *Cplx = Ty->
getAs<ComplexType>()) {
2688 QualType EltTy = Cplx->getElementType();
2691 Context, getInitFloatValue(Context, InitKind::Zero, EltTy),
2692 true, EltTy, ExprRange.
getBegin()));
2694 Context, getInitFloatValue(Context, InitKind::Zero, EltTy),
2695 true, EltTy, ExprRange.
getBegin()));
2698 Context, getInitIntValue(Context, InitKind::Zero, EltTy), EltTy,
2701 Context, getInitIntValue(Context, InitKind::Zero, EltTy), EltTy,
2711 (IK == InitKind::One ||
2712 IK == InitKind::AllOnes ||
2713 IK == InitKind::Largest),
2717 Context, getInitIntValue(Context, IK, Ty), Ty, ExprRange.
getBegin()));
2721 Expr *InitExpr =
new (Context)
2722 InitListExpr(Context, ExprRange.
getBegin(), Exprs, ExprRange.
getEnd());
2727const Expr *StripOffBounds(
const Expr *VarExpr) {
2728 while (isa_and_present<ArraySectionExpr, ArraySubscriptExpr>(VarExpr)) {
2729 if (
const auto *AS = dyn_cast<ArraySectionExpr>(VarExpr))
2731 else if (
const auto *Sub = dyn_cast<ArraySubscriptExpr>(VarExpr))
2732 VarExpr =
Sub->getBase()->IgnoreParenImpCasts();
2737VarDecl *CreateAllocaDecl(ASTContext &Ctx, DeclContext *DC,
2738 SourceLocation BeginLoc, IdentifierInfo *VarName,
2744ExprResult FinishValueInit(Sema &S, InitializedEntity &Entity,
2745 SourceLocation Loc, QualType VarTy, Expr *InitExpr) {
2749 InitializationKind
Kind =
2751 InitializationSequence InitSeq(S, Entity, Kind, InitExpr,
2755 return InitSeq.Perform(S, Entity, Kind, InitExpr, &VarTy);
2770 if (
const auto *ASE =
2774 VarDecl *AllocaDecl = CreateAllocaDecl(
2776 &
getASTContext().Idents.get(
"openacc.private.init"), VarTy);
2787 if (
Init.isUsable()) {
2798 VarExpr = StripOffBounds(VarExpr);
2809 VarDecl *AllocaDecl = CreateAllocaDecl(
2811 &
getASTContext().Idents.get(
"openacc.firstprivate.init"), VarTy);
2813 VarDecl *Temporary = CreateAllocaDecl(
2841 CK_ArrayToPointerDecay, TemporaryDRE,
nullptr,
2844 for (std::size_t I = 0; I < ArrTy->getLimitedSize(); ++I) {
2867 CopySeq.
Perform(
SemaRef.SemaRef, CopyEntity, CopyKind, Subscript);
2868 Args.push_back(ElemRes.
get());
2883 VarExpr = StripOffBounds(VarExpr);
2894 VarDecl *AllocaDecl = CreateAllocaDecl(
2896 &
getASTContext().Idents.get(
"openacc.reduction.init"), VarTy);
2901 InitKind IK = InitKind::Invalid;
2902 switch (ReductionOperator) {
2907 IK = InitKind::Invalid;
2910 IK = InitKind::Least;
2913 IK = InitKind::Largest;
2916 IK = InitKind::AllOnes;
2926 IK = InitKind::Zero;
2930 Expr *InitExpr = GenerateReductionInitRecipeExpr(
This file defines OpenACC nodes for declarative directives.
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.
Defines the SourceManager interface.
This file defines OpenACC AST classes for statement-level contructs.
static OpenACCAtomicConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, OpenACCAtomicKind AtKind, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses, Stmt *AssociatedStmt)
static OpenACCCacheConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation LParenLoc, SourceLocation ReadOnlyLoc, ArrayRef< Expr * > VarList, SourceLocation RParenLoc, SourceLocation End)
static OpenACCCombinedConstruct * Create(const ASTContext &C, OpenACCDirectiveKind K, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses, Stmt *StructuredBlock)
static OpenACCDataConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses, Stmt *StructuredBlock)
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)
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)
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)
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 trap message and trap category.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
unsigned getIntWidth(QualType T) const
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
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.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
QualType getElementType() const
static CXXBoolLiteralExpr * Create(const ASTContext &C, bool Val, QualType Ty, SourceLocation Loc)
Represents a C++ conversion function within a class.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
void addDecl(Decl *D)
Add the declaration D into this context.
bool isSingleDecl() const
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl.
const Decl * getSingleDecl() const
Decl - This represents one declaration (or definition), e.g.
bool isInvalidDecl() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
The name of a declaration.
bool isIdentifier() const
Predicate functions for querying what type of name this is.
SourceLocation getBeginLoc() const LLVM_READONLY
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.
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 difference between two FPOptions values.
static FloatingLiteral * Create(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L)
Represents a function declaration or definition.
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isDeleted() const
Whether this function has been deleted.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
Describes an C or C++ initializer list.
Describes the kind of initialization being performed, along with location information for tokens rela...
static InitializationKind CreateDefault(SourceLocation InitLoc)
Create a default initialization.
static InitializationKind CreateForInit(SourceLocation Loc, bool DirectInit, Expr *Init)
Create an initialization from an initializer (which, for direct initialization from a parenthesized l...
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
Describes the sequence of initializations required to initialize a given object or reference with a s...
ExprResult Perform(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, QualType *ResultType=nullptr)
Perform the actual initialization of the given entity based on the computed initialization sequence.
Describes an entity that is being initialized.
static InitializedEntity InitializeElement(ASTContext &Context, unsigned Index, const InitializedEntity &Parent)
Create the initialization entity for an array element.
static InitializedEntity InitializeVariable(VarDecl *Var)
Create the initialization entity for a variable.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
This represents a decl that may have a name.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
A C++ nested-name-specifier augmented with source location information.
static OpaquePtr make(DeclGroupRef P)
static OpenACCAsteriskSizeExpr * Create(const ASTContext &C, SourceLocation Loc)
SourceLocation getBeginLoc() const
Represents a 'collapse' clause on a 'loop' construct.
const Expr * getLoopCount() const
static OpenACCDeclareDecl * Create(ASTContext &Ctx, DeclContext *DC, SourceLocation StartLoc, SourceLocation DirLoc, SourceLocation EndLoc, ArrayRef< const OpenACCClause * > Clauses)
static OpenACCRoutineDecl * Create(ASTContext &Ctx, DeclContext *DC, SourceLocation StartLoc, SourceLocation DirLoc, SourceLocation LParenLoc, Expr *FuncRef, SourceLocation RParenLoc, SourceLocation EndLoc, ArrayRef< const OpenACCClause * > Clauses)
const Expr * getFunctionReference() const
ArrayRef< Expr * > getSizeExprs()
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 getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Base for LValueReferenceType and RValueReferenceType.
Scope - A scope is a transient data structure that is used while parsing the program.
unsigned getDepth() const
Returns the depth of this scope. The translation-unit has scope depth 0.
bool isOpenACCLoopConstructScope() const
bool isDeclScope(const Decl *D) const
isDeclScope - Return true if this is the scope that the specified decl is declared in.
const Scope * getParent() const
getParent - Return the scope that this is nested in.
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
DeclContext * getCurContext() 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 ActOnRoutineName(Expr *RoutineName)
OpenACCPrivateRecipe CreatePrivateInitRecipe(const Expr *VarExpr)
bool ActOnStartDeclDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, ArrayRef< const OpenACCClause * > Clauses)
Called after the directive, including its clauses, have been parsed and parsing has consumed the 'ann...
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)
OpenACCReductionRecipe CreateReductionInitRecipe(OpenACCReductionOperator ReductionOperator, const Expr *VarExpr)
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 ActOnVariableDeclarator(VarDecl *VD)
Function called when a variable declarator is created, which lets us implement the 'routine' 'functio...
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)...
DeclGroupRef ActOnEndRoutineDeclDirective(SourceLocation StartLoc, SourceLocation DirLoc, SourceLocation LParenLoc, Expr *ReferencedFunc, SourceLocation RParenLoc, ArrayRef< const OpenACCClause * > Clauses, SourceLocation EndLoc, DeclGroupPtrTy NextDecl)
void ActOnInvalidParseVar()
Called only if the parse of a 'var' was invalid, else 'ActOnVar' should be called.
void CheckRoutineDecl(SourceLocation DirLoc, ArrayRef< const OpenACCClause * > Clauses, Decl *NextParsedDecl)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
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
StmtResult ActOnEndRoutineStmtDirective(SourceLocation StartLoc, SourceLocation DirLoc, SourceLocation LParenLoc, Expr *ReferencedFunc, SourceLocation RParenLoc, ArrayRef< const OpenACCClause * > Clauses, SourceLocation EndLoc, Stmt *NextStmt)
void CheckDeclReference(SourceLocation Loc, Expr *E, Decl *D)
StmtResult ActOnAssociatedStmt(SourceLocation DirectiveLoc, OpenACCDirectiveKind K, OpenACCAtomicKind AtKind, ArrayRef< const OpenACCClause * > Clauses, StmtResult AssocStmt)
Called when we encounter an associated statement for our construct, this should check legality of the...
OpenACCRoutineDeclAttr * mergeRoutineDeclAttr(const OpenACCRoutineDeclAttr &Old)
void ActOnFunctionDeclarator(FunctionDecl *FD)
Called when a function decl is created, which lets us implement the 'routine' 'doesn't match next thi...
ExprResult ActOnCacheVar(Expr *VarExpr)
Helper function called by ActonVar that is used to check a 'cache' var.
struct clang::SemaOpenACC::LoopWithoutSeqCheckingInfo LoopWithoutSeqInfo
DeclGroupRef ActOnEndDeclDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc, SourceLocation LParenLoc, SourceLocation RParenLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses)
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)...
ExprResult ActOnVar(OpenACCDirectiveKind DK, OpenACCClauseKind CK, Expr *VarExpr)
Called when encountering a 'var' for OpenACC, ensures it is actually a declaration reference to a var...
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 ActOnVariableInit(VarDecl *VD, QualType InitType)
Called when a variable is initialized, so we can implement the 'routine 'doesn't match the next thing...
void ActOnRangeForStmtBegin(SourceLocation ForLoc, const Stmt *OldRangeFor, const Stmt *RangeFor)
void ActOnStartParseVar(OpenACCDirectiveKind DK, OpenACCClauseKind CK)
Called right before a 'var' is parsed, so we can set the state for parsing a 'cache' var.
OpenACCFirstPrivateRecipe CreateFirstPrivateInitRecipe(const Expr *VarExpr)
StmtResult ActOnEndStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc, SourceLocation LParenLoc, SourceLocation MiscLoc, ArrayRef< Expr * > Exprs, OpenACCAtomicKind AK, SourceLocation RParenLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses, StmtResult AssocStmt)
Called after the directive has been completely parsed, including the declaration group or associated ...
void ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body)
StmtResult CheckAtomicAssociatedStmt(SourceLocation AtomicDirLoc, OpenACCAtomicKind AtKind, StmtResult AssocStmt)
Called to check the form of the atomic construct which has some fairly sizable restrictions.
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.
CXXMethodDecl * getMethod() const
RAII class used to indicate that we are performing provisional semantic analysis to determine the val...
Sema - This implements semantic analysis and AST building for C.
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
SourceManager & SourceMgr
SpecialMemberOverloadResult LookupSpecialMember(CXXRecordDecl *D, CXXSpecialMemberKind SM, bool ConstArg, bool VolatileArg, bool RValueThis, bool ConstThis, bool VolatileThis)
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
SourceLocation getEnd() const
SourceLocation getBegin() const
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
bool isDependentSizedArrayType() const
bool isBooleanType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isConstantArrayType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
bool isEnumeralType() const
bool isScalarType() 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 isFloatingType() const
bool isAnyPointerType() const
const T * getAs() const
Member-template getAs<specific type>'.
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.
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
void setInitStyle(InitializationStyle Style)
@ CallInit
Call-style initialization (C++98)
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)
Returns the results of matching Matcher on Node.
bool Sub(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ Invalid
Invalid Reduction Clause Kind.
bool isa(CodeGen::Address addr)
@ OK_Ordinary
An ordinary object is located at an address in memory.
OpenACCClauseKind
Represents the kind of an OpenACC clause.
@ Collapse
'collapse' clause, allowed on 'loop' and Combined constructs.
@ Private
'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...
@ Invalid
Represents an invalid clause, for the purposes of parsing.
@ UseDevice
'use_device' clause, allowed on 'host_data' construct.
@ Reduction
'reduction' clause, allowed on Parallel, Serial, Loop, and the combined constructs.
@ FirstPrivate
'firstprivate' clause, allowed on 'parallel', 'serial', 'parallel loop', and 'serial loop' constructs...
@ Tile
'tile' clause, allowed on 'loop' and Combined constructs.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Result
The result type of a method or function.
const FunctionProtoType * T
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
U cast(CodeGen::Address addr)
ActionResult< Expr * > ExprResult
ActionResult< Stmt * > StmtResult
@ NOUR_None
This is an odr-use.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
static OpenACCFirstPrivateRecipe Empty()
static OpenACCPrivateRecipe Empty()
static OpenACCReductionRecipe Empty()