24#include "llvm/ADT/StringExtras.h"
25#include "llvm/Support/Casting.h"
56 return S.
Diag(StartLoc, diag::err_acc_construct_appertainment) << K;
62void CollectActiveReductionClauses(
65 for (
auto *CurClause : CurClauses) {
66 if (
auto *RedClause = dyn_cast<OpenACCReductionClause>(CurClause);
67 RedClause && !RedClause->getVarList().empty())
68 ActiveClauses.push_back(RedClause);
98 llvm_unreachable(
"Doesn't have an associated stmt");
100 llvm_unreachable(
"Unhandled directive kind?");
102 llvm_unreachable(
"Unhandled directive kind?");
113 : SemaRef(S), OldActiveComputeConstructInfo(S.ActiveComputeConstructInfo),
118 ActiveReductionClauses(S.ActiveReductionClauses),
119 LoopRAII(SemaRef, PreserveLoopRAIIDepthInAssociatedStmtRAII(DirKind)) {
125 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
126 SemaRef.ActiveComputeConstructInfo.Kind = DirKind;
127 SemaRef.ActiveComputeConstructInfo.Clauses = Clauses;
135 SemaRef.LoopGangClauseOnKernel = {};
136 SemaRef.LoopWorkerClauseLoc = {};
137 SemaRef.LoopVectorClauseLoc = {};
138 SemaRef.LoopWithoutSeqInfo = {};
142 SemaRef.ActiveComputeConstructInfo.Kind = DirKind;
143 SemaRef.ActiveComputeConstructInfo.Clauses = Clauses;
145 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
149 SemaRef.LoopGangClauseOnKernel = {};
150 SemaRef.LoopWorkerClauseLoc = {};
151 SemaRef.LoopVectorClauseLoc = {};
155 SemaRef.LoopWithoutSeqInfo = {};
157 llvm::find_if(Clauses, llvm::IsaPred<OpenACCSeqClause>))
158 SemaRef.LoopWithoutSeqInfo = {DirKind, DirLoc};
170 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCGangClause>);
171 if (Itr != Clauses.end())
172 SemaRef.LoopGangClauseOnKernel = {(*Itr)->getBeginLoc(), DirKind};
175 if (UnInstClauses.empty()) {
176 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCWorkerClause>);
177 if (Itr != Clauses.end())
178 SemaRef.LoopWorkerClauseLoc = (*Itr)->getBeginLoc();
180 auto *Itr2 = llvm::find_if(Clauses, llvm::IsaPred<OpenACCVectorClause>);
181 if (Itr2 != Clauses.end())
182 SemaRef.LoopVectorClauseLoc = (*Itr2)->getBeginLoc();
185 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
191 SemaRef.LoopWithoutSeqInfo = {};
193 llvm::find_if(Clauses, llvm::IsaPred<OpenACCSeqClause>))
194 SemaRef.LoopWithoutSeqInfo = {DirKind, DirLoc};
204 if (SemaRef.getActiveComputeConstructInfo().Kind ==
206 UnInstClauses.empty()) {
208 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCGangClause>);
209 if (Itr != Clauses.end())
210 SemaRef.LoopGangClauseOnKernel = {(*Itr)->getBeginLoc(),
214 if (UnInstClauses.empty()) {
215 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCWorkerClause>);
216 if (Itr != Clauses.end())
217 SemaRef.LoopWorkerClauseLoc = (*Itr)->getBeginLoc();
219 auto *Itr2 = llvm::find_if(Clauses, llvm::IsaPred<OpenACCVectorClause>);
220 if (Itr2 != Clauses.end())
221 SemaRef.LoopVectorClauseLoc = (*Itr2)->getBeginLoc();
236 if (!
New->getLoopCount())
240 if (!
New->getLoopCount())
244 if (
New->getLoopCount()->isInstantiationDependent())
273 SemaRef.LoopInfo.CurLevelHasLoopAlready =
false;
274 SemaRef.CollapseInfo.CollapseDepthSatisfied =
true;
275 SemaRef.CollapseInfo.CurCollapseCount = 0;
276 SemaRef.TileInfo.TileDepthSatisfied =
true;
287 auto *UnInstClauseItr =
288 llvm::find_if(UnInstClauses, llvm::IsaPred<OpenACCCollapseClause>);
290 llvm::find_if(Clauses, llvm::IsaPred<OpenACCCollapseClause>);
299 while (ClauseItr != Clauses.end()) {
303 UnInstClauseItr == UnInstClauses.end()
308 getBestCollapseCandidate(FoundClause, CurClause, UnInstCurClause);
311 UnInstClauseItr == UnInstClauses.end()
313 : std::find_if(std::next(UnInstClauseItr), UnInstClauses.end(),
314 llvm::IsaPred<OpenACCCollapseClause>);
315 ClauseItr = std::find_if(std::next(ClauseItr), Clauses.end(),
316 llvm::IsaPred<OpenACCCollapseClause>);
322 SemaRef.CollapseInfo.ActiveCollapse = FoundClause;
323 SemaRef.CollapseInfo.CollapseDepthSatisfied =
false;
324 SemaRef.CollapseInfo.CurCollapseCount =
326 SemaRef.CollapseInfo.DirectiveKind = DirKind;
335 if (UnInstClauses.size() > 0)
337 auto *TileClauseItr =
338 llvm::find_if(Clauses, llvm::IsaPred<OpenACCTileClause>);
340 if (Clauses.end() == TileClauseItr)
347 while (Clauses.end() !=
348 (TileClauseItr = std::find_if(std::next(TileClauseItr), Clauses.end(),
349 llvm::IsaPred<OpenACCTileClause>))) {
352 TileClause = NewClause;
355 SemaRef.TileInfo.ActiveTile = TileClause;
356 SemaRef.TileInfo.TileDepthSatisfied =
false;
357 SemaRef.TileInfo.CurTileCount =
358 static_cast<unsigned>(TileClause->
getSizeExprs().size());
359 SemaRef.TileInfo.DirectiveKind = DirKind;
370 SemaRef.ActiveComputeConstructInfo = OldActiveComputeConstructInfo;
371 SemaRef.LoopGangClauseOnKernel = OldLoopGangClauseOnKernel;
372 SemaRef.LoopWorkerClauseLoc = OldLoopWorkerClauseLoc;
373 SemaRef.LoopVectorClauseLoc = OldLoopVectorClauseLoc;
374 SemaRef.LoopWithoutSeqInfo = OldLoopWithoutSeqInfo;
375 SemaRef.ActiveReductionClauses.swap(ActiveReductionClauses);
386 SemaRef.PushExpressionEvaluationContext(
403 "Only one of directive or clause kind should be provided");
412 unsigned getDiagKind()
const {
423 : ICEConvertDiagnoser(
false,
426 DirectiveKind(DK), ClauseKind(CK), IntExpr(IntExpr) {}
431 return T->isIntegerType();
435 return S.
Diag(Loc, diag::err_acc_int_expr_requires_integer)
436 << getDiagKind() << ClauseKind << DirectiveKind <<
T;
441 return S.
Diag(Loc, diag::err_acc_int_expr_incomplete_class_type)
448 return S.
Diag(Loc, diag::err_acc_int_expr_explicit_conversion)
461 return S.
Diag(Loc, diag::err_acc_int_expr_multiple_conversions) <<
T;
473 llvm_unreachable(
"conversion functions are permitted");
475 } IntExprDiagnoser(DK, CK, IntExpr);
481 Loc, IntExpr, IntExprDiagnoser);
485 IntExpr = IntExprResult.
get();
519 return Diag(VarExpr->
getExprLoc(), diag::err_acc_var_not_pointer_type)
527 CacheInfo.ParsingCacheVarList =
true;
528 CacheInfo.IsInvalidCacheRef =
false;
533 CacheInfo.ParsingCacheVarList =
false;
534 CacheInfo.IsInvalidCacheRef =
false;
544 bool WasParsingInvalidCacheRef =
545 CacheInfo.ParsingCacheVarList && CacheInfo.IsInvalidCacheRef;
546 CacheInfo.ParsingCacheVarList =
false;
547 CacheInfo.IsInvalidCacheRef =
false;
557 if (
auto *SubScrpt = dyn_cast<ArraySubscriptExpr>(CurVarExpr))
565 if (
const auto *DRE = dyn_cast<DeclRefExpr>(CurVarExpr)) {
567 DRE->getFoundDecl()->getCanonicalDecl()))
568 return WasParsingInvalidCacheRef ?
ExprEmpty() : VarExpr;
571 if (
const auto *ME = dyn_cast<MemberExpr>(CurVarExpr)) {
573 return WasParsingInvalidCacheRef ?
ExprEmpty() : VarExpr;
580 return WasParsingInvalidCacheRef ?
ExprEmpty() : VarExpr;
592 if (!
getLangOpts().OpenACC || !CacheInfo.ParsingCacheVarList || !D ||
618 Diag(Loc, diag::warn_acc_cache_var_not_outside_loop);
620 CacheInfo.IsInvalidCacheRef =
true;
653 if (!ArrTy->isConstantArrayType()) {
654 S.
Diag(InnerLoc, clang::diag::warn_acc_var_referenced_non_const_array)
659 return CheckVarType(S, CK, VarExpr, InnerLoc, ArrTy->getElementType());
670 bool HasNonDeletedDefaultCtor =
671 llvm::find_if(RD->ctors(), [](
const CXXConstructorDecl *CD) {
672 return CD->isDefaultConstructor() && !CD->isDeleted();
673 }) != RD->ctors().end();
674 if (!HasNonDeletedDefaultCtor && !RD->needsImplicitDefaultConstructor()) {
675 S.
Diag(InnerLoc, clang::diag::warn_acc_var_referenced_lacks_op)
676 << InnerTy << CK << clang::diag::AccVarReferencedReason::DefCtor;
680 if (!RD->hasSimpleCopyConstructor()) {
688 S.
Diag(InnerLoc, clang::diag::warn_acc_var_referenced_lacks_op)
689 << InnerTy << CK << clang::diag::AccVarReferencedReason::CopyCtor;
700 bool DestructorDeleted =
701 RD->getDestructor() && RD->getDestructor()->isDeleted();
702 if (DestructorDeleted && !RD->needsImplicitDestructor()) {
703 S.
Diag(InnerLoc, clang::diag::warn_acc_var_referenced_lacks_op)
704 << InnerTy << CK << clang::diag::AccVarReferencedReason::Dtor;
714 return CheckVarType(S, CK, VarExpr, InnerExpr->
getBeginLoc(),
737 diag::err_acc_not_a_var_ref_use_device_declare)
745 diag::ext_acc_array_section_use_device_declare)
752 if (
auto *SubScrpt = dyn_cast<ArraySubscriptExpr>(CurVarExpr))
760 if (
const auto *DRE = dyn_cast<DeclRefExpr>(CurVarExpr)) {
762 DRE->getFoundDecl()->getCanonicalDecl()))
763 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
772 if (
const auto *ME = dyn_cast<MemberExpr>(CurVarExpr)) {
780 const auto *
This = dyn_cast<CXXThisExpr>(ME->getBase());
782 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
784 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
793 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
800 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
808 Diag(VarExpr->
getExprLoc(), diag::err_acc_not_a_var_ref_use_device_declare)
811 Diag(VarExpr->
getExprLoc(), diag::err_acc_not_a_var_ref_use_device_declare)
827 if (
Base->hasPlaceholderType() &&
828 !
Base->hasPlaceholderType(BuiltinType::ArraySection)) {
841 LowerBound =
Result.get();
843 if (Length && Length->getType()->isNonOverloadPlaceholderType()) {
857 if (!
Base->isTypeDependent()) {
864 Diag(
Base->getExprLoc(), diag::err_acc_typecheck_subarray_value)
865 <<
Base->getSourceRange());
869 Diag(
Base->getExprLoc(), diag::err_acc_subarray_function_type)
870 << ResultTy <<
Base->getSourceRange();
874 if (
SemaRef.RequireCompleteType(
Base->getExprLoc(), ResultTy,
875 diag::err_acc_subarray_incomplete_type,
879 if (!
Base->hasPlaceholderType(BuiltinType::ArraySection)) {
890 return Recovery.
isUsable() ? Recovery.
get() :
nullptr;
900 LBRes =
SemaRef.DefaultLvalueConversion(LBRes.
get());
902 LBRes.
isUsable() ? LBRes.
get() : GetRecovery(LowerBound, Context.IntTy);
905 if (Length && !Length->isTypeDependent()) {
908 Length->getExprLoc(), Length);
911 LenRes =
SemaRef.DefaultLvalueConversion(LenRes.
get());
913 LenRes.
isUsable() ? LenRes.
get() : GetRecovery(Length, Context.IntTy);
917 if (!Length && (OriginalBaseTy.
isNull() ||
923 Diag(DiagLoc, diag::err_acc_subarray_no_length) << IsArray;
928 Length = Recovery.
isUsable() ? Recovery.
get() :
nullptr;
939 std::optional<llvm::APSInt> BaseSize;
941 const auto *ArrayTy = Context.getAsConstantArrayType(OriginalBaseTy);
942 BaseSize = ArrayTy->getSize();
945 auto GetBoundValue = [&](
Expr *E) -> std::optional<llvm::APSInt> {
955 std::optional<llvm::APSInt> LowerBoundValue = GetBoundValue(LowerBound);
956 std::optional<llvm::APSInt> LengthValue = GetBoundValue(Length);
959 if (LowerBoundValue.has_value()) {
960 if (LowerBoundValue->isNegative()) {
962 << 0 <<
toString(*LowerBoundValue, 10);
963 LowerBoundValue.reset();
964 LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
965 }
else if (BaseSize.has_value() &&
966 llvm::APSInt::compareValues(*LowerBoundValue, *BaseSize) >= 0) {
968 Diag(LowerBound->
getExprLoc(), diag::err_acc_subarray_out_of_range)
969 << 0 <<
toString(*LowerBoundValue, 10)
971 LowerBoundValue.reset();
972 LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
977 if (LengthValue.has_value()) {
978 if (LengthValue->isNegative()) {
979 Diag(Length->getExprLoc(), diag::err_acc_subarray_negative)
982 Length = GetRecovery(Length, Length->getType());
983 }
else if (BaseSize.has_value() &&
984 llvm::APSInt::compareValues(*LengthValue, *BaseSize) > 0) {
986 Diag(Length->getExprLoc(), diag::err_acc_subarray_out_of_range)
990 Length = GetRecovery(Length, Length->getType());
995 auto AddAPSInt = [](llvm::APSInt LHS, llvm::APSInt RHS) -> llvm::APSInt {
996 if (LHS.isSigned() == RHS.isSigned())
999 unsigned Width = std::max(LHS.getBitWidth(), RHS.getBitWidth()) + 1;
1000 return llvm::APSInt(LHS.sext(Width) + RHS.sext(Width),
true);
1005 if (BaseSize.has_value() && LowerBoundValue.has_value() &&
1006 LengthValue.has_value() &&
1007 llvm::APSInt::compareValues(AddAPSInt(*LowerBoundValue, *LengthValue),
1010 diag::err_acc_subarray_base_plus_length_out_of_range)
1015 LowerBoundValue.reset();
1016 LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
1017 LengthValue.reset();
1018 Length = GetRecovery(Length, Length->getType());
1022 QualType ArrayExprTy = Context.ArraySectionTy;
1023 if (
Base->isTypeDependent() ||
1025 (Length && Length->isTypeDependent()))
1026 ArrayExprTy = Context.DependentTy;
1028 return new (Context)
1037 if (!LoopInfo.TopLevelLoopSeen)
1040 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
1041 Diag(WhileLoc, diag::err_acc_invalid_in_loop)
1042 << 1 << CollapseInfo.DirectiveKind
1044 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
1045 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1046 diag::note_acc_active_clause_here)
1051 CollapseInfo.CurCollapseCount = std::nullopt;
1054 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
1055 Diag(WhileLoc, diag::err_acc_invalid_in_loop)
1056 << 1 << TileInfo.DirectiveKind
1058 assert(TileInfo.ActiveTile &&
"tile count without object?");
1059 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
1064 TileInfo.CurTileCount = std::nullopt;
1072 if (!LoopInfo.TopLevelLoopSeen)
1075 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
1076 Diag(DoLoc, diag::err_acc_invalid_in_loop)
1077 << 2 << CollapseInfo.DirectiveKind
1079 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
1080 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1081 diag::note_acc_active_clause_here)
1086 CollapseInfo.CurCollapseCount = std::nullopt;
1089 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
1090 Diag(DoLoc, diag::err_acc_invalid_in_loop)
1092 assert(TileInfo.ActiveTile &&
"tile count without object?");
1093 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
1098 TileInfo.CurTileCount = std::nullopt;
1103 ForStmtBeginChecker &
C) {
1104 assert(
getLangOpts().OpenACC &&
"Check enabled when not OpenACC?");
1107 LoopInfo.TopLevelLoopSeen =
true;
1109 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
1118 if (LoopInfo.CurLevelHasLoopAlready) {
1119 Diag(ForLoc, diag::err_acc_clause_multiple_loops)
1121 assert(CollapseInfo.ActiveCollapse &&
"No collapse object?");
1123 diag::note_acc_active_clause_here)
1126 --(*CollapseInfo.CurCollapseCount);
1130 if (*CollapseInfo.CurCollapseCount == 0)
1131 CollapseInfo.CollapseDepthSatisfied =
true;
1135 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
1139 if (LoopInfo.CurLevelHasLoopAlready) {
1140 Diag(ForLoc, diag::err_acc_clause_multiple_loops)
1142 assert(TileInfo.ActiveTile &&
"No tile object?");
1143 Diag(TileInfo.ActiveTile->getBeginLoc(),
1144 diag::note_acc_active_clause_here)
1147 TileInfo.CurTileCount = *TileInfo.CurTileCount - 1;
1150 if (*TileInfo.CurTileCount == 0)
1151 TileInfo.TileDepthSatisfied =
true;
1157 LoopInfo.CurLevelHasLoopAlready =
false;
1161bool isValidLoopVariableType(QualType LoopVarTy) {
1184 for (
const auto *TD :
1185 llvm::make_filter_range(RD->decls(), llvm::IsaPred<TypedefNameDecl>)) {
1188 if (TDND->getName() !=
"iterator_category")
1192 if (TDND->getUnderlyingType().isNull())
1195 const CXXRecordDecl *ItrCategoryDecl =
1196 TDND->getUnderlyingType()->getAsCXXRecordDecl();
1199 if (!ItrCategoryDecl)
1202 auto IsRandomAccessIteratorTag = [](
const CXXRecordDecl *RD) {
1203 if (RD->getName() !=
"random_access_iterator_tag")
1206 return RD->getEnclosingNamespaceContext()->isStdNamespace();
1209 if (IsRandomAccessIteratorTag(ItrCategoryDecl))
1214 for (CXXBaseSpecifier BS : ItrCategoryDecl->
bases())
1215 if (IsRandomAccessIteratorTag(BS.getType()->getAsCXXRecordDecl()))
1224const ValueDecl *getDeclFromExpr(
const Expr *E) {
1226 if (
const auto *FE = dyn_cast<FullExpr>(E))
1227 E = FE->getSubExpr();
1233 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
1234 return dyn_cast<ValueDecl>(DRE->getDecl());
1236 if (
const auto *ME = dyn_cast<MemberExpr>(E))
1238 return ME->getMemberDecl();
1244void SemaOpenACC::ForStmtBeginChecker::checkRangeFor() {
1245 const RangeForInfo &RFI = std::get<RangeForInfo>(Info);
1247 if (RFI.Uninstantiated == RFI.CurrentVersion)
1250 const DeclStmt *UninstRangeStmt =
1251 IsInstantiation ? RFI.Uninstantiated->getBeginStmt() :
nullptr;
1252 const DeclStmt *RangeStmt = RFI.CurrentVersion->getBeginStmt();
1256 if (UninstRangeStmt) {
1257 const ValueDecl *InitVar =
1261 if (!isValidLoopVariableType(VarType))
1271 if (!isValidLoopVariableType(VarType)) {
1273 <<
SemaRef.LoopWithoutSeqInfo.Kind << VarType;
1275 diag::note_acc_construct_here)
1276 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1281bool SemaOpenACC::ForStmtBeginChecker::checkForInit(
const Stmt *InitStmt,
1282 const ValueDecl *&InitVar,
1287 SemaRef.Diag(ForLoc, diag::err_acc_loop_variable)
1288 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1290 diag::note_acc_construct_here)
1291 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1295 auto DiagLoopVar = [
this,
Diag, InitStmt]() {
1298 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1300 diag::note_acc_construct_here)
1301 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1306 if (
const auto *ExprTemp = dyn_cast<ExprWithCleanups>(InitStmt))
1307 InitStmt = ExprTemp->getSubExpr();
1308 if (
const auto *E = dyn_cast<Expr>(InitStmt))
1312 if (
const auto *BO = dyn_cast<BinaryOperator>(InitStmt)) {
1315 if (!BO->isAssignmentOp())
1316 return DiagLoopVar();
1318 const Expr *LHS = BO->getLHS()->IgnoreParenImpCasts();
1319 if (
const auto *DRE = dyn_cast<DeclRefExpr>(LHS))
1320 InitVar = DRE->getDecl();
1321 }
else if (
const auto *DS = dyn_cast<DeclStmt>(InitStmt)) {
1323 if (!DS->isSingleDecl())
1324 return DiagLoopVar();
1325 InitVar = dyn_cast<ValueDecl>(DS->getSingleDecl());
1330 return DiagLoopVar();
1335 return DiagLoopVar();
1337 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(InitStmt)) {
1339 if (CE->getOperator() != OO_Equal)
1340 return DiagLoopVar();
1343 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
1344 InitVar = DRE->getDecl();
1345 }
else if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
1347 InitVar = ME->getMemberDecl();
1353 return DiagLoopVar();
1359 if (!isValidLoopVariableType(VarType)) {
1362 <<
SemaRef.LoopWithoutSeqInfo.Kind << VarType;
1364 diag::note_acc_construct_here)
1365 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1373bool SemaOpenACC::ForStmtBeginChecker::checkForCond(
const Stmt *CondStmt,
1374 const ValueDecl *InitVar,
1379 SemaRef.Diag(ForLoc, diag::err_acc_loop_terminating_condition)
1380 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1382 diag::note_acc_construct_here)
1383 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1388 auto DiagCondVar = [
this,
Diag, CondStmt] {
1391 diag::err_acc_loop_terminating_condition)
1392 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1394 diag::note_acc_construct_here)
1395 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1400 if (
const auto *ExprTemp = dyn_cast<ExprWithCleanups>(CondStmt))
1401 CondStmt = ExprTemp->getSubExpr();
1402 if (
const auto *E = dyn_cast<Expr>(CondStmt))
1405 const ValueDecl *CondVar =
nullptr;
1406 if (
const auto *BO = dyn_cast<BinaryOperator>(CondStmt)) {
1407 switch (BO->getOpcode()) {
1409 return DiagCondVar();
1422 CondVar = getDeclFromExpr(BO->getLHS());
1425 CondVar = getDeclFromExpr(BO->getRHS());
1427 }
else if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(CondStmt)) {
1430 if (!CE->isComparisonOp() || CE->getOperator() == OO_Spaceship)
1431 return DiagCondVar();
1435 CondVar = getDeclFromExpr(CE->getArg(0));
1439 CE->getNumArgs() > 1))
1440 CondVar = getDeclFromExpr(CE->getArg(1));
1442 return DiagCondVar();
1446 return DiagCondVar();
1451 return DiagCondVar();
1460bool isValidForIncRHSAssign(
const ValueDecl *InitVar,
const Expr *RHS) {
1462 auto isValid = [](
const ValueDecl *InitVar,
const Expr *InnerLHS,
1463 const Expr *InnerRHS,
bool IsAddition) {
1465 if (!InnerLHS->getType()->isIntegerType() &&
1466 !InnerRHS->getType()->isIntegerType())
1474 const ValueDecl *LHSDecl = getDeclFromExpr(InnerLHS);
1475 const ValueDecl *RHSDecl = getDeclFromExpr(InnerRHS);
1477 if (!LHSDecl || !RHSDecl)
1493 if (
const auto *BO = dyn_cast<BinaryOperator>(RHS)) {
1495 if (OpC != BO_Add && OpC != BO_Sub)
1497 return isValid(InitVar, BO->getLHS(), BO->getRHS(), OpC == BO_Add);
1498 }
else if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
1500 if (Op != OO_Plus && Op != OO_Minus)
1502 return isValid(InitVar, CE->getArg(0), CE->getArg(1), Op == OO_Plus);
1509bool SemaOpenACC::ForStmtBeginChecker::checkForInc(
const Stmt *IncStmt,
1510 const ValueDecl *InitVar,
1514 SemaRef.Diag(ForLoc, diag::err_acc_loop_not_monotonic)
1515 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1517 diag::note_acc_construct_here)
1518 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1522 auto DiagIncVar = [
this,
Diag, IncStmt] {
1525 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1527 diag::note_acc_construct_here)
1528 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1533 if (
const auto *ExprTemp = dyn_cast<ExprWithCleanups>(IncStmt))
1534 IncStmt = ExprTemp->getSubExpr();
1535 if (
const auto *E = dyn_cast<Expr>(IncStmt))
1538 const ValueDecl *IncVar =
nullptr;
1540 if (
const auto *UO = dyn_cast<UnaryOperator>(IncStmt)) {
1542 if (!UO->isIncrementDecrementOp())
1543 return DiagIncVar();
1544 IncVar = getDeclFromExpr(UO->getSubExpr());
1545 }
else if (
const auto *BO = dyn_cast<BinaryOperator>(IncStmt)) {
1546 switch (BO->getOpcode()) {
1548 return DiagIncVar();
1555 if (!isValidForIncRHSAssign(InitVar, BO->getRHS()))
1556 return DiagIncVar();
1559 IncVar = getDeclFromExpr(BO->getLHS());
1560 }
else if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(IncStmt)) {
1561 switch (CE->getOperator()) {
1563 return DiagIncVar();
1572 if (!isValidForIncRHSAssign(InitVar, CE->getArg(1)))
1573 return DiagIncVar();
1577 IncVar = getDeclFromExpr(CE->getArg(0));
1579 return DiagIncVar();
1583 return DiagIncVar();
1589 return DiagIncVar();
1594void SemaOpenACC::ForStmtBeginChecker::checkFor() {
1595 const CheckForInfo &CFI = std::get<CheckForInfo>(Info);
1597 if (!IsInstantiation) {
1600 const ValueDecl *CurInitVar =
nullptr;
1601 checkForInit(CFI.Current.Init, CurInitVar,
true);
1602 checkForCond(CFI.Current.Condition, CurInitVar,
true);
1603 checkForInc(CFI.Current.Increment, CurInitVar,
true);
1605 const ValueDecl *UninstInitVar =
nullptr;
1609 bool UninstInitFailed =
1610 checkForInit(CFI.Uninst.Init, UninstInitVar,
false);
1616 auto InitChanged = [=]() {
1617 if (CFI.Uninst.Init == CFI.Current.Init)
1623 if (
const auto *DS = dyn_cast<DeclStmt>(CFI.Uninst.Init))
1624 if (
const VarDecl *VD = dyn_cast_if_present<VarDecl>(
1625 DS->isSingleDecl() ? DS->getSingleDecl() :
nullptr))
1626 OldVDTy = VD->getType();
1627 if (
const auto *DS = dyn_cast<DeclStmt>(CFI.Current.Init))
1628 if (
const VarDecl *VD = dyn_cast_if_present<VarDecl>(
1629 DS->isSingleDecl() ? DS->getSingleDecl() :
nullptr))
1630 NewVDTy = VD->getType();
1641 bool ShouldDiagNewInit = !UninstInitFailed && InitChanged();
1642 const ValueDecl *CurInitVar =
nullptr;
1643 checkForInit(CFI.Current.Init, CurInitVar, ShouldDiagNewInit);
1647 if (CFI.Uninst.Condition != CFI.Current.Condition &&
1648 !checkForCond(CFI.Uninst.Condition, UninstInitVar,
false))
1649 checkForCond(CFI.Current.Condition, CurInitVar,
true);
1650 if (CFI.Uninst.Increment != CFI.Current.Increment &&
1651 !checkForInc(CFI.Uninst.Increment, UninstInitVar,
false))
1652 checkForInc(CFI.Current.Increment, CurInitVar,
true);
1656void SemaOpenACC::ForStmtBeginChecker::check() {
1667 AlreadyChecked =
true;
1684 if (std::holds_alternative<RangeForInfo>(Info))
1685 return checkRangeFor();
1692 const Stmt *Second,
const Stmt *OldThird,
1693 const Stmt *Third) {
1697 ForStmtBeginChecker FSBC{*
this, ForLoc, OldFirst, OldSecond,
1698 OldThird,
First, Second, Third};
1701 if (!LoopInfo.TopLevelLoopSeen) {
1705 ForStmtBeginHelper(ForLoc, FSBC);
1709 const Stmt *Second,
const Stmt *Third) {
1713 ForStmtBeginChecker FSBC{*
this, ForLoc,
First, Second, Third};
1717 if (!LoopInfo.TopLevelLoopSeen)
1720 ForStmtBeginHelper(ForLoc, FSBC);
1724 const Stmt *OldRangeFor,
1725 const Stmt *RangeFor) {
1726 if (!
getLangOpts().OpenACC || OldRangeFor ==
nullptr || RangeFor ==
nullptr)
1729 ForStmtBeginChecker FSBC{*
this, ForLoc,
1730 cast_if_present<CXXForRangeStmt>(OldRangeFor),
1731 cast_if_present<CXXForRangeStmt>(RangeFor)};
1734 if (!LoopInfo.TopLevelLoopSeen) {
1737 ForStmtBeginHelper(ForLoc, FSBC);
1741 const Stmt *RangeFor) {
1742 if (!
getLangOpts().OpenACC || RangeFor ==
nullptr)
1745 ForStmtBeginChecker FSBC = {*
this, ForLoc,
1746 cast_if_present<CXXForRangeStmt>(RangeFor)};
1750 if (!LoopInfo.TopLevelLoopSeen)
1753 ForStmtBeginHelper(ForLoc, FSBC);
1773 if (
const auto *CS = dyn_cast<CompoundStmt>(CurStmt)) {
1774 for (
const auto *ChildStmt : CS->children()) {
1775 SourceLocation ChildStmtLoc = FindInterveningCodeInLoop(ChildStmt);
1777 return ChildStmtLoc;
1780 return SourceLocation{};
1791 LoopInfo.CurLevelHasLoopAlready =
true;
1796 bool IsActiveCollapse = CollapseInfo.CurCollapseCount &&
1797 *CollapseInfo.CurCollapseCount > 0 &&
1798 !CollapseInfo.ActiveCollapse->hasForce();
1799 bool IsActiveTile = TileInfo.CurTileCount && *TileInfo.CurTileCount > 0;
1801 if (IsActiveCollapse || IsActiveTile) {
1804 if (OtherStmtLoc.
isValid() && IsActiveCollapse) {
1805 Diag(OtherStmtLoc, diag::err_acc_intervening_code)
1807 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1808 diag::note_acc_active_clause_here)
1812 if (OtherStmtLoc.
isValid() && IsActiveTile) {
1813 Diag(OtherStmtLoc, diag::err_acc_intervening_code)
1815 Diag(TileInfo.ActiveTile->getBeginLoc(),
1816 diag::note_acc_active_clause_here)
1836 }
else if (
auto *DRE = dyn_cast<DeclRefExpr>(RoutineName)) {
1837 ValueDecl *VD = DRE->getDecl();
1839 if (
auto *FD = dyn_cast<FunctionDecl>(VD))
1843 if (
auto *VarD = dyn_cast<VarDecl>(VD)) {
1844 QualType VarDTy = VarD->getType();
1847 if (RD->isGenericLambda())
1850 return RD->getLambdaCallOperator();
1866 assert(RoutineName &&
"Routine name cannot be null here");
1877 }
else if (
const auto *DRE = dyn_cast<DeclRefExpr>(RoutineName)) {
1884 if (
const auto *VarD = dyn_cast<VarDecl>(VD)) {
1888 if (RD->isGenericLambda()) {
1928 auto *ContextDecl = dyn_cast<FunctionDecl>(
getCurContext());
1936 for (
const auto *A : ContextDecl->attrs()) {
1939 Diag(A->getLocation(), diag::note_acc_construct_here)
1945 MagicStaticLocs.insert({ContextDecl->getCanonicalDecl(), VD->
getBeginLoc()});
1947void SemaOpenACC::CheckLastRoutineDeclNameConflict(
const NamedDecl *ND) {
1956 if (!LastRoutineDecl)
1989 if (NDLine - LastLine > 1)
1997 diag::warn_acc_confusing_routine_name);
2013 if (!RD || !RD->isLambda())
2016 CheckLastRoutineDeclNameConflict(VD);
2022 CheckLastRoutineDeclNameConflict(FD);
2034 SemaRef.DiscardCleanupsInEvaluationContext();
2035 SemaRef.PopExpressionEvaluationContext();
2042 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
2043 Diag(StartLoc, diag::err_acc_invalid_in_loop)
2044 << 0 << CollapseInfo.DirectiveKind
2046 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
2047 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
2048 diag::note_acc_active_clause_here)
2051 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
2052 Diag(StartLoc, diag::err_acc_invalid_in_loop)
2053 << 0 << TileInfo.DirectiveKind
2055 assert(TileInfo.ActiveTile &&
"Tile count without object?");
2056 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
2060 if (DiagnoseRequiredClauses(K, StartLoc, Clauses))
2062 return diagnoseConstructAppertainment(*
this, K, StartLoc,
true);
2077 return OpenACCComputeConstruct::Create(
2079 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2086 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2090 getASTContext(), ActiveComputeConstructInfo.Kind, StartLoc, DirLoc,
2091 EndLoc, Clauses, AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2096 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2109 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2113 getASTContext(), StartLoc, DirLoc, LParenLoc, Exprs.front(), MiscLoc,
2114 Exprs.drop_front(), RParenLoc, EndLoc, Clauses);
2134 getASTContext(), StartLoc, DirLoc, AtomicKind, EndLoc, Clauses,
2135 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2138 assert(Clauses.empty() &&
"Cache doesn't allow clauses");
2140 LParenLoc, MiscLoc, Exprs, RParenLoc,
2144 llvm_unreachable(
"routine shouldn't handled here");
2149 RParenLoc, EndLoc, Clauses);
2154 llvm_unreachable(
"Unhandled case in directive handling?");
2163 llvm_unreachable(
"Unimplemented associated statement application");
2172 "these don't have associated statements, so shouldn't get here");
2200 Diag(DirectiveLoc, diag::note_acc_construct_here) << K;
2204 if (!CollapseInfo.CollapseDepthSatisfied || !TileInfo.TileDepthSatisfied) {
2205 if (!CollapseInfo.CollapseDepthSatisfied) {
2206 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
2208 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
2209 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
2210 diag::note_acc_active_clause_here)
2214 if (!TileInfo.TileDepthSatisfied) {
2215 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
2217 assert(TileInfo.ActiveTile &&
"Collapse count without object?");
2218 Diag(TileInfo.ActiveTile->getBeginLoc(),
2219 diag::note_acc_active_clause_here)
2225 return AssocStmt.
get();
2227 llvm_unreachable(
"Invalid associated statement application");
2235bool CheckValidRoutineGangWorkerVectorSeqClauses(
2247 auto *FirstDeviceType =
2248 llvm::find_if(Clauses, llvm::IsaPred<OpenACCDeviceTypeClause>);
2253 std::find_if(Clauses.begin(), FirstDeviceType, RequiredPred);
2255 if (ClauseItr != FirstDeviceType)
2259 if (FirstDeviceType == Clauses.end())
2260 return SemaRef.
Diag(DirectiveLoc, diag::err_acc_construct_one_clause_of)
2262 <<
"'gang', 'seq', 'vector', or 'worker'";
2266 auto *PrevDeviceType = FirstDeviceType;
2268 while (PrevDeviceType != Clauses.end()) {
2269 auto *NextDeviceType =
2270 std::find_if(std::next(PrevDeviceType), Clauses.end(),
2271 llvm::IsaPred<OpenACCDeviceTypeClause>);
2273 ClauseItr = std::find_if(PrevDeviceType, NextDeviceType, RequiredPred);
2275 if (ClauseItr == NextDeviceType)
2276 return SemaRef.
Diag((*PrevDeviceType)->getBeginLoc(),
2277 diag::err_acc_clause_routine_one_of_in_region);
2279 PrevDeviceType = NextDeviceType;
2292 SemaRef.DiscardCleanupsInEvaluationContext();
2293 SemaRef.PopExpressionEvaluationContext();
2295 if (DiagnoseRequiredClauses(K, StartLoc, Clauses))
2298 CheckValidRoutineGangWorkerVectorSeqClauses(*
this, StartLoc, Clauses))
2301 return diagnoseConstructAppertainment(*
this, K, StartLoc,
false);
2314 if (Clauses.empty()) {
2315 Diag(EndLoc, diag::err_acc_declare_required_clauses);
2329 llvm_unreachable(
"routine shouldn't be handled here");
2331 llvm_unreachable(
"unhandled case in directive handling?");
2342 if (
auto *FD = dyn_cast<FunctionDecl>(D))
2346 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
2347 return FTD->getTemplatedDecl();
2349 if (
auto *FD = dyn_cast<FieldDecl>(D)) {
2351 FD->getType().isNull() ?
nullptr : FD->getType()->getAsCXXRecordDecl();
2353 if (RD && RD->isGenericLambda())
2354 return RD->getDependentLambdaCallOperator()->getTemplatedDecl();
2355 if (RD && RD->isLambda())
2356 return RD->getLambdaCallOperator();
2360 if (
auto *VD = dyn_cast<VarDecl>(D)) {
2362 if (!
Init ||
Init->getType().isNull())
2365 const auto *RD =
Init->getType()->getAsCXXRecordDecl();
2366 if (RD && RD->isGenericLambda())
2367 return RD->getDependentLambdaCallOperator()->getTemplatedDecl();
2368 if (RD && RD->isLambda())
2369 return RD->getLambdaCallOperator();
2384 ArrayRef<const OpenACCClause *> Clauses,
2386 OpenACCRoutineDeclAttr *A =
2387 OpenACCRoutineDeclAttr::Create(
SemaRef.getASTContext(), DirLoc);
2388 A->Clauses.assign(Clauses.begin(), Clauses.end());
2396 Decl *NextParsedDecl) {
2398 FunctionDecl *NextParsedFDecl = LegalizeNextParsedDecl(NextParsedDecl);
2400 if (!NextParsedFDecl) {
2402 SemaRef.Diag(DirLoc, diag::err_acc_decl_for_routine);
2410 Itr != MagicStaticLocs.end()) {
2411 Diag(Itr->second, diag::err_acc_magic_static_in_routine);
2412 Diag(DirLoc, diag::note_acc_construct_here)
2418 auto BindItr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCBindClause>);
2419 for (
auto *A : NextParsedFDecl->
attrs()) {
2423 if (
auto *RA = dyn_cast<OpenACCRoutineDeclAttr>(A)) {
2425 llvm::find_if(RA->Clauses, llvm::IsaPred<OpenACCBindClause>);
2426 if (OtherBindItr != RA->Clauses.end() &&
2429 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_unnamed_bind);
2430 Diag((*OtherBindItr)->getEndLoc(), diag::note_acc_previous_clause_here)
2431 << (*BindItr)->getClauseKind();
2442 if (
auto *RA = dyn_cast<OpenACCRoutineAnnotAttr>(A);
2443 RA && RA->getRange().getEnd().isValid()) {
2444 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
2445 Diag(RA->getRange().getEnd(), diag::note_acc_previous_clause_here)
2451 CreateRoutineDeclAttr(*
this, DirLoc, Clauses, NextParsedFDecl);
2462 if ((FD = getFunctionFromRoutineName(FuncRef))) {
2467 Itr != MagicStaticLocs.end()) {
2468 Diag(Itr->second, diag::err_acc_magic_static_in_routine);
2469 Diag(DirLoc, diag::note_acc_construct_here)
2478 auto BindItr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCBindClause>);
2480 if (BindItr != Clauses.end()) {
2481 BindLoc = (*BindItr)->getBeginLoc();
2485 for (
auto *A : FD->
attrs()) {
2486 if (
auto *RA = dyn_cast<OpenACCRoutineDeclAttr>(A)) {
2488 llvm::find_if(RA->Clauses, llvm::IsaPred<OpenACCBindClause>);
2489 if (OtherBindItr != RA->Clauses.end()) {
2490 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
2491 Diag((*OtherBindItr)->getEndLoc(),
2492 diag::note_acc_previous_clause_here)
2493 << (*BindItr)->getClauseKind();
2498 if (
auto *RA = dyn_cast<OpenACCRoutineAnnotAttr>(A);
2499 RA && RA->getRange().getEnd().isValid()) {
2500 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
2501 Diag(RA->getRange().getEnd(), diag::note_acc_previous_clause_here)
2502 << (*BindItr)->getClauseKind();
2510 auto *RAA = OpenACCRoutineAnnotAttr::CreateImplicit(
getASTContext(),
2515 for (
auto *CurFD : FD->
redecls())
2521 RParenLoc, EndLoc, Clauses);
2529 RoutineRefList.emplace_back(FD, LastRoutineDecl);
2531 return LastRoutineDecl;
2535 for (
auto [FD, RoutineDecl] : RoutineRefList)
2536 SemaRef.Consumer.HandleOpenACCRoutineReference(FD, RoutineDecl);
2544 assert((!ReferencedFunc || !NextDecl) &&
2545 "Only one of these should be filled");
2548 Decl *NextLineDecl =
nullptr;
2554 return NextDecl.
get();
2558 StartLoc, DirLoc, LParenLoc, ReferencedFunc, RParenLoc, Clauses, EndLoc)};
2566 assert((!ReferencedFunc || !NextStmt) &&
2567 "Only one of these should be filled");
2570 Decl *NextLineDecl =
nullptr;
2573 NextLineDecl = DS->getSingleDecl();
2580 RParenLoc, Clauses, EndLoc)};
2584OpenACCRoutineDeclAttr *
2586 OpenACCRoutineDeclAttr *
New =
2587 OpenACCRoutineDeclAttr::Create(
getASTContext(), Old.getLocation());
2590 New->Clauses = Old.Clauses;
2604enum class InitKind {
Invalid,
Zero, One, AllOnes, Least, Largest };
2607 case InitKind::Invalid:
2608 llvm_unreachable(
"invalid init kind");
2609 case InitKind::Zero:
2610 return llvm::APFloat::getZero(Context.getFloatTypeSemantics(Ty));
2612 return llvm::APFloat::getOne(Context.getFloatTypeSemantics(Ty));
2613 case InitKind::AllOnes:
2614 return llvm::APFloat::getAllOnesValue(Context.getFloatTypeSemantics(Ty));
2615 case InitKind::Least:
2616 return llvm::APFloat::getLargest(Context.getFloatTypeSemantics(Ty),
2618 case InitKind::Largest:
2619 return llvm::APFloat::getLargest(Context.getFloatTypeSemantics(Ty));
2621 llvm_unreachable(
"unknown init kind");
2624llvm::APInt getInitIntValue(ASTContext &Context, InitKind IK, QualType Ty) {
2626 case InitKind::Invalid:
2627 llvm_unreachable(
"invalid init kind");
2628 case InitKind::Zero:
2632 case InitKind::AllOnes:
2633 return llvm::APInt::getAllOnes(Context.
getIntWidth(Ty));
2634 case InitKind::Least:
2636 return llvm::APInt::getSignedMinValue(Context.
getIntWidth(Ty));
2637 return llvm::APInt::getMinValue(Context.
getIntWidth(Ty));
2638 case InitKind::Largest:
2640 return llvm::APInt::getSignedMaxValue(Context.
getIntWidth(Ty));
2641 return llvm::APInt::getMaxValue(Context.
getIntWidth(Ty));
2643 llvm_unreachable(
"unknown init kind");
2648Expr *GenerateReductionInitRecipeExpr(ASTContext &Context,
2649 SourceRange ExprRange, QualType Ty,
2651 if (IK == InitKind::Invalid)
2654 if (IK == InitKind::Zero) {
2655 Expr *InitExpr =
new (Context)
2656 InitListExpr(Context, ExprRange.
getBegin(), {}, ExprRange.
getEnd());
2662 llvm::SmallVector<Expr *> Exprs;
2665 for (
auto *F : RD->fields()) {
2666 if (Expr *NewExpr = GenerateReductionInitRecipeExpr(Context, ExprRange,
2668 Exprs.push_back(NewExpr);
2673 for (uint64_t Idx = 0; Idx < AT->getZExtSize(); ++Idx) {
2674 if (Expr *NewExpr = GenerateReductionInitRecipeExpr(
2675 Context, ExprRange, AT->getElementType(), IK))
2676 Exprs.push_back(NewExpr);
2694 if (
const auto *Cplx = Ty->
getAs<ComplexType>()) {
2699 QualType EltTy = Cplx->getElementType();
2702 Context, getInitFloatValue(Context, InitKind::Zero, EltTy),
2703 true, EltTy, ExprRange.
getBegin()));
2705 Context, getInitFloatValue(Context, InitKind::Zero, EltTy),
2706 true, EltTy, ExprRange.
getBegin()));
2709 Context, getInitIntValue(Context, InitKind::Zero, EltTy), EltTy,
2712 Context, getInitIntValue(Context, InitKind::Zero, EltTy), EltTy,
2722 (IK == InitKind::One ||
2723 IK == InitKind::AllOnes ||
2724 IK == InitKind::Largest),
2728 Context, getInitIntValue(Context, IK, Ty), Ty, ExprRange.
getBegin()));
2732 Expr *InitExpr =
new (Context)
2733 InitListExpr(Context, ExprRange.
getBegin(), Exprs, ExprRange.
getEnd());
2738VarDecl *CreateAllocaDecl(ASTContext &Ctx, DeclContext *DC,
2739 SourceLocation BeginLoc, IdentifierInfo *VarName,
2745ExprResult FinishValueInit(Sema &S, InitializedEntity &Entity,
2746 SourceLocation Loc, QualType VarTy, Expr *InitExpr) {
2750 InitializationKind
Kind =
2752 InitializationSequence InitSeq(S, Entity, Kind, InitExpr,
2756 return InitSeq.Perform(S, Entity, Kind, InitExpr, &VarTy);
2771 if (
const auto *ASE =
2773 VarTy = ASE->getElementType();
2775 VarDecl *AllocaDecl = CreateAllocaDecl(
2777 &
getASTContext().Idents.get(
"openacc.private.init"), VarTy);
2788 if (
Init.isUsable()) {
2807 if (
const auto *ASE =
2809 VarTy = ASE->getElementType();
2811 VarDecl *AllocaDecl = CreateAllocaDecl(
2813 &
getASTContext().Idents.get(
"openacc.firstprivate.init"), VarTy);
2815 VarDecl *Temporary = CreateAllocaDecl(
2836 if (
Init.isUsable()) {
2850 CK_ArrayToPointerDecay, TemporaryDRE,
nullptr,
2853 for (std::size_t I = 0; I < ArrTy->getLimitedSize(); ++I) {
2876 CopySeq.
Perform(
SemaRef.SemaRef, CopyEntity, CopyKind, Subscript);
2877 Args.push_back(ElemRes.
get());
2889 if (
Init.isUsable()) {
2908 if (
const auto *ASE =
2910 VarTy = ASE->getElementType();
2917 if (CreateReductionCombinerRecipe(VarExpr->
getBeginLoc(), ReductionOperator,
2918 VarTy, CombinerRecipes))
2921 VarDecl *AllocaDecl = CreateAllocaDecl(
2923 &
getASTContext().Idents.get(
"openacc.reduction.init"), VarTy);
2928 InitKind IK = InitKind::Invalid;
2929 switch (ReductionOperator) {
2934 IK = InitKind::Invalid;
2937 IK = InitKind::Least;
2940 IK = InitKind::Largest;
2943 IK = InitKind::AllOnes;
2953 IK = InitKind::Zero;
2957 Expr *InitExpr = GenerateReductionInitRecipeExpr(
2965 if (
Init.isUsable()) {
2973bool SemaOpenACC::CreateReductionCombinerRecipe(
2985 switch (ReductionOperator) {
2990 CombinerRecipes.push_back({
nullptr,
nullptr,
nullptr});
2993 BinOp = BinaryOperatorKind::BO_AddAssign;
2996 BinOp = BinaryOperatorKind::BO_MulAssign;
2999 BinOp = BinaryOperatorKind::BO_AndAssign;
3002 BinOp = BinaryOperatorKind::BO_OrAssign;
3005 BinOp = BinaryOperatorKind::BO_XorAssign;
3010 BinOp = BinaryOperatorKind::BO_LT;
3013 BinOp = BinaryOperatorKind::BO_LAnd;
3016 BinOp = BinaryOperatorKind::BO_LOr;
3023 VarTy = AT->getElementType();
3025 assert(!VarTy->
isArrayType() &&
"Only 1 level of array allowed");
3027 enum class CombinerFailureKind {
3034 auto genCombiner = [&,
this](DeclRefExpr *LHSDRE, DeclRefExpr *RHSDRE)
3035 -> std::pair<ExprResult, CombinerFailureKind> {
3037 SemaRef.BuildBinOp(
SemaRef.getCurScope(), Loc, BinOp, LHSDRE, RHSDRE,
3039 switch (ReductionOperator) {
3047 return {BinOpRes, BinOpRes.
isUsable() ? CombinerFailureKind::None
3048 : CombinerFailureKind::BinOp};
3057 return {BinOpRes, CombinerFailureKind::BinOp};
3063 CondRes =
SemaRef.ActOnConditionalOp(Loc, Loc, BinOpRes.
get(), LHSDRE,
3066 CondRes =
SemaRef.ActOnConditionalOp(Loc, Loc, BinOpRes.
get(), RHSDRE,
3070 return {CondRes, CombinerFailureKind::Conditional};
3074 BinaryOperatorKind::BO_Assign,
3075 LHSDRE, CondRes.
get(),
3078 ? CombinerFailureKind::None
3079 : CombinerFailureKind::Assignment};
3086 return {BinOpRes, CombinerFailureKind::BinOp};
3090 BinaryOperatorKind::BO_Assign,
3091 LHSDRE, BinOpRes.
get(),
3094 ? CombinerFailureKind::None
3095 : CombinerFailureKind::Assignment};
3098 llvm_unreachable(
"Invalid should have been caught above");
3100 llvm_unreachable(
"Unhandled case");
3103 auto tryCombiner = [&,
this](DeclRefExpr *LHSDRE, DeclRefExpr *RHSDRE,
3107 Sema::TentativeAnalysisScope Trap{
SemaRef};
3108 return genCombiner(LHSDRE, RHSDRE);
3110 return genCombiner(LHSDRE, RHSDRE);
3113 struct CombinerAttemptTy {
3114 CombinerFailureKind FailKind;
3116 DeclRefExpr *LHSDRE;
3118 DeclRefExpr *RHSDRE;
3122 auto formCombiner = [&,
this](QualType Ty) -> CombinerAttemptTy {
3123 VarDecl *LHSDecl = CreateAllocaDecl(
3125 &
getASTContext().Idents.get(
"openacc.reduction.combiner.lhs"), Ty);
3127 getASTContext(), NestedNameSpecifierLoc{}, SourceLocation{}, LHSDecl,
3129 DeclarationNameInfo{DeclarationName{LHSDecl->
getDeclName()},
3132 VarDecl *RHSDecl = CreateAllocaDecl(
3134 &
getASTContext().Idents.get(
"openacc.reduction.combiner.lhs"), Ty);
3136 getASTContext(), NestedNameSpecifierLoc{}, SourceLocation{}, RHSDecl,
3138 DeclarationNameInfo{DeclarationName{RHSDecl->getDeclName()},
3139 RHSDecl->getBeginLoc()},
3142 std::pair<ExprResult, CombinerFailureKind> BinOpResult =
3143 tryCombiner(LHSDRE, RHSDRE,
true);
3145 return {BinOpResult.second, LHSDecl, LHSDRE, RHSDecl, RHSDRE,
3146 BinOpResult.first.get()};
3149 CombinerAttemptTy TopLevelCombinerInfo = formCombiner(VarTy);
3151 if (TopLevelCombinerInfo.Op) {
3152 if (!TopLevelCombinerInfo.Op->containsErrors() &&
3153 TopLevelCombinerInfo.Op->isInstantiationDependent()) {
3156 CombinerRecipes.push_back({
nullptr,
nullptr,
nullptr});
3158 }
else if (!TopLevelCombinerInfo.Op->containsErrors()) {
3160 CombinerRecipes.push_back({TopLevelCombinerInfo.LHS,
3161 TopLevelCombinerInfo.RHS,
3162 TopLevelCombinerInfo.Op});
3167 auto EmitFailureNote = [&](CombinerFailureKind CFK) {
3168 if (CFK == CombinerFailureKind::BinOp)
3169 return Diag(Loc, diag::note_acc_reduction_combiner_forming)
3171 return Diag(Loc, diag::note_acc_reduction_combiner_forming) << CFK;
3179 Diag(Loc, diag::err_acc_reduction_recipe_no_op) << VarTy;
3180 EmitFailureNote(TopLevelCombinerInfo.FailKind);
3181 tryCombiner(TopLevelCombinerInfo.LHSDRE, TopLevelCombinerInfo.RHSDRE,
3186 for (
const FieldDecl *FD : RD->
fields()) {
3187 CombinerAttemptTy FieldCombinerInfo = formCombiner(FD->getType());
3189 if (!FieldCombinerInfo.Op || FieldCombinerInfo.Op->containsErrors()) {
3190 Diag(Loc, diag::err_acc_reduction_recipe_no_op) << FD->getType();
3191 Diag(FD->getBeginLoc(), diag::note_acc_reduction_recipe_noop_field) << RD;
3192 EmitFailureNote(FieldCombinerInfo.FailKind);
3193 tryCombiner(FieldCombinerInfo.LHSDRE, FieldCombinerInfo.RHSDRE,
3198 if (FieldCombinerInfo.Op->isInstantiationDependent()) {
3201 CombinerRecipes.push_back({
nullptr,
nullptr,
nullptr});
3203 CombinerRecipes.push_back(
3204 {FieldCombinerInfo.LHS, FieldCombinerInfo.RHS, FieldCombinerInfo.Op});
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
StringRef getOpcodeStr() 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.
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
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.
field_range fields() const
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.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
DeclContext * getCurContext() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
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)
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)
void ActOnEndOfTranslationUnit(TranslationUnitDecl *TU)
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.
OpenACCReductionRecipeWithStorage CreateReductionInitRecipe(OpenACCReductionOperator ReductionOperator, const Expr *VarExpr)
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
The top declaration context.
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.
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)
@ Conditional
A conditional (?:) operator.
@ 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)
@ None
The alignment was not explicit in code.
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 OpenACCReductionRecipeWithStorage Empty()