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;
536 SemaRef.CleanupVarDeclMarking();
546 bool WasParsingInvalidCacheRef =
547 CacheInfo.ParsingCacheVarList && CacheInfo.IsInvalidCacheRef;
548 CacheInfo.ParsingCacheVarList =
false;
549 CacheInfo.IsInvalidCacheRef =
false;
559 if (
auto *SubScrpt = dyn_cast<ArraySubscriptExpr>(CurVarExpr))
567 if (
const auto *DRE = dyn_cast<DeclRefExpr>(CurVarExpr)) {
569 DRE->getFoundDecl()->getCanonicalDecl()))
570 return WasParsingInvalidCacheRef ?
ExprEmpty() : VarExpr;
573 if (
const auto *ME = dyn_cast<MemberExpr>(CurVarExpr)) {
575 return WasParsingInvalidCacheRef ?
ExprEmpty() : VarExpr;
582 return WasParsingInvalidCacheRef ?
ExprEmpty() : VarExpr;
594 if (!
getLangOpts().OpenACC || !CacheInfo.ParsingCacheVarList || !D ||
620 Diag(Loc, diag::warn_acc_cache_var_not_outside_loop);
622 CacheInfo.IsInvalidCacheRef =
true;
655 if (!ArrTy->isConstantArrayType()) {
656 S.
Diag(InnerLoc, clang::diag::warn_acc_var_referenced_non_const_array)
661 return CheckVarType(S, CK, VarExpr, InnerLoc, ArrTy->getElementType());
666 diag::err_incomplete_type))
677 bool HasNonDeletedDefaultCtor =
678 llvm::find_if(RD->ctors(), [](
const CXXConstructorDecl *CD) {
679 return CD->isDefaultConstructor() && !CD->isDeleted();
680 }) != RD->ctors().end();
681 if (!HasNonDeletedDefaultCtor && !RD->needsImplicitDefaultConstructor()) {
682 S.
Diag(InnerLoc, clang::diag::warn_acc_var_referenced_lacks_op)
683 << InnerTy << CK << clang::diag::AccVarReferencedReason::DefCtor;
687 if (!RD->hasSimpleCopyConstructor()) {
695 S.
Diag(InnerLoc, clang::diag::warn_acc_var_referenced_lacks_op)
696 << InnerTy << CK << clang::diag::AccVarReferencedReason::CopyCtor;
707 bool DestructorDeleted =
708 RD->getDestructor() && RD->getDestructor()->isDeleted();
709 if (DestructorDeleted && !RD->needsImplicitDestructor()) {
710 S.
Diag(InnerLoc, clang::diag::warn_acc_var_referenced_lacks_op)
711 << InnerTy << CK << clang::diag::AccVarReferencedReason::Dtor;
721 return CheckVarType(S, CK, VarExpr, InnerExpr->
getBeginLoc(),
729 SemaRef.CleanupVarDeclMarking();
747 diag::err_acc_not_a_var_ref_use_device_declare)
755 diag::ext_acc_array_section_use_device_declare)
762 if (
auto *SubScrpt = dyn_cast<ArraySubscriptExpr>(CurVarExpr))
770 if (
const auto *DRE = dyn_cast<DeclRefExpr>(CurVarExpr)) {
772 DRE->getFoundDecl()->getCanonicalDecl()))
773 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
782 if (
const auto *ME = dyn_cast<MemberExpr>(CurVarExpr)) {
790 const auto *
This = dyn_cast<CXXThisExpr>(ME->getBase());
792 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
794 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
803 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
810 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
818 Diag(VarExpr->
getExprLoc(), diag::err_acc_not_a_var_ref_use_device_declare)
821 Diag(VarExpr->
getExprLoc(), diag::err_acc_not_a_var_ref_use_device_declare)
837 if (
Base->hasPlaceholderType() &&
838 !
Base->hasPlaceholderType(BuiltinType::ArraySection)) {
851 LowerBound =
Result.get();
853 if (Length && Length->getType()->isNonOverloadPlaceholderType()) {
867 if (!
Base->isTypeDependent()) {
874 Diag(
Base->getExprLoc(), diag::err_acc_typecheck_subarray_value)
875 <<
Base->getSourceRange());
879 Diag(
Base->getExprLoc(), diag::err_acc_subarray_function_type)
880 << ResultTy <<
Base->getSourceRange();
884 if (
SemaRef.RequireCompleteType(
Base->getExprLoc(), ResultTy,
885 diag::err_acc_subarray_incomplete_type,
889 if (!
Base->hasPlaceholderType(BuiltinType::ArraySection)) {
900 return Recovery.
isUsable() ? Recovery.
get() :
nullptr;
910 LBRes =
SemaRef.DefaultLvalueConversion(LBRes.
get());
912 LBRes.
isUsable() ? LBRes.
get() : GetRecovery(LowerBound, Context.IntTy);
915 if (Length && !Length->isTypeDependent()) {
918 Length->getExprLoc(), Length);
921 LenRes =
SemaRef.DefaultLvalueConversion(LenRes.
get());
923 LenRes.
isUsable() ? LenRes.
get() : GetRecovery(Length, Context.IntTy);
927 if (!Length && (OriginalBaseTy.
isNull() ||
933 Diag(DiagLoc, diag::err_acc_subarray_no_length) << IsArray;
938 Length = Recovery.
isUsable() ? Recovery.
get() :
nullptr;
949 std::optional<llvm::APSInt> BaseSize;
951 const auto *ArrayTy = Context.getAsConstantArrayType(OriginalBaseTy);
952 BaseSize = ArrayTy->getSize();
955 auto GetBoundValue = [&](
Expr *E) -> std::optional<llvm::APSInt> {
965 std::optional<llvm::APSInt> LowerBoundValue = GetBoundValue(LowerBound);
966 std::optional<llvm::APSInt> LengthValue = GetBoundValue(Length);
969 if (LowerBoundValue.has_value()) {
970 if (LowerBoundValue->isNegative()) {
972 << 0 <<
toString(*LowerBoundValue, 10);
973 LowerBoundValue.reset();
974 LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
975 }
else if (BaseSize.has_value() &&
976 llvm::APSInt::compareValues(*LowerBoundValue, *BaseSize) >= 0) {
978 Diag(LowerBound->
getExprLoc(), diag::err_acc_subarray_out_of_range)
979 << 0 <<
toString(*LowerBoundValue, 10)
981 LowerBoundValue.reset();
982 LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
987 if (LengthValue.has_value()) {
988 if (LengthValue->isNegative()) {
989 Diag(Length->getExprLoc(), diag::err_acc_subarray_negative)
992 Length = GetRecovery(Length, Length->getType());
993 }
else if (BaseSize.has_value() &&
994 llvm::APSInt::compareValues(*LengthValue, *BaseSize) > 0) {
996 Diag(Length->getExprLoc(), diag::err_acc_subarray_out_of_range)
1000 Length = GetRecovery(Length, Length->getType());
1005 auto AddAPSInt = [](llvm::APSInt LHS, llvm::APSInt RHS) -> llvm::APSInt {
1006 if (LHS.isSigned() == RHS.isSigned() &&
1007 LHS.getBitWidth() == RHS.getBitWidth())
1011 unsigned Width = std::max(LHS.getBitWidth(), RHS.getBitWidth()) + 1;
1012 return llvm::APSInt(LHS.sext(Width) + RHS.sext(Width),
true);
1017 if (BaseSize.has_value() && LowerBoundValue.has_value() &&
1018 LengthValue.has_value() &&
1019 llvm::APSInt::compareValues(AddAPSInt(*LowerBoundValue, *LengthValue),
1022 diag::err_acc_subarray_base_plus_length_out_of_range)
1027 LowerBoundValue.reset();
1028 LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
1029 LengthValue.reset();
1030 Length = GetRecovery(Length, Length->getType());
1034 QualType ArrayExprTy = Context.ArraySectionTy;
1035 if (
Base->isTypeDependent() ||
1037 (Length && Length->isTypeDependent()))
1038 ArrayExprTy = Context.DependentTy;
1040 return new (Context)
1049 if (!LoopInfo.TopLevelLoopSeen)
1052 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
1053 Diag(WhileLoc, diag::err_acc_invalid_in_loop)
1054 << 1 << CollapseInfo.DirectiveKind
1056 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
1057 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1058 diag::note_acc_active_clause_here)
1063 CollapseInfo.CurCollapseCount = std::nullopt;
1066 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
1067 Diag(WhileLoc, diag::err_acc_invalid_in_loop)
1068 << 1 << TileInfo.DirectiveKind
1070 assert(TileInfo.ActiveTile &&
"tile count without object?");
1071 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
1076 TileInfo.CurTileCount = std::nullopt;
1084 if (!LoopInfo.TopLevelLoopSeen)
1087 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
1088 Diag(DoLoc, diag::err_acc_invalid_in_loop)
1089 << 2 << CollapseInfo.DirectiveKind
1091 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
1092 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1093 diag::note_acc_active_clause_here)
1098 CollapseInfo.CurCollapseCount = std::nullopt;
1101 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
1102 Diag(DoLoc, diag::err_acc_invalid_in_loop)
1104 assert(TileInfo.ActiveTile &&
"tile count without object?");
1105 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
1110 TileInfo.CurTileCount = std::nullopt;
1115 ForStmtBeginChecker &
C) {
1116 assert(
getLangOpts().OpenACC &&
"Check enabled when not OpenACC?");
1119 LoopInfo.TopLevelLoopSeen =
true;
1121 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
1130 if (LoopInfo.CurLevelHasLoopAlready) {
1131 Diag(ForLoc, diag::err_acc_clause_multiple_loops)
1133 assert(CollapseInfo.ActiveCollapse &&
"No collapse object?");
1135 diag::note_acc_active_clause_here)
1138 --(*CollapseInfo.CurCollapseCount);
1142 if (*CollapseInfo.CurCollapseCount == 0)
1143 CollapseInfo.CollapseDepthSatisfied =
true;
1147 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
1151 if (LoopInfo.CurLevelHasLoopAlready) {
1152 Diag(ForLoc, diag::err_acc_clause_multiple_loops)
1154 assert(TileInfo.ActiveTile &&
"No tile object?");
1155 Diag(TileInfo.ActiveTile->getBeginLoc(),
1156 diag::note_acc_active_clause_here)
1159 TileInfo.CurTileCount = *TileInfo.CurTileCount - 1;
1162 if (*TileInfo.CurTileCount == 0)
1163 TileInfo.TileDepthSatisfied =
true;
1169 LoopInfo.CurLevelHasLoopAlready =
false;
1173bool isValidLoopVariableType(QualType LoopVarTy) {
1196 for (
const auto *TD :
1197 llvm::make_filter_range(RD->decls(), llvm::IsaPred<TypedefNameDecl>)) {
1200 if (TDND->getName() !=
"iterator_category")
1204 if (TDND->getUnderlyingType().isNull())
1207 const CXXRecordDecl *ItrCategoryDecl =
1208 TDND->getUnderlyingType()->getAsCXXRecordDecl();
1211 if (!ItrCategoryDecl)
1214 auto IsRandomAccessIteratorTag = [](
const CXXRecordDecl *RD) {
1215 if (RD->getName() !=
"random_access_iterator_tag")
1218 return RD->getEnclosingNamespaceContext()->isStdNamespace();
1221 if (IsRandomAccessIteratorTag(ItrCategoryDecl))
1226 for (CXXBaseSpecifier BS : ItrCategoryDecl->
bases())
1227 if (IsRandomAccessIteratorTag(BS.getType()->getAsCXXRecordDecl()))
1236const ValueDecl *getDeclFromExpr(
const Expr *E) {
1238 if (
const auto *FE = dyn_cast<FullExpr>(E))
1239 E = FE->getSubExpr();
1245 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
1246 return DRE->getDecl();
1248 if (
const auto *ME = dyn_cast<MemberExpr>(E))
1250 return ME->getMemberDecl();
1256void SemaOpenACC::ForStmtBeginChecker::checkRangeFor() {
1257 const RangeForInfo &RFI = std::get<RangeForInfo>(Info);
1259 if (RFI.Uninstantiated == RFI.CurrentVersion)
1262 const DeclStmt *UninstRangeStmt =
1263 IsInstantiation ? RFI.Uninstantiated->getBeginStmt() :
nullptr;
1264 const DeclStmt *RangeStmt = RFI.CurrentVersion->getBeginStmt();
1268 if (UninstRangeStmt) {
1269 const ValueDecl *InitVar =
1273 if (!isValidLoopVariableType(VarType))
1283 if (!isValidLoopVariableType(VarType)) {
1285 <<
SemaRef.LoopWithoutSeqInfo.Kind << VarType;
1287 diag::note_acc_construct_here)
1288 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1293bool SemaOpenACC::ForStmtBeginChecker::checkForInit(
const Stmt *InitStmt,
1294 const ValueDecl *&InitVar,
1299 SemaRef.Diag(ForLoc, diag::err_acc_loop_variable)
1300 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1302 diag::note_acc_construct_here)
1303 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1307 auto DiagLoopVar = [
this,
Diag, InitStmt]() {
1310 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1312 diag::note_acc_construct_here)
1313 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1318 if (
const auto *ExprTemp = dyn_cast<ExprWithCleanups>(InitStmt))
1319 InitStmt = ExprTemp->getSubExpr();
1320 if (
const auto *E = dyn_cast<Expr>(InitStmt))
1324 if (
const auto *BO = dyn_cast<BinaryOperator>(InitStmt)) {
1327 if (!BO->isAssignmentOp())
1328 return DiagLoopVar();
1330 const Expr *LHS = BO->getLHS()->IgnoreParenImpCasts();
1331 if (
const auto *DRE = dyn_cast<DeclRefExpr>(LHS))
1332 InitVar = DRE->getDecl();
1333 }
else if (
const auto *DS = dyn_cast<DeclStmt>(InitStmt)) {
1335 if (!DS->isSingleDecl())
1336 return DiagLoopVar();
1337 InitVar = dyn_cast<ValueDecl>(DS->getSingleDecl());
1342 return DiagLoopVar();
1347 return DiagLoopVar();
1349 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(InitStmt)) {
1351 if (CE->getOperator() != OO_Equal)
1352 return DiagLoopVar();
1353 if (CE->getNumArgs() < 1)
1354 return DiagLoopVar();
1357 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
1358 InitVar = DRE->getDecl();
1359 }
else if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
1361 InitVar = ME->getMemberDecl();
1367 return DiagLoopVar();
1373 if (!isValidLoopVariableType(VarType)) {
1376 <<
SemaRef.LoopWithoutSeqInfo.Kind << VarType;
1378 diag::note_acc_construct_here)
1379 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1387bool SemaOpenACC::ForStmtBeginChecker::checkForCond(
const Stmt *CondStmt,
1388 const ValueDecl *InitVar,
1393 SemaRef.Diag(ForLoc, diag::err_acc_loop_terminating_condition)
1394 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1396 diag::note_acc_construct_here)
1397 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1402 auto DiagCondVar = [
this,
Diag, CondStmt] {
1405 diag::err_acc_loop_terminating_condition)
1406 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1408 diag::note_acc_construct_here)
1409 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1414 if (
const auto *ExprTemp = dyn_cast<ExprWithCleanups>(CondStmt))
1415 CondStmt = ExprTemp->getSubExpr();
1416 if (
const auto *E = dyn_cast<Expr>(CondStmt))
1419 const ValueDecl *CondVar =
nullptr;
1420 if (
const auto *BO = dyn_cast<BinaryOperator>(CondStmt)) {
1421 switch (BO->getOpcode()) {
1423 return DiagCondVar();
1436 CondVar = getDeclFromExpr(BO->getLHS());
1439 CondVar = getDeclFromExpr(BO->getRHS());
1441 }
else if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(CondStmt)) {
1444 if (!CE->isComparisonOp() || CE->getOperator() == OO_Spaceship)
1445 return DiagCondVar();
1447 if (CE->getNumArgs() < 1)
1452 CondVar = getDeclFromExpr(CE->getArg(0));
1456 CE->getNumArgs() > 1))
1457 CondVar = getDeclFromExpr(CE->getArg(1));
1459 return DiagCondVar();
1463 return DiagCondVar();
1468 return DiagCondVar();
1477bool isValidForIncRHSAssign(
const ValueDecl *InitVar,
const Expr *RHS) {
1479 auto isValid = [](
const ValueDecl *InitVar,
const Expr *InnerLHS,
1480 const Expr *InnerRHS,
bool IsAddition) {
1482 if (!InnerLHS->getType()->isIntegerType() &&
1483 !InnerRHS->getType()->isIntegerType())
1491 const ValueDecl *LHSDecl = getDeclFromExpr(InnerLHS);
1492 const ValueDecl *RHSDecl = getDeclFromExpr(InnerRHS);
1494 if (!LHSDecl || !RHSDecl)
1510 if (
const auto *BO = dyn_cast<BinaryOperator>(RHS)) {
1512 if (OpC != BO_Add && OpC != BO_Sub)
1514 return isValid(InitVar, BO->getLHS(), BO->getRHS(), OpC == BO_Add);
1515 }
else if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
1517 if (Op != OO_Plus && Op != OO_Minus)
1522 if (CE->getNumArgs() != 2)
1524 return isValid(InitVar, CE->getArg(0), CE->getArg(1), Op == OO_Plus);
1531bool SemaOpenACC::ForStmtBeginChecker::checkForInc(
const Stmt *IncStmt,
1532 const ValueDecl *InitVar,
1536 SemaRef.Diag(ForLoc, diag::err_acc_loop_not_monotonic)
1537 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1539 diag::note_acc_construct_here)
1540 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1544 auto DiagIncVar = [
this,
Diag, IncStmt] {
1547 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1549 diag::note_acc_construct_here)
1550 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1555 if (
const auto *ExprTemp = dyn_cast<ExprWithCleanups>(IncStmt))
1556 IncStmt = ExprTemp->getSubExpr();
1557 if (
const auto *E = dyn_cast<Expr>(IncStmt))
1560 const ValueDecl *IncVar =
nullptr;
1562 if (
const auto *UO = dyn_cast<UnaryOperator>(IncStmt)) {
1564 if (!UO->isIncrementDecrementOp())
1565 return DiagIncVar();
1566 IncVar = getDeclFromExpr(UO->getSubExpr());
1567 }
else if (
const auto *BO = dyn_cast<BinaryOperator>(IncStmt)) {
1568 switch (BO->getOpcode()) {
1570 return DiagIncVar();
1577 if (!isValidForIncRHSAssign(InitVar, BO->getRHS()))
1578 return DiagIncVar();
1581 IncVar = getDeclFromExpr(BO->getLHS());
1582 }
else if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(IncStmt)) {
1583 if (CE->getNumArgs() < 1)
1584 return DiagIncVar();
1586 switch (CE->getOperator()) {
1588 return DiagIncVar();
1597 if (CE->getNumArgs() != 2 ||
1598 !isValidForIncRHSAssign(InitVar, CE->getArg(1)))
1599 return DiagIncVar();
1603 IncVar = getDeclFromExpr(CE->getArg(0));
1605 return DiagIncVar();
1609 return DiagIncVar();
1615 return DiagIncVar();
1620void SemaOpenACC::ForStmtBeginChecker::checkFor() {
1621 const CheckForInfo &CFI = std::get<CheckForInfo>(Info);
1623 if (!IsInstantiation) {
1626 const ValueDecl *CurInitVar =
nullptr;
1627 checkForInit(CFI.Current.Init, CurInitVar,
true);
1628 checkForCond(CFI.Current.Condition, CurInitVar,
true);
1629 checkForInc(CFI.Current.Increment, CurInitVar,
true);
1631 const ValueDecl *UninstInitVar =
nullptr;
1635 bool UninstInitFailed =
1636 checkForInit(CFI.Uninst.Init, UninstInitVar,
false);
1642 auto InitChanged = [=]() {
1643 if (CFI.Uninst.Init == CFI.Current.Init)
1649 if (
const auto *DS = dyn_cast<DeclStmt>(CFI.Uninst.Init))
1650 if (
const VarDecl *VD = dyn_cast_if_present<VarDecl>(
1651 DS->isSingleDecl() ? DS->getSingleDecl() :
nullptr))
1652 OldVDTy = VD->getType();
1653 if (
const auto *DS = dyn_cast<DeclStmt>(CFI.Current.Init))
1654 if (
const VarDecl *VD = dyn_cast_if_present<VarDecl>(
1655 DS->isSingleDecl() ? DS->getSingleDecl() :
nullptr))
1656 NewVDTy = VD->getType();
1667 bool ShouldDiagNewInit = !UninstInitFailed && InitChanged();
1668 const ValueDecl *CurInitVar =
nullptr;
1669 checkForInit(CFI.Current.Init, CurInitVar, ShouldDiagNewInit);
1673 if (CFI.Uninst.Condition != CFI.Current.Condition &&
1674 !checkForCond(CFI.Uninst.Condition, UninstInitVar,
false))
1675 checkForCond(CFI.Current.Condition, CurInitVar,
true);
1676 if (CFI.Uninst.Increment != CFI.Current.Increment &&
1677 !checkForInc(CFI.Uninst.Increment, UninstInitVar,
false))
1678 checkForInc(CFI.Current.Increment, CurInitVar,
true);
1682void SemaOpenACC::ForStmtBeginChecker::check() {
1693 AlreadyChecked =
true;
1710 if (std::holds_alternative<RangeForInfo>(Info))
1711 return checkRangeFor();
1718 const Stmt *Second,
const Stmt *OldThird,
1719 const Stmt *Third) {
1723 ForStmtBeginChecker FSBC{*
this, ForLoc, OldFirst, OldSecond,
1724 OldThird,
First, Second, Third};
1727 if (!LoopInfo.TopLevelLoopSeen) {
1731 ForStmtBeginHelper(ForLoc, FSBC);
1735 const Stmt *Second,
const Stmt *Third) {
1739 ForStmtBeginChecker FSBC{*
this, ForLoc,
First, Second, Third};
1743 if (!LoopInfo.TopLevelLoopSeen)
1746 ForStmtBeginHelper(ForLoc, FSBC);
1750 const Stmt *OldRangeFor,
1751 const Stmt *RangeFor) {
1752 if (!
getLangOpts().OpenACC || OldRangeFor ==
nullptr || RangeFor ==
nullptr)
1755 ForStmtBeginChecker FSBC{*
this, ForLoc,
1756 cast_if_present<CXXForRangeStmt>(OldRangeFor),
1757 cast_if_present<CXXForRangeStmt>(RangeFor)};
1760 if (!LoopInfo.TopLevelLoopSeen) {
1763 ForStmtBeginHelper(ForLoc, FSBC);
1767 const Stmt *RangeFor) {
1768 if (!
getLangOpts().OpenACC || RangeFor ==
nullptr)
1771 ForStmtBeginChecker FSBC = {*
this, ForLoc,
1772 cast_if_present<CXXForRangeStmt>(RangeFor)};
1776 if (!LoopInfo.TopLevelLoopSeen)
1779 ForStmtBeginHelper(ForLoc, FSBC);
1799 if (
const auto *CS = dyn_cast<CompoundStmt>(CurStmt)) {
1800 for (
const auto *ChildStmt : CS->children()) {
1801 SourceLocation ChildStmtLoc = FindInterveningCodeInLoop(ChildStmt);
1803 return ChildStmtLoc;
1806 return SourceLocation{};
1817 LoopInfo.CurLevelHasLoopAlready =
true;
1822 bool IsActiveCollapse = CollapseInfo.CurCollapseCount &&
1823 *CollapseInfo.CurCollapseCount > 0 &&
1824 !CollapseInfo.ActiveCollapse->hasForce();
1825 bool IsActiveTile = TileInfo.CurTileCount && *TileInfo.CurTileCount > 0;
1827 if (IsActiveCollapse || IsActiveTile) {
1830 if (OtherStmtLoc.
isValid() && IsActiveCollapse) {
1831 Diag(OtherStmtLoc, diag::err_acc_intervening_code)
1833 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1834 diag::note_acc_active_clause_here)
1838 if (OtherStmtLoc.
isValid() && IsActiveTile) {
1839 Diag(OtherStmtLoc, diag::err_acc_intervening_code)
1841 Diag(TileInfo.ActiveTile->getBeginLoc(),
1842 diag::note_acc_active_clause_here)
1862 }
else if (
auto *DRE = dyn_cast<DeclRefExpr>(RoutineName)) {
1863 ValueDecl *VD = DRE->getDecl();
1865 if (
auto *FD = dyn_cast<FunctionDecl>(VD))
1869 if (
auto *VarD = dyn_cast<VarDecl>(VD)) {
1870 QualType VarDTy = VarD->getType();
1873 if (RD->isGenericLambda())
1876 return RD->getLambdaCallOperator();
1892 assert(RoutineName &&
"Routine name cannot be null here");
1903 }
else if (
const auto *DRE = dyn_cast<DeclRefExpr>(RoutineName)) {
1910 if (
const auto *VarD = dyn_cast<VarDecl>(VD)) {
1914 if (RD->isGenericLambda()) {
1954 auto *ContextDecl = dyn_cast<FunctionDecl>(
getCurContext());
1962 for (
const auto *A : ContextDecl->attrs()) {
1965 Diag(A->getLocation(), diag::note_acc_construct_here)
1971 MagicStaticLocs.insert({ContextDecl->getCanonicalDecl(), VD->
getBeginLoc()});
1973void SemaOpenACC::CheckLastRoutineDeclNameConflict(
const NamedDecl *ND) {
1982 if (!LastRoutineDecl)
2015 if (NDLine - LastLine > 1)
2023 diag::warn_acc_confusing_routine_name);
2039 if (!RD || !RD->isLambda())
2042 CheckLastRoutineDeclNameConflict(VD);
2048 CheckLastRoutineDeclNameConflict(FD);
2060 SemaRef.DiscardCleanupsInEvaluationContext();
2061 SemaRef.PopExpressionEvaluationContext();
2068 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
2069 Diag(StartLoc, diag::err_acc_invalid_in_loop)
2070 << 0 << CollapseInfo.DirectiveKind
2072 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
2073 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
2074 diag::note_acc_active_clause_here)
2077 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
2078 Diag(StartLoc, diag::err_acc_invalid_in_loop)
2079 << 0 << TileInfo.DirectiveKind
2081 assert(TileInfo.ActiveTile &&
"Tile count without object?");
2082 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
2086 if (DiagnoseRequiredClauses(K, StartLoc, Clauses))
2088 return diagnoseConstructAppertainment(*
this, K, StartLoc,
true);
2103 return OpenACCComputeConstruct::Create(
2105 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2112 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2116 getASTContext(), ActiveComputeConstructInfo.Kind, StartLoc, DirLoc,
2117 EndLoc, Clauses, AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2122 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2135 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2139 getASTContext(), StartLoc, DirLoc, LParenLoc, Exprs.front(), MiscLoc,
2140 Exprs.drop_front(), RParenLoc, EndLoc, Clauses);
2160 getASTContext(), StartLoc, DirLoc, AtomicKind, EndLoc, Clauses,
2161 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2164 assert(Clauses.empty() &&
"Cache doesn't allow clauses");
2166 LParenLoc, MiscLoc, Exprs, RParenLoc,
2170 llvm_unreachable(
"routine shouldn't handled here");
2175 RParenLoc, EndLoc, Clauses);
2180 llvm_unreachable(
"Unhandled case in directive handling?");
2189 llvm_unreachable(
"Unimplemented associated statement application");
2198 "these don't have associated statements, so shouldn't get here");
2226 Diag(DirectiveLoc, diag::note_acc_construct_here) << K;
2230 if (!CollapseInfo.CollapseDepthSatisfied || !TileInfo.TileDepthSatisfied) {
2231 if (!CollapseInfo.CollapseDepthSatisfied) {
2232 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
2234 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
2235 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
2236 diag::note_acc_active_clause_here)
2240 if (!TileInfo.TileDepthSatisfied) {
2241 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
2243 assert(TileInfo.ActiveTile &&
"Collapse count without object?");
2244 Diag(TileInfo.ActiveTile->getBeginLoc(),
2245 diag::note_acc_active_clause_here)
2251 return AssocStmt.
get();
2253 llvm_unreachable(
"Invalid associated statement application");
2261bool CheckValidRoutineGangWorkerVectorSeqClauses(
2273 auto *FirstDeviceType =
2274 llvm::find_if(Clauses, llvm::IsaPred<OpenACCDeviceTypeClause>);
2279 std::find_if(Clauses.begin(), FirstDeviceType, RequiredPred);
2281 if (ClauseItr != FirstDeviceType)
2285 if (FirstDeviceType == Clauses.end())
2286 return SemaRef.
Diag(DirectiveLoc, diag::err_acc_construct_one_clause_of)
2288 <<
"'gang', 'seq', 'vector', or 'worker'";
2292 auto *PrevDeviceType = FirstDeviceType;
2294 while (PrevDeviceType != Clauses.end()) {
2295 auto *NextDeviceType =
2296 std::find_if(std::next(PrevDeviceType), Clauses.end(),
2297 llvm::IsaPred<OpenACCDeviceTypeClause>);
2299 ClauseItr = std::find_if(PrevDeviceType, NextDeviceType, RequiredPred);
2301 if (ClauseItr == NextDeviceType)
2302 return SemaRef.
Diag((*PrevDeviceType)->getBeginLoc(),
2303 diag::err_acc_clause_routine_one_of_in_region);
2305 PrevDeviceType = NextDeviceType;
2318 SemaRef.DiscardCleanupsInEvaluationContext();
2319 SemaRef.PopExpressionEvaluationContext();
2321 if (DiagnoseRequiredClauses(K, StartLoc, Clauses))
2324 CheckValidRoutineGangWorkerVectorSeqClauses(*
this, StartLoc, Clauses))
2327 return diagnoseConstructAppertainment(*
this, K, StartLoc,
false);
2340 if (Clauses.empty()) {
2341 Diag(EndLoc, diag::err_acc_declare_required_clauses);
2355 llvm_unreachable(
"routine shouldn't be handled here");
2357 llvm_unreachable(
"unhandled case in directive handling?");
2368 if (
auto *FD = dyn_cast<FunctionDecl>(D))
2372 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
2373 return FTD->getTemplatedDecl();
2375 if (
auto *FD = dyn_cast<FieldDecl>(D)) {
2377 FD->getType().isNull() ?
nullptr : FD->getType()->getAsCXXRecordDecl();
2379 if (RD && RD->isGenericLambda())
2380 return RD->getDependentLambdaCallOperator()->getTemplatedDecl();
2381 if (RD && RD->isLambda())
2382 return RD->getLambdaCallOperator();
2386 if (
auto *VD = dyn_cast<VarDecl>(D)) {
2388 if (!
Init ||
Init->getType().isNull())
2391 const auto *RD =
Init->getType()->getAsCXXRecordDecl();
2392 if (RD && RD->isGenericLambda())
2393 return RD->getDependentLambdaCallOperator()->getTemplatedDecl();
2394 if (RD && RD->isLambda())
2395 return RD->getLambdaCallOperator();
2410 ArrayRef<const OpenACCClause *> Clauses,
2412 OpenACCRoutineDeclAttr *A =
2413 OpenACCRoutineDeclAttr::Create(
SemaRef.getASTContext(), DirLoc);
2414 A->Clauses.assign(Clauses.begin(), Clauses.end());
2422 Decl *NextParsedDecl) {
2424 FunctionDecl *NextParsedFDecl = LegalizeNextParsedDecl(NextParsedDecl);
2426 if (!NextParsedFDecl) {
2428 SemaRef.Diag(DirLoc, diag::err_acc_decl_for_routine);
2436 Itr != MagicStaticLocs.end()) {
2437 Diag(Itr->second, diag::err_acc_magic_static_in_routine);
2438 Diag(DirLoc, diag::note_acc_construct_here)
2444 auto BindItr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCBindClause>);
2445 if (BindItr != Clauses.end()) {
2446 for (
auto *A : NextParsedFDecl->
attrs()) {
2450 if (
auto *RA = dyn_cast<OpenACCRoutineDeclAttr>(A)) {
2452 llvm::find_if(RA->Clauses, llvm::IsaPred<OpenACCBindClause>);
2453 if (OtherBindItr != RA->Clauses.end() &&
2456 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_unnamed_bind);
2457 Diag((*OtherBindItr)->getEndLoc(),
2458 diag::note_acc_previous_clause_here)
2459 << (*BindItr)->getClauseKind();
2470 if (
auto *RA = dyn_cast<OpenACCRoutineAnnotAttr>(A);
2471 RA && RA->getRange().getEnd().isValid()) {
2472 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
2473 Diag(RA->getRange().getEnd(), diag::note_acc_previous_clause_here)
2480 CreateRoutineDeclAttr(*
this, DirLoc, Clauses, NextParsedFDecl);
2491 if ((FD = getFunctionFromRoutineName(FuncRef))) {
2496 Itr != MagicStaticLocs.end()) {
2497 Diag(Itr->second, diag::err_acc_magic_static_in_routine);
2498 Diag(DirLoc, diag::note_acc_construct_here)
2507 auto BindItr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCBindClause>);
2509 if (BindItr != Clauses.end()) {
2510 BindLoc = (*BindItr)->getBeginLoc();
2514 for (
auto *A : FD->
attrs()) {
2515 if (
auto *RA = dyn_cast<OpenACCRoutineDeclAttr>(A)) {
2517 llvm::find_if(RA->Clauses, llvm::IsaPred<OpenACCBindClause>);
2518 if (OtherBindItr != RA->Clauses.end()) {
2519 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
2520 Diag((*OtherBindItr)->getEndLoc(),
2521 diag::note_acc_previous_clause_here)
2522 << (*BindItr)->getClauseKind();
2527 if (
auto *RA = dyn_cast<OpenACCRoutineAnnotAttr>(A);
2528 RA && RA->getRange().getEnd().isValid()) {
2529 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
2530 Diag(RA->getRange().getEnd(), diag::note_acc_previous_clause_here)
2531 << (*BindItr)->getClauseKind();
2539 auto *RAA = OpenACCRoutineAnnotAttr::CreateImplicit(
getASTContext(),
2544 for (
auto *CurFD : FD->
redecls())
2550 RParenLoc, EndLoc, Clauses);
2558 RoutineRefList.emplace_back(FD, LastRoutineDecl);
2560 return LastRoutineDecl;
2564 for (
auto [FD, RoutineDecl] : RoutineRefList)
2565 SemaRef.Consumer.HandleOpenACCRoutineReference(FD, RoutineDecl);
2573 assert((!ReferencedFunc || !NextDecl) &&
2574 "Only one of these should be filled");
2577 Decl *NextLineDecl =
nullptr;
2583 return NextDecl.
get();
2587 StartLoc, DirLoc, LParenLoc, ReferencedFunc, RParenLoc, Clauses, EndLoc)};
2595 assert((!ReferencedFunc || !NextStmt) &&
2596 "Only one of these should be filled");
2599 Decl *NextLineDecl =
nullptr;
2602 NextLineDecl = DS->getSingleDecl();
2609 RParenLoc, Clauses, EndLoc)};
2613OpenACCRoutineDeclAttr *
2615 OpenACCRoutineDeclAttr *
New =
2616 OpenACCRoutineDeclAttr::Create(
getASTContext(), Old.getLocation());
2619 New->Clauses = Old.Clauses;
2633enum class InitKind {
Invalid,
Zero, One, AllOnes, Least, Largest };
2636 case InitKind::Invalid:
2637 llvm_unreachable(
"invalid init kind");
2638 case InitKind::Zero:
2639 return llvm::APFloat::getZero(Context.getFloatTypeSemantics(Ty));
2641 return llvm::APFloat::getOne(Context.getFloatTypeSemantics(Ty));
2642 case InitKind::AllOnes:
2643 return llvm::APFloat::getAllOnesValue(Context.getFloatTypeSemantics(Ty));
2644 case InitKind::Least:
2645 return llvm::APFloat::getLargest(Context.getFloatTypeSemantics(Ty),
2647 case InitKind::Largest:
2648 return llvm::APFloat::getLargest(Context.getFloatTypeSemantics(Ty));
2650 llvm_unreachable(
"unknown init kind");
2653llvm::APInt getInitIntValue(ASTContext &Context, InitKind IK, QualType Ty) {
2655 case InitKind::Invalid:
2656 llvm_unreachable(
"invalid init kind");
2657 case InitKind::Zero:
2661 case InitKind::AllOnes:
2662 return llvm::APInt::getAllOnes(Context.
getIntWidth(Ty));
2663 case InitKind::Least:
2665 return llvm::APInt::getSignedMinValue(Context.
getIntWidth(Ty));
2666 return llvm::APInt::getMinValue(Context.
getIntWidth(Ty));
2667 case InitKind::Largest:
2669 return llvm::APInt::getSignedMaxValue(Context.
getIntWidth(Ty));
2670 return llvm::APInt::getMaxValue(Context.
getIntWidth(Ty));
2672 llvm_unreachable(
"unknown init kind");
2677Expr *GenerateReductionInitRecipeExpr(ASTContext &Context,
2678 SourceRange ExprRange, QualType Ty,
2680 if (IK == InitKind::Invalid)
2683 if (IK == InitKind::Zero) {
2685 new (Context) InitListExpr(Context, ExprRange.
getBegin(), {},
2686 ExprRange.
getEnd(),
false);
2692 llvm::SmallVector<Expr *> Exprs;
2695 for (
auto *F : RD->fields()) {
2696 if (Expr *NewExpr = GenerateReductionInitRecipeExpr(Context, ExprRange,
2698 Exprs.push_back(NewExpr);
2703 for (uint64_t Idx = 0; Idx < AT->getZExtSize(); ++Idx) {
2704 if (Expr *NewExpr = GenerateReductionInitRecipeExpr(
2705 Context, ExprRange, AT->getElementType(), IK))
2706 Exprs.push_back(NewExpr);
2724 if (
const auto *Cplx = Ty->
getAs<ComplexType>()) {
2729 QualType EltTy = Cplx->getElementType();
2732 Context, getInitFloatValue(Context, InitKind::Zero, EltTy),
2733 true, EltTy, ExprRange.
getBegin()));
2735 Context, getInitFloatValue(Context, InitKind::Zero, EltTy),
2736 true, EltTy, ExprRange.
getBegin()));
2739 Context, getInitIntValue(Context, InitKind::Zero, EltTy), EltTy,
2742 Context, getInitIntValue(Context, InitKind::Zero, EltTy), EltTy,
2752 (IK == InitKind::One ||
2753 IK == InitKind::AllOnes ||
2754 IK == InitKind::Largest),
2757 Exprs.push_back(
new (Context)
2758 CXXNullPtrLiteralExpr(Ty, ExprRange.
getBegin()));
2761 Context, getInitIntValue(Context, IK, Ty), Ty, ExprRange.
getBegin()));
2766 new (Context) InitListExpr(Context, ExprRange.
getBegin(), Exprs,
2767 ExprRange.
getEnd(),
false);
2772VarDecl *CreateAllocaDecl(ASTContext &Ctx, DeclContext *DC,
2773 SourceLocation BeginLoc, IdentifierInfo *VarName,
2775 auto *VD =
VarDecl::Create(Ctx, DC, BeginLoc, BeginLoc, VarName, VarTy,
2781ExprResult FinishValueInit(Sema &S, InitializedEntity &Entity,
2782 SourceLocation Loc, QualType VarTy, Expr *InitExpr) {
2786 InitializationKind
Kind =
2788 InitializationSequence InitSeq(S, Entity, Kind, InitExpr,
2792 return InitSeq.Perform(S, Entity, Kind, InitExpr, &VarTy);
2807 if (
const auto *ASE =
2809 VarTy = ASE->getElementType();
2811 VarDecl *AllocaDecl = CreateAllocaDecl(
2813 &
getASTContext().Idents.get(
"openacc.private.init"), VarTy);
2824 if (
Init.isUsable()) {
2843 if (
const auto *ASE =
2845 VarTy = ASE->getElementType();
2847 VarDecl *AllocaDecl = CreateAllocaDecl(
2849 &
getASTContext().Idents.get(
"openacc.firstprivate.init"), VarTy);
2851 VarDecl *Temporary = CreateAllocaDecl(
2872 if (
Init.isUsable()) {
2886 CK_ArrayToPointerDecay, TemporaryDRE,
nullptr,
2889 for (std::size_t I = 0; I < ArrTy->getLimitedSize(); ++I) {
2912 CopySeq.
Perform(
SemaRef.SemaRef, CopyEntity, CopyKind, Subscript);
2913 Args.push_back(ElemRes.
get());
2926 if (
Init.isUsable()) {
2945 if (
const auto *ASE =
2947 VarTy = ASE->getElementType();
2954 if (CreateReductionCombinerRecipe(VarExpr->
getBeginLoc(), ReductionOperator,
2955 VarTy, CombinerRecipes))
2958 VarDecl *AllocaDecl = CreateAllocaDecl(
2960 &
getASTContext().Idents.get(
"openacc.reduction.init"), VarTy);
2965 InitKind IK = InitKind::Invalid;
2966 switch (ReductionOperator) {
2971 IK = InitKind::Invalid;
2974 IK = InitKind::Least;
2977 IK = InitKind::Largest;
2980 IK = InitKind::AllOnes;
2990 IK = InitKind::Zero;
2994 Expr *InitExpr = GenerateReductionInitRecipeExpr(
3002 if (
Init.isUsable()) {
3010bool SemaOpenACC::CreateReductionCombinerRecipe(
3022 switch (ReductionOperator) {
3027 CombinerRecipes.push_back({
nullptr,
nullptr,
nullptr});
3030 BinOp = BinaryOperatorKind::BO_AddAssign;
3033 BinOp = BinaryOperatorKind::BO_MulAssign;
3036 BinOp = BinaryOperatorKind::BO_AndAssign;
3039 BinOp = BinaryOperatorKind::BO_OrAssign;
3042 BinOp = BinaryOperatorKind::BO_XorAssign;
3047 BinOp = BinaryOperatorKind::BO_LT;
3050 BinOp = BinaryOperatorKind::BO_LAnd;
3053 BinOp = BinaryOperatorKind::BO_LOr;
3060 VarTy = AT->getElementType();
3062 assert(!VarTy->
isArrayType() &&
"Only 1 level of array allowed");
3064 enum class CombinerFailureKind {
3071 auto genCombiner = [&,
this](DeclRefExpr *LHSDRE, DeclRefExpr *RHSDRE)
3072 -> std::pair<ExprResult, CombinerFailureKind> {
3074 SemaRef.BuildBinOp(
SemaRef.getCurScope(), Loc, BinOp, LHSDRE, RHSDRE,
3076 switch (ReductionOperator) {
3084 return {BinOpRes, BinOpRes.
isUsable() ? CombinerFailureKind::None
3085 : CombinerFailureKind::BinOp};
3094 return {BinOpRes, CombinerFailureKind::BinOp};
3100 CondRes =
SemaRef.ActOnConditionalOp(Loc, Loc, BinOpRes.
get(), LHSDRE,
3103 CondRes =
SemaRef.ActOnConditionalOp(Loc, Loc, BinOpRes.
get(), RHSDRE,
3107 return {CondRes, CombinerFailureKind::Conditional};
3111 BinaryOperatorKind::BO_Assign,
3112 LHSDRE, CondRes.
get(),
3115 ? CombinerFailureKind::None
3116 : CombinerFailureKind::Assignment};
3123 return {BinOpRes, CombinerFailureKind::BinOp};
3127 BinaryOperatorKind::BO_Assign,
3128 LHSDRE, BinOpRes.
get(),
3131 ? CombinerFailureKind::None
3132 : CombinerFailureKind::Assignment};
3135 llvm_unreachable(
"Invalid should have been caught above");
3137 llvm_unreachable(
"Unhandled case");
3140 auto tryCombiner = [&,
this](DeclRefExpr *LHSDRE, DeclRefExpr *RHSDRE,
3144 Sema::TentativeAnalysisScope Trap{
SemaRef};
3145 return genCombiner(LHSDRE, RHSDRE);
3147 return genCombiner(LHSDRE, RHSDRE);
3150 struct CombinerAttemptTy {
3151 CombinerFailureKind FailKind;
3153 DeclRefExpr *LHSDRE;
3155 DeclRefExpr *RHSDRE;
3159 auto formCombiner = [&,
this](QualType Ty) -> CombinerAttemptTy {
3160 VarDecl *LHSDecl = CreateAllocaDecl(
3162 &
getASTContext().Idents.get(
"openacc.reduction.combiner.lhs"), Ty);
3164 getASTContext(), NestedNameSpecifierLoc{}, SourceLocation{}, LHSDecl,
3166 DeclarationNameInfo{DeclarationName{LHSDecl->
getDeclName()},
3169 VarDecl *RHSDecl = CreateAllocaDecl(
3171 &
getASTContext().Idents.get(
"openacc.reduction.combiner.lhs"), Ty);
3173 getASTContext(), NestedNameSpecifierLoc{}, SourceLocation{}, RHSDecl,
3175 DeclarationNameInfo{DeclarationName{RHSDecl->getDeclName()},
3176 RHSDecl->getBeginLoc()},
3179 std::pair<ExprResult, CombinerFailureKind> BinOpResult =
3180 tryCombiner(LHSDRE, RHSDRE,
true);
3182 return {BinOpResult.second, LHSDecl, LHSDRE, RHSDecl, RHSDRE,
3183 BinOpResult.first.get()};
3186 CombinerAttemptTy TopLevelCombinerInfo = formCombiner(VarTy);
3188 if (TopLevelCombinerInfo.Op) {
3189 if (!TopLevelCombinerInfo.Op->containsErrors() &&
3190 TopLevelCombinerInfo.Op->isInstantiationDependent()) {
3193 CombinerRecipes.push_back({
nullptr,
nullptr,
nullptr});
3195 }
else if (!TopLevelCombinerInfo.Op->containsErrors()) {
3197 CombinerRecipes.push_back({TopLevelCombinerInfo.LHS,
3198 TopLevelCombinerInfo.RHS,
3199 TopLevelCombinerInfo.Op});
3204 auto EmitFailureNote = [&](CombinerFailureKind CFK) {
3205 if (CFK == CombinerFailureKind::BinOp)
3206 return Diag(Loc, diag::note_acc_reduction_combiner_forming)
3208 return Diag(Loc, diag::note_acc_reduction_combiner_forming) << CFK;
3216 Diag(Loc, diag::err_acc_reduction_recipe_no_op) << VarTy;
3217 EmitFailureNote(TopLevelCombinerInfo.FailKind);
3218 tryCombiner(TopLevelCombinerInfo.LHSDRE, TopLevelCombinerInfo.RHSDRE,
3223 for (
const FieldDecl *FD : RD->
fields()) {
3224 CombinerAttemptTy FieldCombinerInfo = formCombiner(FD->getType());
3226 if (!FieldCombinerInfo.Op || FieldCombinerInfo.Op->containsErrors()) {
3227 Diag(Loc, diag::err_acc_reduction_recipe_no_op) << FD->getType();
3228 Diag(FD->getBeginLoc(), diag::note_acc_reduction_recipe_noop_field) << RD;
3229 EmitFailureNote(FieldCombinerInfo.FailKind);
3230 tryCombiner(FieldCombinerInfo.LHSDRE, FieldCombinerInfo.RHSDRE,
3235 if (FieldCombinerInfo.Op->isInstantiationDependent()) {
3238 CombinerRecipes.push_back({
nullptr,
nullptr,
nullptr});
3240 CombinerRecipes.push_back(
3241 {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.
void markUsed(ASTContext &C)
Mark the declaration used, in the sense of odr-use.
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() const
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 isNullPtrType() const
bool isRecordType() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
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.
Top level wrappers for InstallAPI frontend operations.
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)
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()