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());
664 diag::err_incomplete_type))
675 bool HasNonDeletedDefaultCtor =
676 llvm::find_if(RD->ctors(), [](
const CXXConstructorDecl *CD) {
677 return CD->isDefaultConstructor() && !CD->isDeleted();
678 }) != RD->ctors().end();
679 if (!HasNonDeletedDefaultCtor && !RD->needsImplicitDefaultConstructor()) {
680 S.
Diag(InnerLoc, clang::diag::warn_acc_var_referenced_lacks_op)
681 << InnerTy << CK << clang::diag::AccVarReferencedReason::DefCtor;
685 if (!RD->hasSimpleCopyConstructor()) {
693 S.
Diag(InnerLoc, clang::diag::warn_acc_var_referenced_lacks_op)
694 << InnerTy << CK << clang::diag::AccVarReferencedReason::CopyCtor;
705 bool DestructorDeleted =
706 RD->getDestructor() && RD->getDestructor()->isDeleted();
707 if (DestructorDeleted && !RD->needsImplicitDestructor()) {
708 S.
Diag(InnerLoc, clang::diag::warn_acc_var_referenced_lacks_op)
709 << InnerTy << CK << clang::diag::AccVarReferencedReason::Dtor;
719 return CheckVarType(S, CK, VarExpr, InnerExpr->
getBeginLoc(),
742 diag::err_acc_not_a_var_ref_use_device_declare)
750 diag::ext_acc_array_section_use_device_declare)
757 if (
auto *SubScrpt = dyn_cast<ArraySubscriptExpr>(CurVarExpr))
765 if (
const auto *DRE = dyn_cast<DeclRefExpr>(CurVarExpr)) {
767 DRE->getFoundDecl()->getCanonicalDecl()))
768 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
777 if (
const auto *ME = dyn_cast<MemberExpr>(CurVarExpr)) {
785 const auto *
This = dyn_cast<CXXThisExpr>(ME->getBase());
787 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
789 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
798 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
805 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
813 Diag(VarExpr->
getExprLoc(), diag::err_acc_not_a_var_ref_use_device_declare)
816 Diag(VarExpr->
getExprLoc(), diag::err_acc_not_a_var_ref_use_device_declare)
832 if (
Base->hasPlaceholderType() &&
833 !
Base->hasPlaceholderType(BuiltinType::ArraySection)) {
846 LowerBound =
Result.get();
848 if (Length && Length->getType()->isNonOverloadPlaceholderType()) {
862 if (!
Base->isTypeDependent()) {
869 Diag(
Base->getExprLoc(), diag::err_acc_typecheck_subarray_value)
870 <<
Base->getSourceRange());
874 Diag(
Base->getExprLoc(), diag::err_acc_subarray_function_type)
875 << ResultTy <<
Base->getSourceRange();
879 if (
SemaRef.RequireCompleteType(
Base->getExprLoc(), ResultTy,
880 diag::err_acc_subarray_incomplete_type,
884 if (!
Base->hasPlaceholderType(BuiltinType::ArraySection)) {
895 return Recovery.
isUsable() ? Recovery.
get() :
nullptr;
905 LBRes =
SemaRef.DefaultLvalueConversion(LBRes.
get());
907 LBRes.
isUsable() ? LBRes.
get() : GetRecovery(LowerBound, Context.IntTy);
910 if (Length && !Length->isTypeDependent()) {
913 Length->getExprLoc(), Length);
916 LenRes =
SemaRef.DefaultLvalueConversion(LenRes.
get());
918 LenRes.
isUsable() ? LenRes.
get() : GetRecovery(Length, Context.IntTy);
922 if (!Length && (OriginalBaseTy.
isNull() ||
928 Diag(DiagLoc, diag::err_acc_subarray_no_length) << IsArray;
933 Length = Recovery.
isUsable() ? Recovery.
get() :
nullptr;
944 std::optional<llvm::APSInt> BaseSize;
946 const auto *ArrayTy = Context.getAsConstantArrayType(OriginalBaseTy);
947 BaseSize = ArrayTy->getSize();
950 auto GetBoundValue = [&](
Expr *E) -> std::optional<llvm::APSInt> {
960 std::optional<llvm::APSInt> LowerBoundValue = GetBoundValue(LowerBound);
961 std::optional<llvm::APSInt> LengthValue = GetBoundValue(Length);
964 if (LowerBoundValue.has_value()) {
965 if (LowerBoundValue->isNegative()) {
967 << 0 <<
toString(*LowerBoundValue, 10);
968 LowerBoundValue.reset();
969 LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
970 }
else if (BaseSize.has_value() &&
971 llvm::APSInt::compareValues(*LowerBoundValue, *BaseSize) >= 0) {
973 Diag(LowerBound->
getExprLoc(), diag::err_acc_subarray_out_of_range)
974 << 0 <<
toString(*LowerBoundValue, 10)
976 LowerBoundValue.reset();
977 LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
982 if (LengthValue.has_value()) {
983 if (LengthValue->isNegative()) {
984 Diag(Length->getExprLoc(), diag::err_acc_subarray_negative)
987 Length = GetRecovery(Length, Length->getType());
988 }
else if (BaseSize.has_value() &&
989 llvm::APSInt::compareValues(*LengthValue, *BaseSize) > 0) {
991 Diag(Length->getExprLoc(), diag::err_acc_subarray_out_of_range)
995 Length = GetRecovery(Length, Length->getType());
1000 auto AddAPSInt = [](llvm::APSInt LHS, llvm::APSInt RHS) -> llvm::APSInt {
1001 if (LHS.isSigned() == RHS.isSigned())
1004 unsigned Width = std::max(LHS.getBitWidth(), RHS.getBitWidth()) + 1;
1005 return llvm::APSInt(LHS.sext(Width) + RHS.sext(Width),
true);
1010 if (BaseSize.has_value() && LowerBoundValue.has_value() &&
1011 LengthValue.has_value() &&
1012 llvm::APSInt::compareValues(AddAPSInt(*LowerBoundValue, *LengthValue),
1015 diag::err_acc_subarray_base_plus_length_out_of_range)
1020 LowerBoundValue.reset();
1021 LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
1022 LengthValue.reset();
1023 Length = GetRecovery(Length, Length->getType());
1027 QualType ArrayExprTy = Context.ArraySectionTy;
1028 if (
Base->isTypeDependent() ||
1030 (Length && Length->isTypeDependent()))
1031 ArrayExprTy = Context.DependentTy;
1033 return new (Context)
1042 if (!LoopInfo.TopLevelLoopSeen)
1045 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
1046 Diag(WhileLoc, diag::err_acc_invalid_in_loop)
1047 << 1 << CollapseInfo.DirectiveKind
1049 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
1050 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1051 diag::note_acc_active_clause_here)
1056 CollapseInfo.CurCollapseCount = std::nullopt;
1059 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
1060 Diag(WhileLoc, diag::err_acc_invalid_in_loop)
1061 << 1 << TileInfo.DirectiveKind
1063 assert(TileInfo.ActiveTile &&
"tile count without object?");
1064 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
1069 TileInfo.CurTileCount = std::nullopt;
1077 if (!LoopInfo.TopLevelLoopSeen)
1080 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
1081 Diag(DoLoc, diag::err_acc_invalid_in_loop)
1082 << 2 << CollapseInfo.DirectiveKind
1084 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
1085 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1086 diag::note_acc_active_clause_here)
1091 CollapseInfo.CurCollapseCount = std::nullopt;
1094 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
1095 Diag(DoLoc, diag::err_acc_invalid_in_loop)
1097 assert(TileInfo.ActiveTile &&
"tile count without object?");
1098 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
1103 TileInfo.CurTileCount = std::nullopt;
1108 ForStmtBeginChecker &
C) {
1109 assert(
getLangOpts().OpenACC &&
"Check enabled when not OpenACC?");
1112 LoopInfo.TopLevelLoopSeen =
true;
1114 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
1123 if (LoopInfo.CurLevelHasLoopAlready) {
1124 Diag(ForLoc, diag::err_acc_clause_multiple_loops)
1126 assert(CollapseInfo.ActiveCollapse &&
"No collapse object?");
1128 diag::note_acc_active_clause_here)
1131 --(*CollapseInfo.CurCollapseCount);
1135 if (*CollapseInfo.CurCollapseCount == 0)
1136 CollapseInfo.CollapseDepthSatisfied =
true;
1140 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
1144 if (LoopInfo.CurLevelHasLoopAlready) {
1145 Diag(ForLoc, diag::err_acc_clause_multiple_loops)
1147 assert(TileInfo.ActiveTile &&
"No tile object?");
1148 Diag(TileInfo.ActiveTile->getBeginLoc(),
1149 diag::note_acc_active_clause_here)
1152 TileInfo.CurTileCount = *TileInfo.CurTileCount - 1;
1155 if (*TileInfo.CurTileCount == 0)
1156 TileInfo.TileDepthSatisfied =
true;
1162 LoopInfo.CurLevelHasLoopAlready =
false;
1166bool isValidLoopVariableType(QualType LoopVarTy) {
1189 for (
const auto *TD :
1190 llvm::make_filter_range(RD->decls(), llvm::IsaPred<TypedefNameDecl>)) {
1193 if (TDND->getName() !=
"iterator_category")
1197 if (TDND->getUnderlyingType().isNull())
1200 const CXXRecordDecl *ItrCategoryDecl =
1201 TDND->getUnderlyingType()->getAsCXXRecordDecl();
1204 if (!ItrCategoryDecl)
1207 auto IsRandomAccessIteratorTag = [](
const CXXRecordDecl *RD) {
1208 if (RD->getName() !=
"random_access_iterator_tag")
1211 return RD->getEnclosingNamespaceContext()->isStdNamespace();
1214 if (IsRandomAccessIteratorTag(ItrCategoryDecl))
1219 for (CXXBaseSpecifier BS : ItrCategoryDecl->
bases())
1220 if (IsRandomAccessIteratorTag(BS.getType()->getAsCXXRecordDecl()))
1229const ValueDecl *getDeclFromExpr(
const Expr *E) {
1231 if (
const auto *FE = dyn_cast<FullExpr>(E))
1232 E = FE->getSubExpr();
1238 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
1239 return DRE->getDecl();
1241 if (
const auto *ME = dyn_cast<MemberExpr>(E))
1243 return ME->getMemberDecl();
1249void SemaOpenACC::ForStmtBeginChecker::checkRangeFor() {
1250 const RangeForInfo &RFI = std::get<RangeForInfo>(Info);
1252 if (RFI.Uninstantiated == RFI.CurrentVersion)
1255 const DeclStmt *UninstRangeStmt =
1256 IsInstantiation ? RFI.Uninstantiated->getBeginStmt() :
nullptr;
1257 const DeclStmt *RangeStmt = RFI.CurrentVersion->getBeginStmt();
1261 if (UninstRangeStmt) {
1262 const ValueDecl *InitVar =
1266 if (!isValidLoopVariableType(VarType))
1276 if (!isValidLoopVariableType(VarType)) {
1278 <<
SemaRef.LoopWithoutSeqInfo.Kind << VarType;
1280 diag::note_acc_construct_here)
1281 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1286bool SemaOpenACC::ForStmtBeginChecker::checkForInit(
const Stmt *InitStmt,
1287 const ValueDecl *&InitVar,
1292 SemaRef.Diag(ForLoc, diag::err_acc_loop_variable)
1293 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1295 diag::note_acc_construct_here)
1296 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1300 auto DiagLoopVar = [
this,
Diag, InitStmt]() {
1303 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1305 diag::note_acc_construct_here)
1306 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1311 if (
const auto *ExprTemp = dyn_cast<ExprWithCleanups>(InitStmt))
1312 InitStmt = ExprTemp->getSubExpr();
1313 if (
const auto *E = dyn_cast<Expr>(InitStmt))
1317 if (
const auto *BO = dyn_cast<BinaryOperator>(InitStmt)) {
1320 if (!BO->isAssignmentOp())
1321 return DiagLoopVar();
1323 const Expr *LHS = BO->getLHS()->IgnoreParenImpCasts();
1324 if (
const auto *DRE = dyn_cast<DeclRefExpr>(LHS))
1325 InitVar = DRE->getDecl();
1326 }
else if (
const auto *DS = dyn_cast<DeclStmt>(InitStmt)) {
1328 if (!DS->isSingleDecl())
1329 return DiagLoopVar();
1330 InitVar = dyn_cast<ValueDecl>(DS->getSingleDecl());
1335 return DiagLoopVar();
1340 return DiagLoopVar();
1342 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(InitStmt)) {
1344 if (CE->getOperator() != OO_Equal)
1345 return DiagLoopVar();
1348 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
1349 InitVar = DRE->getDecl();
1350 }
else if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
1352 InitVar = ME->getMemberDecl();
1358 return DiagLoopVar();
1364 if (!isValidLoopVariableType(VarType)) {
1367 <<
SemaRef.LoopWithoutSeqInfo.Kind << VarType;
1369 diag::note_acc_construct_here)
1370 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1378bool SemaOpenACC::ForStmtBeginChecker::checkForCond(
const Stmt *CondStmt,
1379 const ValueDecl *InitVar,
1384 SemaRef.Diag(ForLoc, diag::err_acc_loop_terminating_condition)
1385 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1387 diag::note_acc_construct_here)
1388 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1393 auto DiagCondVar = [
this,
Diag, CondStmt] {
1396 diag::err_acc_loop_terminating_condition)
1397 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1399 diag::note_acc_construct_here)
1400 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1405 if (
const auto *ExprTemp = dyn_cast<ExprWithCleanups>(CondStmt))
1406 CondStmt = ExprTemp->getSubExpr();
1407 if (
const auto *E = dyn_cast<Expr>(CondStmt))
1410 const ValueDecl *CondVar =
nullptr;
1411 if (
const auto *BO = dyn_cast<BinaryOperator>(CondStmt)) {
1412 switch (BO->getOpcode()) {
1414 return DiagCondVar();
1427 CondVar = getDeclFromExpr(BO->getLHS());
1430 CondVar = getDeclFromExpr(BO->getRHS());
1432 }
else if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(CondStmt)) {
1435 if (!CE->isComparisonOp() || CE->getOperator() == OO_Spaceship)
1436 return DiagCondVar();
1440 CondVar = getDeclFromExpr(CE->getArg(0));
1444 CE->getNumArgs() > 1))
1445 CondVar = getDeclFromExpr(CE->getArg(1));
1447 return DiagCondVar();
1451 return DiagCondVar();
1456 return DiagCondVar();
1465bool isValidForIncRHSAssign(
const ValueDecl *InitVar,
const Expr *RHS) {
1467 auto isValid = [](
const ValueDecl *InitVar,
const Expr *InnerLHS,
1468 const Expr *InnerRHS,
bool IsAddition) {
1470 if (!InnerLHS->getType()->isIntegerType() &&
1471 !InnerRHS->getType()->isIntegerType())
1479 const ValueDecl *LHSDecl = getDeclFromExpr(InnerLHS);
1480 const ValueDecl *RHSDecl = getDeclFromExpr(InnerRHS);
1482 if (!LHSDecl || !RHSDecl)
1498 if (
const auto *BO = dyn_cast<BinaryOperator>(RHS)) {
1500 if (OpC != BO_Add && OpC != BO_Sub)
1502 return isValid(InitVar, BO->getLHS(), BO->getRHS(), OpC == BO_Add);
1503 }
else if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
1505 if (Op != OO_Plus && Op != OO_Minus)
1507 return isValid(InitVar, CE->getArg(0), CE->getArg(1), Op == OO_Plus);
1514bool SemaOpenACC::ForStmtBeginChecker::checkForInc(
const Stmt *IncStmt,
1515 const ValueDecl *InitVar,
1519 SemaRef.Diag(ForLoc, diag::err_acc_loop_not_monotonic)
1520 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1522 diag::note_acc_construct_here)
1523 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1527 auto DiagIncVar = [
this,
Diag, IncStmt] {
1530 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1532 diag::note_acc_construct_here)
1533 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1538 if (
const auto *ExprTemp = dyn_cast<ExprWithCleanups>(IncStmt))
1539 IncStmt = ExprTemp->getSubExpr();
1540 if (
const auto *E = dyn_cast<Expr>(IncStmt))
1543 const ValueDecl *IncVar =
nullptr;
1545 if (
const auto *UO = dyn_cast<UnaryOperator>(IncStmt)) {
1547 if (!UO->isIncrementDecrementOp())
1548 return DiagIncVar();
1549 IncVar = getDeclFromExpr(UO->getSubExpr());
1550 }
else if (
const auto *BO = dyn_cast<BinaryOperator>(IncStmt)) {
1551 switch (BO->getOpcode()) {
1553 return DiagIncVar();
1560 if (!isValidForIncRHSAssign(InitVar, BO->getRHS()))
1561 return DiagIncVar();
1564 IncVar = getDeclFromExpr(BO->getLHS());
1565 }
else if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(IncStmt)) {
1566 switch (CE->getOperator()) {
1568 return DiagIncVar();
1577 if (!isValidForIncRHSAssign(InitVar, CE->getArg(1)))
1578 return DiagIncVar();
1582 IncVar = getDeclFromExpr(CE->getArg(0));
1584 return DiagIncVar();
1588 return DiagIncVar();
1594 return DiagIncVar();
1599void SemaOpenACC::ForStmtBeginChecker::checkFor() {
1600 const CheckForInfo &CFI = std::get<CheckForInfo>(Info);
1602 if (!IsInstantiation) {
1605 const ValueDecl *CurInitVar =
nullptr;
1606 checkForInit(CFI.Current.Init, CurInitVar,
true);
1607 checkForCond(CFI.Current.Condition, CurInitVar,
true);
1608 checkForInc(CFI.Current.Increment, CurInitVar,
true);
1610 const ValueDecl *UninstInitVar =
nullptr;
1614 bool UninstInitFailed =
1615 checkForInit(CFI.Uninst.Init, UninstInitVar,
false);
1621 auto InitChanged = [=]() {
1622 if (CFI.Uninst.Init == CFI.Current.Init)
1628 if (
const auto *DS = dyn_cast<DeclStmt>(CFI.Uninst.Init))
1629 if (
const VarDecl *VD = dyn_cast_if_present<VarDecl>(
1630 DS->isSingleDecl() ? DS->getSingleDecl() :
nullptr))
1631 OldVDTy = VD->getType();
1632 if (
const auto *DS = dyn_cast<DeclStmt>(CFI.Current.Init))
1633 if (
const VarDecl *VD = dyn_cast_if_present<VarDecl>(
1634 DS->isSingleDecl() ? DS->getSingleDecl() :
nullptr))
1635 NewVDTy = VD->getType();
1646 bool ShouldDiagNewInit = !UninstInitFailed && InitChanged();
1647 const ValueDecl *CurInitVar =
nullptr;
1648 checkForInit(CFI.Current.Init, CurInitVar, ShouldDiagNewInit);
1652 if (CFI.Uninst.Condition != CFI.Current.Condition &&
1653 !checkForCond(CFI.Uninst.Condition, UninstInitVar,
false))
1654 checkForCond(CFI.Current.Condition, CurInitVar,
true);
1655 if (CFI.Uninst.Increment != CFI.Current.Increment &&
1656 !checkForInc(CFI.Uninst.Increment, UninstInitVar,
false))
1657 checkForInc(CFI.Current.Increment, CurInitVar,
true);
1661void SemaOpenACC::ForStmtBeginChecker::check() {
1672 AlreadyChecked =
true;
1689 if (std::holds_alternative<RangeForInfo>(Info))
1690 return checkRangeFor();
1697 const Stmt *Second,
const Stmt *OldThird,
1698 const Stmt *Third) {
1702 ForStmtBeginChecker FSBC{*
this, ForLoc, OldFirst, OldSecond,
1703 OldThird,
First, Second, Third};
1706 if (!LoopInfo.TopLevelLoopSeen) {
1710 ForStmtBeginHelper(ForLoc, FSBC);
1714 const Stmt *Second,
const Stmt *Third) {
1718 ForStmtBeginChecker FSBC{*
this, ForLoc,
First, Second, Third};
1722 if (!LoopInfo.TopLevelLoopSeen)
1725 ForStmtBeginHelper(ForLoc, FSBC);
1729 const Stmt *OldRangeFor,
1730 const Stmt *RangeFor) {
1731 if (!
getLangOpts().OpenACC || OldRangeFor ==
nullptr || RangeFor ==
nullptr)
1734 ForStmtBeginChecker FSBC{*
this, ForLoc,
1735 cast_if_present<CXXForRangeStmt>(OldRangeFor),
1736 cast_if_present<CXXForRangeStmt>(RangeFor)};
1739 if (!LoopInfo.TopLevelLoopSeen) {
1742 ForStmtBeginHelper(ForLoc, FSBC);
1746 const Stmt *RangeFor) {
1747 if (!
getLangOpts().OpenACC || RangeFor ==
nullptr)
1750 ForStmtBeginChecker FSBC = {*
this, ForLoc,
1751 cast_if_present<CXXForRangeStmt>(RangeFor)};
1755 if (!LoopInfo.TopLevelLoopSeen)
1758 ForStmtBeginHelper(ForLoc, FSBC);
1778 if (
const auto *CS = dyn_cast<CompoundStmt>(CurStmt)) {
1779 for (
const auto *ChildStmt : CS->children()) {
1780 SourceLocation ChildStmtLoc = FindInterveningCodeInLoop(ChildStmt);
1782 return ChildStmtLoc;
1785 return SourceLocation{};
1796 LoopInfo.CurLevelHasLoopAlready =
true;
1801 bool IsActiveCollapse = CollapseInfo.CurCollapseCount &&
1802 *CollapseInfo.CurCollapseCount > 0 &&
1803 !CollapseInfo.ActiveCollapse->hasForce();
1804 bool IsActiveTile = TileInfo.CurTileCount && *TileInfo.CurTileCount > 0;
1806 if (IsActiveCollapse || IsActiveTile) {
1809 if (OtherStmtLoc.
isValid() && IsActiveCollapse) {
1810 Diag(OtherStmtLoc, diag::err_acc_intervening_code)
1812 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1813 diag::note_acc_active_clause_here)
1817 if (OtherStmtLoc.
isValid() && IsActiveTile) {
1818 Diag(OtherStmtLoc, diag::err_acc_intervening_code)
1820 Diag(TileInfo.ActiveTile->getBeginLoc(),
1821 diag::note_acc_active_clause_here)
1841 }
else if (
auto *DRE = dyn_cast<DeclRefExpr>(RoutineName)) {
1842 ValueDecl *VD = DRE->getDecl();
1844 if (
auto *FD = dyn_cast<FunctionDecl>(VD))
1848 if (
auto *VarD = dyn_cast<VarDecl>(VD)) {
1849 QualType VarDTy = VarD->getType();
1852 if (RD->isGenericLambda())
1855 return RD->getLambdaCallOperator();
1871 assert(RoutineName &&
"Routine name cannot be null here");
1882 }
else if (
const auto *DRE = dyn_cast<DeclRefExpr>(RoutineName)) {
1889 if (
const auto *VarD = dyn_cast<VarDecl>(VD)) {
1893 if (RD->isGenericLambda()) {
1933 auto *ContextDecl = dyn_cast<FunctionDecl>(
getCurContext());
1941 for (
const auto *A : ContextDecl->attrs()) {
1944 Diag(A->getLocation(), diag::note_acc_construct_here)
1950 MagicStaticLocs.insert({ContextDecl->getCanonicalDecl(), VD->
getBeginLoc()});
1952void SemaOpenACC::CheckLastRoutineDeclNameConflict(
const NamedDecl *ND) {
1961 if (!LastRoutineDecl)
1994 if (NDLine - LastLine > 1)
2002 diag::warn_acc_confusing_routine_name);
2018 if (!RD || !RD->isLambda())
2021 CheckLastRoutineDeclNameConflict(VD);
2027 CheckLastRoutineDeclNameConflict(FD);
2039 SemaRef.DiscardCleanupsInEvaluationContext();
2040 SemaRef.PopExpressionEvaluationContext();
2047 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
2048 Diag(StartLoc, diag::err_acc_invalid_in_loop)
2049 << 0 << CollapseInfo.DirectiveKind
2051 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
2052 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
2053 diag::note_acc_active_clause_here)
2056 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
2057 Diag(StartLoc, diag::err_acc_invalid_in_loop)
2058 << 0 << TileInfo.DirectiveKind
2060 assert(TileInfo.ActiveTile &&
"Tile count without object?");
2061 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
2065 if (DiagnoseRequiredClauses(K, StartLoc, Clauses))
2067 return diagnoseConstructAppertainment(*
this, K, StartLoc,
true);
2082 return OpenACCComputeConstruct::Create(
2084 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2091 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2095 getASTContext(), ActiveComputeConstructInfo.Kind, StartLoc, DirLoc,
2096 EndLoc, Clauses, AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2101 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2114 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2118 getASTContext(), StartLoc, DirLoc, LParenLoc, Exprs.front(), MiscLoc,
2119 Exprs.drop_front(), RParenLoc, EndLoc, Clauses);
2139 getASTContext(), StartLoc, DirLoc, AtomicKind, EndLoc, Clauses,
2140 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2143 assert(Clauses.empty() &&
"Cache doesn't allow clauses");
2145 LParenLoc, MiscLoc, Exprs, RParenLoc,
2149 llvm_unreachable(
"routine shouldn't handled here");
2154 RParenLoc, EndLoc, Clauses);
2159 llvm_unreachable(
"Unhandled case in directive handling?");
2168 llvm_unreachable(
"Unimplemented associated statement application");
2177 "these don't have associated statements, so shouldn't get here");
2205 Diag(DirectiveLoc, diag::note_acc_construct_here) << K;
2209 if (!CollapseInfo.CollapseDepthSatisfied || !TileInfo.TileDepthSatisfied) {
2210 if (!CollapseInfo.CollapseDepthSatisfied) {
2211 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
2213 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
2214 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
2215 diag::note_acc_active_clause_here)
2219 if (!TileInfo.TileDepthSatisfied) {
2220 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
2222 assert(TileInfo.ActiveTile &&
"Collapse count without object?");
2223 Diag(TileInfo.ActiveTile->getBeginLoc(),
2224 diag::note_acc_active_clause_here)
2230 return AssocStmt.
get();
2232 llvm_unreachable(
"Invalid associated statement application");
2240bool CheckValidRoutineGangWorkerVectorSeqClauses(
2252 auto *FirstDeviceType =
2253 llvm::find_if(Clauses, llvm::IsaPred<OpenACCDeviceTypeClause>);
2258 std::find_if(Clauses.begin(), FirstDeviceType, RequiredPred);
2260 if (ClauseItr != FirstDeviceType)
2264 if (FirstDeviceType == Clauses.end())
2265 return SemaRef.
Diag(DirectiveLoc, diag::err_acc_construct_one_clause_of)
2267 <<
"'gang', 'seq', 'vector', or 'worker'";
2271 auto *PrevDeviceType = FirstDeviceType;
2273 while (PrevDeviceType != Clauses.end()) {
2274 auto *NextDeviceType =
2275 std::find_if(std::next(PrevDeviceType), Clauses.end(),
2276 llvm::IsaPred<OpenACCDeviceTypeClause>);
2278 ClauseItr = std::find_if(PrevDeviceType, NextDeviceType, RequiredPred);
2280 if (ClauseItr == NextDeviceType)
2281 return SemaRef.
Diag((*PrevDeviceType)->getBeginLoc(),
2282 diag::err_acc_clause_routine_one_of_in_region);
2284 PrevDeviceType = NextDeviceType;
2297 SemaRef.DiscardCleanupsInEvaluationContext();
2298 SemaRef.PopExpressionEvaluationContext();
2300 if (DiagnoseRequiredClauses(K, StartLoc, Clauses))
2303 CheckValidRoutineGangWorkerVectorSeqClauses(*
this, StartLoc, Clauses))
2306 return diagnoseConstructAppertainment(*
this, K, StartLoc,
false);
2319 if (Clauses.empty()) {
2320 Diag(EndLoc, diag::err_acc_declare_required_clauses);
2334 llvm_unreachable(
"routine shouldn't be handled here");
2336 llvm_unreachable(
"unhandled case in directive handling?");
2347 if (
auto *FD = dyn_cast<FunctionDecl>(D))
2351 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
2352 return FTD->getTemplatedDecl();
2354 if (
auto *FD = dyn_cast<FieldDecl>(D)) {
2356 FD->getType().isNull() ?
nullptr : FD->getType()->getAsCXXRecordDecl();
2358 if (RD && RD->isGenericLambda())
2359 return RD->getDependentLambdaCallOperator()->getTemplatedDecl();
2360 if (RD && RD->isLambda())
2361 return RD->getLambdaCallOperator();
2365 if (
auto *VD = dyn_cast<VarDecl>(D)) {
2367 if (!
Init ||
Init->getType().isNull())
2370 const auto *RD =
Init->getType()->getAsCXXRecordDecl();
2371 if (RD && RD->isGenericLambda())
2372 return RD->getDependentLambdaCallOperator()->getTemplatedDecl();
2373 if (RD && RD->isLambda())
2374 return RD->getLambdaCallOperator();
2389 ArrayRef<const OpenACCClause *> Clauses,
2391 OpenACCRoutineDeclAttr *A =
2392 OpenACCRoutineDeclAttr::Create(
SemaRef.getASTContext(), DirLoc);
2393 A->Clauses.assign(Clauses.begin(), Clauses.end());
2401 Decl *NextParsedDecl) {
2403 FunctionDecl *NextParsedFDecl = LegalizeNextParsedDecl(NextParsedDecl);
2405 if (!NextParsedFDecl) {
2407 SemaRef.Diag(DirLoc, diag::err_acc_decl_for_routine);
2415 Itr != MagicStaticLocs.end()) {
2416 Diag(Itr->second, diag::err_acc_magic_static_in_routine);
2417 Diag(DirLoc, diag::note_acc_construct_here)
2423 auto BindItr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCBindClause>);
2424 if (BindItr != Clauses.end()) {
2425 for (
auto *A : NextParsedFDecl->
attrs()) {
2429 if (
auto *RA = dyn_cast<OpenACCRoutineDeclAttr>(A)) {
2431 llvm::find_if(RA->Clauses, llvm::IsaPred<OpenACCBindClause>);
2432 if (OtherBindItr != RA->Clauses.end() &&
2435 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_unnamed_bind);
2436 Diag((*OtherBindItr)->getEndLoc(),
2437 diag::note_acc_previous_clause_here)
2438 << (*BindItr)->getClauseKind();
2449 if (
auto *RA = dyn_cast<OpenACCRoutineAnnotAttr>(A);
2450 RA && RA->getRange().getEnd().isValid()) {
2451 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
2452 Diag(RA->getRange().getEnd(), diag::note_acc_previous_clause_here)
2459 CreateRoutineDeclAttr(*
this, DirLoc, Clauses, NextParsedFDecl);
2470 if ((FD = getFunctionFromRoutineName(FuncRef))) {
2475 Itr != MagicStaticLocs.end()) {
2476 Diag(Itr->second, diag::err_acc_magic_static_in_routine);
2477 Diag(DirLoc, diag::note_acc_construct_here)
2486 auto BindItr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCBindClause>);
2488 if (BindItr != Clauses.end()) {
2489 BindLoc = (*BindItr)->getBeginLoc();
2493 for (
auto *A : FD->
attrs()) {
2494 if (
auto *RA = dyn_cast<OpenACCRoutineDeclAttr>(A)) {
2496 llvm::find_if(RA->Clauses, llvm::IsaPred<OpenACCBindClause>);
2497 if (OtherBindItr != RA->Clauses.end()) {
2498 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
2499 Diag((*OtherBindItr)->getEndLoc(),
2500 diag::note_acc_previous_clause_here)
2501 << (*BindItr)->getClauseKind();
2506 if (
auto *RA = dyn_cast<OpenACCRoutineAnnotAttr>(A);
2507 RA && RA->getRange().getEnd().isValid()) {
2508 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
2509 Diag(RA->getRange().getEnd(), diag::note_acc_previous_clause_here)
2510 << (*BindItr)->getClauseKind();
2518 auto *RAA = OpenACCRoutineAnnotAttr::CreateImplicit(
getASTContext(),
2523 for (
auto *CurFD : FD->
redecls())
2529 RParenLoc, EndLoc, Clauses);
2537 RoutineRefList.emplace_back(FD, LastRoutineDecl);
2539 return LastRoutineDecl;
2543 for (
auto [FD, RoutineDecl] : RoutineRefList)
2544 SemaRef.Consumer.HandleOpenACCRoutineReference(FD, RoutineDecl);
2552 assert((!ReferencedFunc || !NextDecl) &&
2553 "Only one of these should be filled");
2556 Decl *NextLineDecl =
nullptr;
2562 return NextDecl.
get();
2566 StartLoc, DirLoc, LParenLoc, ReferencedFunc, RParenLoc, Clauses, EndLoc)};
2574 assert((!ReferencedFunc || !NextStmt) &&
2575 "Only one of these should be filled");
2578 Decl *NextLineDecl =
nullptr;
2581 NextLineDecl = DS->getSingleDecl();
2588 RParenLoc, Clauses, EndLoc)};
2592OpenACCRoutineDeclAttr *
2594 OpenACCRoutineDeclAttr *
New =
2595 OpenACCRoutineDeclAttr::Create(
getASTContext(), Old.getLocation());
2598 New->Clauses = Old.Clauses;
2612enum class InitKind {
Invalid,
Zero, One, AllOnes, Least, Largest };
2615 case InitKind::Invalid:
2616 llvm_unreachable(
"invalid init kind");
2617 case InitKind::Zero:
2618 return llvm::APFloat::getZero(Context.getFloatTypeSemantics(Ty));
2620 return llvm::APFloat::getOne(Context.getFloatTypeSemantics(Ty));
2621 case InitKind::AllOnes:
2622 return llvm::APFloat::getAllOnesValue(Context.getFloatTypeSemantics(Ty));
2623 case InitKind::Least:
2624 return llvm::APFloat::getLargest(Context.getFloatTypeSemantics(Ty),
2626 case InitKind::Largest:
2627 return llvm::APFloat::getLargest(Context.getFloatTypeSemantics(Ty));
2629 llvm_unreachable(
"unknown init kind");
2632llvm::APInt getInitIntValue(ASTContext &Context, InitKind IK, QualType Ty) {
2634 case InitKind::Invalid:
2635 llvm_unreachable(
"invalid init kind");
2636 case InitKind::Zero:
2640 case InitKind::AllOnes:
2641 return llvm::APInt::getAllOnes(Context.
getIntWidth(Ty));
2642 case InitKind::Least:
2644 return llvm::APInt::getSignedMinValue(Context.
getIntWidth(Ty));
2645 return llvm::APInt::getMinValue(Context.
getIntWidth(Ty));
2646 case InitKind::Largest:
2648 return llvm::APInt::getSignedMaxValue(Context.
getIntWidth(Ty));
2649 return llvm::APInt::getMaxValue(Context.
getIntWidth(Ty));
2651 llvm_unreachable(
"unknown init kind");
2656Expr *GenerateReductionInitRecipeExpr(ASTContext &Context,
2657 SourceRange ExprRange, QualType Ty,
2659 if (IK == InitKind::Invalid)
2662 if (IK == InitKind::Zero) {
2663 Expr *InitExpr =
new (Context)
2664 InitListExpr(Context, ExprRange.
getBegin(), {}, ExprRange.
getEnd());
2670 llvm::SmallVector<Expr *> Exprs;
2673 for (
auto *F : RD->fields()) {
2674 if (Expr *NewExpr = GenerateReductionInitRecipeExpr(Context, ExprRange,
2676 Exprs.push_back(NewExpr);
2681 for (uint64_t Idx = 0; Idx < AT->getZExtSize(); ++Idx) {
2682 if (Expr *NewExpr = GenerateReductionInitRecipeExpr(
2683 Context, ExprRange, AT->getElementType(), IK))
2684 Exprs.push_back(NewExpr);
2702 if (
const auto *Cplx = Ty->
getAs<ComplexType>()) {
2707 QualType EltTy = Cplx->getElementType();
2710 Context, getInitFloatValue(Context, InitKind::Zero, EltTy),
2711 true, EltTy, ExprRange.
getBegin()));
2713 Context, getInitFloatValue(Context, InitKind::Zero, EltTy),
2714 true, EltTy, ExprRange.
getBegin()));
2717 Context, getInitIntValue(Context, InitKind::Zero, EltTy), EltTy,
2720 Context, getInitIntValue(Context, InitKind::Zero, EltTy), EltTy,
2730 (IK == InitKind::One ||
2731 IK == InitKind::AllOnes ||
2732 IK == InitKind::Largest),
2736 Context, getInitIntValue(Context, IK, Ty), Ty, ExprRange.
getBegin()));
2740 Expr *InitExpr =
new (Context)
2741 InitListExpr(Context, ExprRange.
getBegin(), Exprs, ExprRange.
getEnd());
2746VarDecl *CreateAllocaDecl(ASTContext &Ctx, DeclContext *DC,
2747 SourceLocation BeginLoc, IdentifierInfo *VarName,
2753ExprResult FinishValueInit(Sema &S, InitializedEntity &Entity,
2754 SourceLocation Loc, QualType VarTy, Expr *InitExpr) {
2758 InitializationKind
Kind =
2760 InitializationSequence InitSeq(S, Entity, Kind, InitExpr,
2764 return InitSeq.Perform(S, Entity, Kind, InitExpr, &VarTy);
2779 if (
const auto *ASE =
2781 VarTy = ASE->getElementType();
2783 VarDecl *AllocaDecl = CreateAllocaDecl(
2785 &
getASTContext().Idents.get(
"openacc.private.init"), VarTy);
2796 if (
Init.isUsable()) {
2815 if (
const auto *ASE =
2817 VarTy = ASE->getElementType();
2819 VarDecl *AllocaDecl = CreateAllocaDecl(
2821 &
getASTContext().Idents.get(
"openacc.firstprivate.init"), VarTy);
2823 VarDecl *Temporary = CreateAllocaDecl(
2844 if (
Init.isUsable()) {
2858 CK_ArrayToPointerDecay, TemporaryDRE,
nullptr,
2861 for (std::size_t I = 0; I < ArrTy->getLimitedSize(); ++I) {
2884 CopySeq.
Perform(
SemaRef.SemaRef, CopyEntity, CopyKind, Subscript);
2885 Args.push_back(ElemRes.
get());
2897 if (
Init.isUsable()) {
2916 if (
const auto *ASE =
2918 VarTy = ASE->getElementType();
2925 if (CreateReductionCombinerRecipe(VarExpr->
getBeginLoc(), ReductionOperator,
2926 VarTy, CombinerRecipes))
2929 VarDecl *AllocaDecl = CreateAllocaDecl(
2931 &
getASTContext().Idents.get(
"openacc.reduction.init"), VarTy);
2936 InitKind IK = InitKind::Invalid;
2937 switch (ReductionOperator) {
2942 IK = InitKind::Invalid;
2945 IK = InitKind::Least;
2948 IK = InitKind::Largest;
2951 IK = InitKind::AllOnes;
2961 IK = InitKind::Zero;
2965 Expr *InitExpr = GenerateReductionInitRecipeExpr(
2973 if (
Init.isUsable()) {
2981bool SemaOpenACC::CreateReductionCombinerRecipe(
2993 switch (ReductionOperator) {
2998 CombinerRecipes.push_back({
nullptr,
nullptr,
nullptr});
3001 BinOp = BinaryOperatorKind::BO_AddAssign;
3004 BinOp = BinaryOperatorKind::BO_MulAssign;
3007 BinOp = BinaryOperatorKind::BO_AndAssign;
3010 BinOp = BinaryOperatorKind::BO_OrAssign;
3013 BinOp = BinaryOperatorKind::BO_XorAssign;
3018 BinOp = BinaryOperatorKind::BO_LT;
3021 BinOp = BinaryOperatorKind::BO_LAnd;
3024 BinOp = BinaryOperatorKind::BO_LOr;
3031 VarTy = AT->getElementType();
3033 assert(!VarTy->
isArrayType() &&
"Only 1 level of array allowed");
3035 enum class CombinerFailureKind {
3042 auto genCombiner = [&,
this](DeclRefExpr *LHSDRE, DeclRefExpr *RHSDRE)
3043 -> std::pair<ExprResult, CombinerFailureKind> {
3045 SemaRef.BuildBinOp(
SemaRef.getCurScope(), Loc, BinOp, LHSDRE, RHSDRE,
3047 switch (ReductionOperator) {
3055 return {BinOpRes, BinOpRes.
isUsable() ? CombinerFailureKind::None
3056 : CombinerFailureKind::BinOp};
3065 return {BinOpRes, CombinerFailureKind::BinOp};
3071 CondRes =
SemaRef.ActOnConditionalOp(Loc, Loc, BinOpRes.
get(), LHSDRE,
3074 CondRes =
SemaRef.ActOnConditionalOp(Loc, Loc, BinOpRes.
get(), RHSDRE,
3078 return {CondRes, CombinerFailureKind::Conditional};
3082 BinaryOperatorKind::BO_Assign,
3083 LHSDRE, CondRes.
get(),
3086 ? CombinerFailureKind::None
3087 : CombinerFailureKind::Assignment};
3094 return {BinOpRes, CombinerFailureKind::BinOp};
3098 BinaryOperatorKind::BO_Assign,
3099 LHSDRE, BinOpRes.
get(),
3102 ? CombinerFailureKind::None
3103 : CombinerFailureKind::Assignment};
3106 llvm_unreachable(
"Invalid should have been caught above");
3108 llvm_unreachable(
"Unhandled case");
3111 auto tryCombiner = [&,
this](DeclRefExpr *LHSDRE, DeclRefExpr *RHSDRE,
3115 Sema::TentativeAnalysisScope Trap{
SemaRef};
3116 return genCombiner(LHSDRE, RHSDRE);
3118 return genCombiner(LHSDRE, RHSDRE);
3121 struct CombinerAttemptTy {
3122 CombinerFailureKind FailKind;
3124 DeclRefExpr *LHSDRE;
3126 DeclRefExpr *RHSDRE;
3130 auto formCombiner = [&,
this](QualType Ty) -> CombinerAttemptTy {
3131 VarDecl *LHSDecl = CreateAllocaDecl(
3133 &
getASTContext().Idents.get(
"openacc.reduction.combiner.lhs"), Ty);
3135 getASTContext(), NestedNameSpecifierLoc{}, SourceLocation{}, LHSDecl,
3137 DeclarationNameInfo{DeclarationName{LHSDecl->
getDeclName()},
3140 VarDecl *RHSDecl = CreateAllocaDecl(
3142 &
getASTContext().Idents.get(
"openacc.reduction.combiner.lhs"), Ty);
3144 getASTContext(), NestedNameSpecifierLoc{}, SourceLocation{}, RHSDecl,
3146 DeclarationNameInfo{DeclarationName{RHSDecl->getDeclName()},
3147 RHSDecl->getBeginLoc()},
3150 std::pair<ExprResult, CombinerFailureKind> BinOpResult =
3151 tryCombiner(LHSDRE, RHSDRE,
true);
3153 return {BinOpResult.second, LHSDecl, LHSDRE, RHSDecl, RHSDRE,
3154 BinOpResult.first.get()};
3157 CombinerAttemptTy TopLevelCombinerInfo = formCombiner(VarTy);
3159 if (TopLevelCombinerInfo.Op) {
3160 if (!TopLevelCombinerInfo.Op->containsErrors() &&
3161 TopLevelCombinerInfo.Op->isInstantiationDependent()) {
3164 CombinerRecipes.push_back({
nullptr,
nullptr,
nullptr});
3166 }
else if (!TopLevelCombinerInfo.Op->containsErrors()) {
3168 CombinerRecipes.push_back({TopLevelCombinerInfo.LHS,
3169 TopLevelCombinerInfo.RHS,
3170 TopLevelCombinerInfo.Op});
3175 auto EmitFailureNote = [&](CombinerFailureKind CFK) {
3176 if (CFK == CombinerFailureKind::BinOp)
3177 return Diag(Loc, diag::note_acc_reduction_combiner_forming)
3179 return Diag(Loc, diag::note_acc_reduction_combiner_forming) << CFK;
3187 Diag(Loc, diag::err_acc_reduction_recipe_no_op) << VarTy;
3188 EmitFailureNote(TopLevelCombinerInfo.FailKind);
3189 tryCombiner(TopLevelCombinerInfo.LHSDRE, TopLevelCombinerInfo.RHSDRE,
3194 for (
const FieldDecl *FD : RD->
fields()) {
3195 CombinerAttemptTy FieldCombinerInfo = formCombiner(FD->getType());
3197 if (!FieldCombinerInfo.Op || FieldCombinerInfo.Op->containsErrors()) {
3198 Diag(Loc, diag::err_acc_reduction_recipe_no_op) << FD->getType();
3199 Diag(FD->getBeginLoc(), diag::note_acc_reduction_recipe_noop_field) << RD;
3200 EmitFailureNote(FieldCombinerInfo.FailKind);
3201 tryCombiner(FieldCombinerInfo.LHSDRE, FieldCombinerInfo.RHSDRE,
3206 if (FieldCombinerInfo.Op->isInstantiationDependent()) {
3209 CombinerRecipes.push_back({
nullptr,
nullptr,
nullptr});
3211 CombinerRecipes.push_back(
3212 {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.
@ Normal
Apply the normal rules for complete types.
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
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.
@ 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()