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() &&
1002 LHS.getBitWidth() == RHS.getBitWidth())
1006 unsigned Width = std::max(LHS.getBitWidth(), RHS.getBitWidth()) + 1;
1007 return llvm::APSInt(LHS.sext(Width) + RHS.sext(Width),
true);
1012 if (BaseSize.has_value() && LowerBoundValue.has_value() &&
1013 LengthValue.has_value() &&
1014 llvm::APSInt::compareValues(AddAPSInt(*LowerBoundValue, *LengthValue),
1017 diag::err_acc_subarray_base_plus_length_out_of_range)
1022 LowerBoundValue.reset();
1023 LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
1024 LengthValue.reset();
1025 Length = GetRecovery(Length, Length->getType());
1029 QualType ArrayExprTy = Context.ArraySectionTy;
1030 if (
Base->isTypeDependent() ||
1032 (Length && Length->isTypeDependent()))
1033 ArrayExprTy = Context.DependentTy;
1035 return new (Context)
1044 if (!LoopInfo.TopLevelLoopSeen)
1047 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
1048 Diag(WhileLoc, diag::err_acc_invalid_in_loop)
1049 << 1 << CollapseInfo.DirectiveKind
1051 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
1052 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1053 diag::note_acc_active_clause_here)
1058 CollapseInfo.CurCollapseCount = std::nullopt;
1061 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
1062 Diag(WhileLoc, diag::err_acc_invalid_in_loop)
1063 << 1 << TileInfo.DirectiveKind
1065 assert(TileInfo.ActiveTile &&
"tile count without object?");
1066 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
1071 TileInfo.CurTileCount = std::nullopt;
1079 if (!LoopInfo.TopLevelLoopSeen)
1082 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
1083 Diag(DoLoc, diag::err_acc_invalid_in_loop)
1084 << 2 << CollapseInfo.DirectiveKind
1086 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
1087 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1088 diag::note_acc_active_clause_here)
1093 CollapseInfo.CurCollapseCount = std::nullopt;
1096 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
1097 Diag(DoLoc, diag::err_acc_invalid_in_loop)
1099 assert(TileInfo.ActiveTile &&
"tile count without object?");
1100 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
1105 TileInfo.CurTileCount = std::nullopt;
1110 ForStmtBeginChecker &
C) {
1111 assert(
getLangOpts().OpenACC &&
"Check enabled when not OpenACC?");
1114 LoopInfo.TopLevelLoopSeen =
true;
1116 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
1125 if (LoopInfo.CurLevelHasLoopAlready) {
1126 Diag(ForLoc, diag::err_acc_clause_multiple_loops)
1128 assert(CollapseInfo.ActiveCollapse &&
"No collapse object?");
1130 diag::note_acc_active_clause_here)
1133 --(*CollapseInfo.CurCollapseCount);
1137 if (*CollapseInfo.CurCollapseCount == 0)
1138 CollapseInfo.CollapseDepthSatisfied =
true;
1142 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
1146 if (LoopInfo.CurLevelHasLoopAlready) {
1147 Diag(ForLoc, diag::err_acc_clause_multiple_loops)
1149 assert(TileInfo.ActiveTile &&
"No tile object?");
1150 Diag(TileInfo.ActiveTile->getBeginLoc(),
1151 diag::note_acc_active_clause_here)
1154 TileInfo.CurTileCount = *TileInfo.CurTileCount - 1;
1157 if (*TileInfo.CurTileCount == 0)
1158 TileInfo.TileDepthSatisfied =
true;
1164 LoopInfo.CurLevelHasLoopAlready =
false;
1168bool isValidLoopVariableType(QualType LoopVarTy) {
1191 for (
const auto *TD :
1192 llvm::make_filter_range(RD->decls(), llvm::IsaPred<TypedefNameDecl>)) {
1195 if (TDND->getName() !=
"iterator_category")
1199 if (TDND->getUnderlyingType().isNull())
1202 const CXXRecordDecl *ItrCategoryDecl =
1203 TDND->getUnderlyingType()->getAsCXXRecordDecl();
1206 if (!ItrCategoryDecl)
1209 auto IsRandomAccessIteratorTag = [](
const CXXRecordDecl *RD) {
1210 if (RD->getName() !=
"random_access_iterator_tag")
1213 return RD->getEnclosingNamespaceContext()->isStdNamespace();
1216 if (IsRandomAccessIteratorTag(ItrCategoryDecl))
1221 for (CXXBaseSpecifier BS : ItrCategoryDecl->
bases())
1222 if (IsRandomAccessIteratorTag(BS.getType()->getAsCXXRecordDecl()))
1231const ValueDecl *getDeclFromExpr(
const Expr *E) {
1233 if (
const auto *FE = dyn_cast<FullExpr>(E))
1234 E = FE->getSubExpr();
1240 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
1241 return DRE->getDecl();
1243 if (
const auto *ME = dyn_cast<MemberExpr>(E))
1245 return ME->getMemberDecl();
1251void SemaOpenACC::ForStmtBeginChecker::checkRangeFor() {
1252 const RangeForInfo &RFI = std::get<RangeForInfo>(Info);
1254 if (RFI.Uninstantiated == RFI.CurrentVersion)
1257 const DeclStmt *UninstRangeStmt =
1258 IsInstantiation ? RFI.Uninstantiated->getBeginStmt() :
nullptr;
1259 const DeclStmt *RangeStmt = RFI.CurrentVersion->getBeginStmt();
1263 if (UninstRangeStmt) {
1264 const ValueDecl *InitVar =
1268 if (!isValidLoopVariableType(VarType))
1278 if (!isValidLoopVariableType(VarType)) {
1280 <<
SemaRef.LoopWithoutSeqInfo.Kind << VarType;
1282 diag::note_acc_construct_here)
1283 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1288bool SemaOpenACC::ForStmtBeginChecker::checkForInit(
const Stmt *InitStmt,
1289 const ValueDecl *&InitVar,
1294 SemaRef.Diag(ForLoc, diag::err_acc_loop_variable)
1295 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1297 diag::note_acc_construct_here)
1298 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1302 auto DiagLoopVar = [
this,
Diag, InitStmt]() {
1305 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1307 diag::note_acc_construct_here)
1308 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1313 if (
const auto *ExprTemp = dyn_cast<ExprWithCleanups>(InitStmt))
1314 InitStmt = ExprTemp->getSubExpr();
1315 if (
const auto *E = dyn_cast<Expr>(InitStmt))
1319 if (
const auto *BO = dyn_cast<BinaryOperator>(InitStmt)) {
1322 if (!BO->isAssignmentOp())
1323 return DiagLoopVar();
1325 const Expr *LHS = BO->getLHS()->IgnoreParenImpCasts();
1326 if (
const auto *DRE = dyn_cast<DeclRefExpr>(LHS))
1327 InitVar = DRE->getDecl();
1328 }
else if (
const auto *DS = dyn_cast<DeclStmt>(InitStmt)) {
1330 if (!DS->isSingleDecl())
1331 return DiagLoopVar();
1332 InitVar = dyn_cast<ValueDecl>(DS->getSingleDecl());
1337 return DiagLoopVar();
1342 return DiagLoopVar();
1344 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(InitStmt)) {
1346 if (CE->getOperator() != OO_Equal)
1347 return DiagLoopVar();
1348 if (CE->getNumArgs() < 1)
1349 return DiagLoopVar();
1352 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
1353 InitVar = DRE->getDecl();
1354 }
else if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
1356 InitVar = ME->getMemberDecl();
1362 return DiagLoopVar();
1368 if (!isValidLoopVariableType(VarType)) {
1371 <<
SemaRef.LoopWithoutSeqInfo.Kind << VarType;
1373 diag::note_acc_construct_here)
1374 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1382bool SemaOpenACC::ForStmtBeginChecker::checkForCond(
const Stmt *CondStmt,
1383 const ValueDecl *InitVar,
1388 SemaRef.Diag(ForLoc, diag::err_acc_loop_terminating_condition)
1389 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1391 diag::note_acc_construct_here)
1392 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1397 auto DiagCondVar = [
this,
Diag, CondStmt] {
1400 diag::err_acc_loop_terminating_condition)
1401 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1403 diag::note_acc_construct_here)
1404 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1409 if (
const auto *ExprTemp = dyn_cast<ExprWithCleanups>(CondStmt))
1410 CondStmt = ExprTemp->getSubExpr();
1411 if (
const auto *E = dyn_cast<Expr>(CondStmt))
1414 const ValueDecl *CondVar =
nullptr;
1415 if (
const auto *BO = dyn_cast<BinaryOperator>(CondStmt)) {
1416 switch (BO->getOpcode()) {
1418 return DiagCondVar();
1431 CondVar = getDeclFromExpr(BO->getLHS());
1434 CondVar = getDeclFromExpr(BO->getRHS());
1436 }
else if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(CondStmt)) {
1439 if (!CE->isComparisonOp() || CE->getOperator() == OO_Spaceship)
1440 return DiagCondVar();
1442 if (CE->getNumArgs() < 1)
1447 CondVar = getDeclFromExpr(CE->getArg(0));
1451 CE->getNumArgs() > 1))
1452 CondVar = getDeclFromExpr(CE->getArg(1));
1454 return DiagCondVar();
1458 return DiagCondVar();
1463 return DiagCondVar();
1472bool isValidForIncRHSAssign(
const ValueDecl *InitVar,
const Expr *RHS) {
1474 auto isValid = [](
const ValueDecl *InitVar,
const Expr *InnerLHS,
1475 const Expr *InnerRHS,
bool IsAddition) {
1477 if (!InnerLHS->getType()->isIntegerType() &&
1478 !InnerRHS->getType()->isIntegerType())
1486 const ValueDecl *LHSDecl = getDeclFromExpr(InnerLHS);
1487 const ValueDecl *RHSDecl = getDeclFromExpr(InnerRHS);
1489 if (!LHSDecl || !RHSDecl)
1505 if (
const auto *BO = dyn_cast<BinaryOperator>(RHS)) {
1507 if (OpC != BO_Add && OpC != BO_Sub)
1509 return isValid(InitVar, BO->getLHS(), BO->getRHS(), OpC == BO_Add);
1510 }
else if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
1512 if (Op != OO_Plus && Op != OO_Minus)
1517 if (CE->getNumArgs() != 2)
1519 return isValid(InitVar, CE->getArg(0), CE->getArg(1), Op == OO_Plus);
1526bool SemaOpenACC::ForStmtBeginChecker::checkForInc(
const Stmt *IncStmt,
1527 const ValueDecl *InitVar,
1531 SemaRef.Diag(ForLoc, diag::err_acc_loop_not_monotonic)
1532 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1534 diag::note_acc_construct_here)
1535 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1539 auto DiagIncVar = [
this,
Diag, IncStmt] {
1542 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1544 diag::note_acc_construct_here)
1545 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1550 if (
const auto *ExprTemp = dyn_cast<ExprWithCleanups>(IncStmt))
1551 IncStmt = ExprTemp->getSubExpr();
1552 if (
const auto *E = dyn_cast<Expr>(IncStmt))
1555 const ValueDecl *IncVar =
nullptr;
1557 if (
const auto *UO = dyn_cast<UnaryOperator>(IncStmt)) {
1559 if (!UO->isIncrementDecrementOp())
1560 return DiagIncVar();
1561 IncVar = getDeclFromExpr(UO->getSubExpr());
1562 }
else if (
const auto *BO = dyn_cast<BinaryOperator>(IncStmt)) {
1563 switch (BO->getOpcode()) {
1565 return DiagIncVar();
1572 if (!isValidForIncRHSAssign(InitVar, BO->getRHS()))
1573 return DiagIncVar();
1576 IncVar = getDeclFromExpr(BO->getLHS());
1577 }
else if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(IncStmt)) {
1578 if (CE->getNumArgs() < 1)
1579 return DiagIncVar();
1581 switch (CE->getOperator()) {
1583 return DiagIncVar();
1592 if (CE->getNumArgs() != 2 ||
1593 !isValidForIncRHSAssign(InitVar, CE->getArg(1)))
1594 return DiagIncVar();
1598 IncVar = getDeclFromExpr(CE->getArg(0));
1600 return DiagIncVar();
1604 return DiagIncVar();
1610 return DiagIncVar();
1615void SemaOpenACC::ForStmtBeginChecker::checkFor() {
1616 const CheckForInfo &CFI = std::get<CheckForInfo>(Info);
1618 if (!IsInstantiation) {
1621 const ValueDecl *CurInitVar =
nullptr;
1622 checkForInit(CFI.Current.Init, CurInitVar,
true);
1623 checkForCond(CFI.Current.Condition, CurInitVar,
true);
1624 checkForInc(CFI.Current.Increment, CurInitVar,
true);
1626 const ValueDecl *UninstInitVar =
nullptr;
1630 bool UninstInitFailed =
1631 checkForInit(CFI.Uninst.Init, UninstInitVar,
false);
1637 auto InitChanged = [=]() {
1638 if (CFI.Uninst.Init == CFI.Current.Init)
1644 if (
const auto *DS = dyn_cast<DeclStmt>(CFI.Uninst.Init))
1645 if (
const VarDecl *VD = dyn_cast_if_present<VarDecl>(
1646 DS->isSingleDecl() ? DS->getSingleDecl() :
nullptr))
1647 OldVDTy = VD->getType();
1648 if (
const auto *DS = dyn_cast<DeclStmt>(CFI.Current.Init))
1649 if (
const VarDecl *VD = dyn_cast_if_present<VarDecl>(
1650 DS->isSingleDecl() ? DS->getSingleDecl() :
nullptr))
1651 NewVDTy = VD->getType();
1662 bool ShouldDiagNewInit = !UninstInitFailed && InitChanged();
1663 const ValueDecl *CurInitVar =
nullptr;
1664 checkForInit(CFI.Current.Init, CurInitVar, ShouldDiagNewInit);
1668 if (CFI.Uninst.Condition != CFI.Current.Condition &&
1669 !checkForCond(CFI.Uninst.Condition, UninstInitVar,
false))
1670 checkForCond(CFI.Current.Condition, CurInitVar,
true);
1671 if (CFI.Uninst.Increment != CFI.Current.Increment &&
1672 !checkForInc(CFI.Uninst.Increment, UninstInitVar,
false))
1673 checkForInc(CFI.Current.Increment, CurInitVar,
true);
1677void SemaOpenACC::ForStmtBeginChecker::check() {
1688 AlreadyChecked =
true;
1705 if (std::holds_alternative<RangeForInfo>(Info))
1706 return checkRangeFor();
1713 const Stmt *Second,
const Stmt *OldThird,
1714 const Stmt *Third) {
1718 ForStmtBeginChecker FSBC{*
this, ForLoc, OldFirst, OldSecond,
1719 OldThird,
First, Second, Third};
1722 if (!LoopInfo.TopLevelLoopSeen) {
1726 ForStmtBeginHelper(ForLoc, FSBC);
1730 const Stmt *Second,
const Stmt *Third) {
1734 ForStmtBeginChecker FSBC{*
this, ForLoc,
First, Second, Third};
1738 if (!LoopInfo.TopLevelLoopSeen)
1741 ForStmtBeginHelper(ForLoc, FSBC);
1745 const Stmt *OldRangeFor,
1746 const Stmt *RangeFor) {
1747 if (!
getLangOpts().OpenACC || OldRangeFor ==
nullptr || RangeFor ==
nullptr)
1750 ForStmtBeginChecker FSBC{*
this, ForLoc,
1751 cast_if_present<CXXForRangeStmt>(OldRangeFor),
1752 cast_if_present<CXXForRangeStmt>(RangeFor)};
1755 if (!LoopInfo.TopLevelLoopSeen) {
1758 ForStmtBeginHelper(ForLoc, FSBC);
1762 const Stmt *RangeFor) {
1763 if (!
getLangOpts().OpenACC || RangeFor ==
nullptr)
1766 ForStmtBeginChecker FSBC = {*
this, ForLoc,
1767 cast_if_present<CXXForRangeStmt>(RangeFor)};
1771 if (!LoopInfo.TopLevelLoopSeen)
1774 ForStmtBeginHelper(ForLoc, FSBC);
1794 if (
const auto *CS = dyn_cast<CompoundStmt>(CurStmt)) {
1795 for (
const auto *ChildStmt : CS->children()) {
1796 SourceLocation ChildStmtLoc = FindInterveningCodeInLoop(ChildStmt);
1798 return ChildStmtLoc;
1801 return SourceLocation{};
1812 LoopInfo.CurLevelHasLoopAlready =
true;
1817 bool IsActiveCollapse = CollapseInfo.CurCollapseCount &&
1818 *CollapseInfo.CurCollapseCount > 0 &&
1819 !CollapseInfo.ActiveCollapse->hasForce();
1820 bool IsActiveTile = TileInfo.CurTileCount && *TileInfo.CurTileCount > 0;
1822 if (IsActiveCollapse || IsActiveTile) {
1825 if (OtherStmtLoc.
isValid() && IsActiveCollapse) {
1826 Diag(OtherStmtLoc, diag::err_acc_intervening_code)
1828 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1829 diag::note_acc_active_clause_here)
1833 if (OtherStmtLoc.
isValid() && IsActiveTile) {
1834 Diag(OtherStmtLoc, diag::err_acc_intervening_code)
1836 Diag(TileInfo.ActiveTile->getBeginLoc(),
1837 diag::note_acc_active_clause_here)
1857 }
else if (
auto *DRE = dyn_cast<DeclRefExpr>(RoutineName)) {
1858 ValueDecl *VD = DRE->getDecl();
1860 if (
auto *FD = dyn_cast<FunctionDecl>(VD))
1864 if (
auto *VarD = dyn_cast<VarDecl>(VD)) {
1865 QualType VarDTy = VarD->getType();
1868 if (RD->isGenericLambda())
1871 return RD->getLambdaCallOperator();
1887 assert(RoutineName &&
"Routine name cannot be null here");
1898 }
else if (
const auto *DRE = dyn_cast<DeclRefExpr>(RoutineName)) {
1905 if (
const auto *VarD = dyn_cast<VarDecl>(VD)) {
1909 if (RD->isGenericLambda()) {
1949 auto *ContextDecl = dyn_cast<FunctionDecl>(
getCurContext());
1957 for (
const auto *A : ContextDecl->attrs()) {
1960 Diag(A->getLocation(), diag::note_acc_construct_here)
1966 MagicStaticLocs.insert({ContextDecl->getCanonicalDecl(), VD->
getBeginLoc()});
1968void SemaOpenACC::CheckLastRoutineDeclNameConflict(
const NamedDecl *ND) {
1977 if (!LastRoutineDecl)
2010 if (NDLine - LastLine > 1)
2018 diag::warn_acc_confusing_routine_name);
2034 if (!RD || !RD->isLambda())
2037 CheckLastRoutineDeclNameConflict(VD);
2043 CheckLastRoutineDeclNameConflict(FD);
2055 SemaRef.DiscardCleanupsInEvaluationContext();
2056 SemaRef.PopExpressionEvaluationContext();
2063 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
2064 Diag(StartLoc, diag::err_acc_invalid_in_loop)
2065 << 0 << CollapseInfo.DirectiveKind
2067 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
2068 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
2069 diag::note_acc_active_clause_here)
2072 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
2073 Diag(StartLoc, diag::err_acc_invalid_in_loop)
2074 << 0 << TileInfo.DirectiveKind
2076 assert(TileInfo.ActiveTile &&
"Tile count without object?");
2077 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
2081 if (DiagnoseRequiredClauses(K, StartLoc, Clauses))
2083 return diagnoseConstructAppertainment(*
this, K, StartLoc,
true);
2098 return OpenACCComputeConstruct::Create(
2100 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2107 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2111 getASTContext(), ActiveComputeConstructInfo.Kind, StartLoc, DirLoc,
2112 EndLoc, Clauses, AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2117 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2130 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2134 getASTContext(), StartLoc, DirLoc, LParenLoc, Exprs.front(), MiscLoc,
2135 Exprs.drop_front(), RParenLoc, EndLoc, Clauses);
2155 getASTContext(), StartLoc, DirLoc, AtomicKind, EndLoc, Clauses,
2156 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2159 assert(Clauses.empty() &&
"Cache doesn't allow clauses");
2161 LParenLoc, MiscLoc, Exprs, RParenLoc,
2165 llvm_unreachable(
"routine shouldn't handled here");
2170 RParenLoc, EndLoc, Clauses);
2175 llvm_unreachable(
"Unhandled case in directive handling?");
2184 llvm_unreachable(
"Unimplemented associated statement application");
2193 "these don't have associated statements, so shouldn't get here");
2221 Diag(DirectiveLoc, diag::note_acc_construct_here) << K;
2225 if (!CollapseInfo.CollapseDepthSatisfied || !TileInfo.TileDepthSatisfied) {
2226 if (!CollapseInfo.CollapseDepthSatisfied) {
2227 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
2229 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
2230 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
2231 diag::note_acc_active_clause_here)
2235 if (!TileInfo.TileDepthSatisfied) {
2236 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
2238 assert(TileInfo.ActiveTile &&
"Collapse count without object?");
2239 Diag(TileInfo.ActiveTile->getBeginLoc(),
2240 diag::note_acc_active_clause_here)
2246 return AssocStmt.
get();
2248 llvm_unreachable(
"Invalid associated statement application");
2256bool CheckValidRoutineGangWorkerVectorSeqClauses(
2268 auto *FirstDeviceType =
2269 llvm::find_if(Clauses, llvm::IsaPred<OpenACCDeviceTypeClause>);
2274 std::find_if(Clauses.begin(), FirstDeviceType, RequiredPred);
2276 if (ClauseItr != FirstDeviceType)
2280 if (FirstDeviceType == Clauses.end())
2281 return SemaRef.
Diag(DirectiveLoc, diag::err_acc_construct_one_clause_of)
2283 <<
"'gang', 'seq', 'vector', or 'worker'";
2287 auto *PrevDeviceType = FirstDeviceType;
2289 while (PrevDeviceType != Clauses.end()) {
2290 auto *NextDeviceType =
2291 std::find_if(std::next(PrevDeviceType), Clauses.end(),
2292 llvm::IsaPred<OpenACCDeviceTypeClause>);
2294 ClauseItr = std::find_if(PrevDeviceType, NextDeviceType, RequiredPred);
2296 if (ClauseItr == NextDeviceType)
2297 return SemaRef.
Diag((*PrevDeviceType)->getBeginLoc(),
2298 diag::err_acc_clause_routine_one_of_in_region);
2300 PrevDeviceType = NextDeviceType;
2313 SemaRef.DiscardCleanupsInEvaluationContext();
2314 SemaRef.PopExpressionEvaluationContext();
2316 if (DiagnoseRequiredClauses(K, StartLoc, Clauses))
2319 CheckValidRoutineGangWorkerVectorSeqClauses(*
this, StartLoc, Clauses))
2322 return diagnoseConstructAppertainment(*
this, K, StartLoc,
false);
2335 if (Clauses.empty()) {
2336 Diag(EndLoc, diag::err_acc_declare_required_clauses);
2350 llvm_unreachable(
"routine shouldn't be handled here");
2352 llvm_unreachable(
"unhandled case in directive handling?");
2363 if (
auto *FD = dyn_cast<FunctionDecl>(D))
2367 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
2368 return FTD->getTemplatedDecl();
2370 if (
auto *FD = dyn_cast<FieldDecl>(D)) {
2372 FD->getType().isNull() ?
nullptr : FD->getType()->getAsCXXRecordDecl();
2374 if (RD && RD->isGenericLambda())
2375 return RD->getDependentLambdaCallOperator()->getTemplatedDecl();
2376 if (RD && RD->isLambda())
2377 return RD->getLambdaCallOperator();
2381 if (
auto *VD = dyn_cast<VarDecl>(D)) {
2383 if (!
Init ||
Init->getType().isNull())
2386 const auto *RD =
Init->getType()->getAsCXXRecordDecl();
2387 if (RD && RD->isGenericLambda())
2388 return RD->getDependentLambdaCallOperator()->getTemplatedDecl();
2389 if (RD && RD->isLambda())
2390 return RD->getLambdaCallOperator();
2405 ArrayRef<const OpenACCClause *> Clauses,
2407 OpenACCRoutineDeclAttr *A =
2408 OpenACCRoutineDeclAttr::Create(
SemaRef.getASTContext(), DirLoc);
2409 A->Clauses.assign(Clauses.begin(), Clauses.end());
2417 Decl *NextParsedDecl) {
2419 FunctionDecl *NextParsedFDecl = LegalizeNextParsedDecl(NextParsedDecl);
2421 if (!NextParsedFDecl) {
2423 SemaRef.Diag(DirLoc, diag::err_acc_decl_for_routine);
2431 Itr != MagicStaticLocs.end()) {
2432 Diag(Itr->second, diag::err_acc_magic_static_in_routine);
2433 Diag(DirLoc, diag::note_acc_construct_here)
2439 auto BindItr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCBindClause>);
2440 if (BindItr != Clauses.end()) {
2441 for (
auto *A : NextParsedFDecl->
attrs()) {
2445 if (
auto *RA = dyn_cast<OpenACCRoutineDeclAttr>(A)) {
2447 llvm::find_if(RA->Clauses, llvm::IsaPred<OpenACCBindClause>);
2448 if (OtherBindItr != RA->Clauses.end() &&
2451 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_unnamed_bind);
2452 Diag((*OtherBindItr)->getEndLoc(),
2453 diag::note_acc_previous_clause_here)
2454 << (*BindItr)->getClauseKind();
2465 if (
auto *RA = dyn_cast<OpenACCRoutineAnnotAttr>(A);
2466 RA && RA->getRange().getEnd().isValid()) {
2467 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
2468 Diag(RA->getRange().getEnd(), diag::note_acc_previous_clause_here)
2475 CreateRoutineDeclAttr(*
this, DirLoc, Clauses, NextParsedFDecl);
2486 if ((FD = getFunctionFromRoutineName(FuncRef))) {
2491 Itr != MagicStaticLocs.end()) {
2492 Diag(Itr->second, diag::err_acc_magic_static_in_routine);
2493 Diag(DirLoc, diag::note_acc_construct_here)
2502 auto BindItr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCBindClause>);
2504 if (BindItr != Clauses.end()) {
2505 BindLoc = (*BindItr)->getBeginLoc();
2509 for (
auto *A : FD->
attrs()) {
2510 if (
auto *RA = dyn_cast<OpenACCRoutineDeclAttr>(A)) {
2512 llvm::find_if(RA->Clauses, llvm::IsaPred<OpenACCBindClause>);
2513 if (OtherBindItr != RA->Clauses.end()) {
2514 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
2515 Diag((*OtherBindItr)->getEndLoc(),
2516 diag::note_acc_previous_clause_here)
2517 << (*BindItr)->getClauseKind();
2522 if (
auto *RA = dyn_cast<OpenACCRoutineAnnotAttr>(A);
2523 RA && RA->getRange().getEnd().isValid()) {
2524 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
2525 Diag(RA->getRange().getEnd(), diag::note_acc_previous_clause_here)
2526 << (*BindItr)->getClauseKind();
2534 auto *RAA = OpenACCRoutineAnnotAttr::CreateImplicit(
getASTContext(),
2539 for (
auto *CurFD : FD->
redecls())
2545 RParenLoc, EndLoc, Clauses);
2553 RoutineRefList.emplace_back(FD, LastRoutineDecl);
2555 return LastRoutineDecl;
2559 for (
auto [FD, RoutineDecl] : RoutineRefList)
2560 SemaRef.Consumer.HandleOpenACCRoutineReference(FD, RoutineDecl);
2568 assert((!ReferencedFunc || !NextDecl) &&
2569 "Only one of these should be filled");
2572 Decl *NextLineDecl =
nullptr;
2578 return NextDecl.
get();
2582 StartLoc, DirLoc, LParenLoc, ReferencedFunc, RParenLoc, Clauses, EndLoc)};
2590 assert((!ReferencedFunc || !NextStmt) &&
2591 "Only one of these should be filled");
2594 Decl *NextLineDecl =
nullptr;
2597 NextLineDecl = DS->getSingleDecl();
2604 RParenLoc, Clauses, EndLoc)};
2608OpenACCRoutineDeclAttr *
2610 OpenACCRoutineDeclAttr *
New =
2611 OpenACCRoutineDeclAttr::Create(
getASTContext(), Old.getLocation());
2614 New->Clauses = Old.Clauses;
2628enum class InitKind {
Invalid,
Zero, One, AllOnes, Least, Largest };
2631 case InitKind::Invalid:
2632 llvm_unreachable(
"invalid init kind");
2633 case InitKind::Zero:
2634 return llvm::APFloat::getZero(Context.getFloatTypeSemantics(Ty));
2636 return llvm::APFloat::getOne(Context.getFloatTypeSemantics(Ty));
2637 case InitKind::AllOnes:
2638 return llvm::APFloat::getAllOnesValue(Context.getFloatTypeSemantics(Ty));
2639 case InitKind::Least:
2640 return llvm::APFloat::getLargest(Context.getFloatTypeSemantics(Ty),
2642 case InitKind::Largest:
2643 return llvm::APFloat::getLargest(Context.getFloatTypeSemantics(Ty));
2645 llvm_unreachable(
"unknown init kind");
2648llvm::APInt getInitIntValue(ASTContext &Context, InitKind IK, QualType Ty) {
2650 case InitKind::Invalid:
2651 llvm_unreachable(
"invalid init kind");
2652 case InitKind::Zero:
2656 case InitKind::AllOnes:
2657 return llvm::APInt::getAllOnes(Context.
getIntWidth(Ty));
2658 case InitKind::Least:
2660 return llvm::APInt::getSignedMinValue(Context.
getIntWidth(Ty));
2661 return llvm::APInt::getMinValue(Context.
getIntWidth(Ty));
2662 case InitKind::Largest:
2664 return llvm::APInt::getSignedMaxValue(Context.
getIntWidth(Ty));
2665 return llvm::APInt::getMaxValue(Context.
getIntWidth(Ty));
2667 llvm_unreachable(
"unknown init kind");
2672Expr *GenerateReductionInitRecipeExpr(ASTContext &Context,
2673 SourceRange ExprRange, QualType Ty,
2675 if (IK == InitKind::Invalid)
2678 if (IK == InitKind::Zero) {
2680 new (Context) InitListExpr(Context, ExprRange.
getBegin(), {},
2681 ExprRange.
getEnd(),
false);
2687 llvm::SmallVector<Expr *> Exprs;
2690 for (
auto *F : RD->fields()) {
2691 if (Expr *NewExpr = GenerateReductionInitRecipeExpr(Context, ExprRange,
2693 Exprs.push_back(NewExpr);
2698 for (uint64_t Idx = 0; Idx < AT->getZExtSize(); ++Idx) {
2699 if (Expr *NewExpr = GenerateReductionInitRecipeExpr(
2700 Context, ExprRange, AT->getElementType(), IK))
2701 Exprs.push_back(NewExpr);
2719 if (
const auto *Cplx = Ty->
getAs<ComplexType>()) {
2724 QualType EltTy = Cplx->getElementType();
2727 Context, getInitFloatValue(Context, InitKind::Zero, EltTy),
2728 true, EltTy, ExprRange.
getBegin()));
2730 Context, getInitFloatValue(Context, InitKind::Zero, EltTy),
2731 true, EltTy, ExprRange.
getBegin()));
2734 Context, getInitIntValue(Context, InitKind::Zero, EltTy), EltTy,
2737 Context, getInitIntValue(Context, InitKind::Zero, EltTy), EltTy,
2747 (IK == InitKind::One ||
2748 IK == InitKind::AllOnes ||
2749 IK == InitKind::Largest),
2752 Exprs.push_back(
new (Context)
2753 CXXNullPtrLiteralExpr(Ty, ExprRange.
getBegin()));
2756 Context, getInitIntValue(Context, IK, Ty), Ty, ExprRange.
getBegin()));
2761 new (Context) InitListExpr(Context, ExprRange.
getBegin(), Exprs,
2762 ExprRange.
getEnd(),
false);
2767VarDecl *CreateAllocaDecl(ASTContext &Ctx, DeclContext *DC,
2768 SourceLocation BeginLoc, IdentifierInfo *VarName,
2770 auto *VD =
VarDecl::Create(Ctx, DC, BeginLoc, BeginLoc, VarName, VarTy,
2776ExprResult FinishValueInit(Sema &S, InitializedEntity &Entity,
2777 SourceLocation Loc, QualType VarTy, Expr *InitExpr) {
2781 InitializationKind
Kind =
2783 InitializationSequence InitSeq(S, Entity, Kind, InitExpr,
2787 return InitSeq.Perform(S, Entity, Kind, InitExpr, &VarTy);
2802 if (
const auto *ASE =
2804 VarTy = ASE->getElementType();
2806 VarDecl *AllocaDecl = CreateAllocaDecl(
2808 &
getASTContext().Idents.get(
"openacc.private.init"), VarTy);
2819 if (
Init.isUsable()) {
2838 if (
const auto *ASE =
2840 VarTy = ASE->getElementType();
2842 VarDecl *AllocaDecl = CreateAllocaDecl(
2844 &
getASTContext().Idents.get(
"openacc.firstprivate.init"), VarTy);
2846 VarDecl *Temporary = CreateAllocaDecl(
2867 if (
Init.isUsable()) {
2881 CK_ArrayToPointerDecay, TemporaryDRE,
nullptr,
2884 for (std::size_t I = 0; I < ArrTy->getLimitedSize(); ++I) {
2907 CopySeq.
Perform(
SemaRef.SemaRef, CopyEntity, CopyKind, Subscript);
2908 Args.push_back(ElemRes.
get());
2921 if (
Init.isUsable()) {
2940 if (
const auto *ASE =
2942 VarTy = ASE->getElementType();
2949 if (CreateReductionCombinerRecipe(VarExpr->
getBeginLoc(), ReductionOperator,
2950 VarTy, CombinerRecipes))
2953 VarDecl *AllocaDecl = CreateAllocaDecl(
2955 &
getASTContext().Idents.get(
"openacc.reduction.init"), VarTy);
2960 InitKind IK = InitKind::Invalid;
2961 switch (ReductionOperator) {
2966 IK = InitKind::Invalid;
2969 IK = InitKind::Least;
2972 IK = InitKind::Largest;
2975 IK = InitKind::AllOnes;
2985 IK = InitKind::Zero;
2989 Expr *InitExpr = GenerateReductionInitRecipeExpr(
2997 if (
Init.isUsable()) {
3005bool SemaOpenACC::CreateReductionCombinerRecipe(
3017 switch (ReductionOperator) {
3022 CombinerRecipes.push_back({
nullptr,
nullptr,
nullptr});
3025 BinOp = BinaryOperatorKind::BO_AddAssign;
3028 BinOp = BinaryOperatorKind::BO_MulAssign;
3031 BinOp = BinaryOperatorKind::BO_AndAssign;
3034 BinOp = BinaryOperatorKind::BO_OrAssign;
3037 BinOp = BinaryOperatorKind::BO_XorAssign;
3042 BinOp = BinaryOperatorKind::BO_LT;
3045 BinOp = BinaryOperatorKind::BO_LAnd;
3048 BinOp = BinaryOperatorKind::BO_LOr;
3055 VarTy = AT->getElementType();
3057 assert(!VarTy->
isArrayType() &&
"Only 1 level of array allowed");
3059 enum class CombinerFailureKind {
3066 auto genCombiner = [&,
this](DeclRefExpr *LHSDRE, DeclRefExpr *RHSDRE)
3067 -> std::pair<ExprResult, CombinerFailureKind> {
3069 SemaRef.BuildBinOp(
SemaRef.getCurScope(), Loc, BinOp, LHSDRE, RHSDRE,
3071 switch (ReductionOperator) {
3079 return {BinOpRes, BinOpRes.
isUsable() ? CombinerFailureKind::None
3080 : CombinerFailureKind::BinOp};
3089 return {BinOpRes, CombinerFailureKind::BinOp};
3095 CondRes =
SemaRef.ActOnConditionalOp(Loc, Loc, BinOpRes.
get(), LHSDRE,
3098 CondRes =
SemaRef.ActOnConditionalOp(Loc, Loc, BinOpRes.
get(), RHSDRE,
3102 return {CondRes, CombinerFailureKind::Conditional};
3106 BinaryOperatorKind::BO_Assign,
3107 LHSDRE, CondRes.
get(),
3110 ? CombinerFailureKind::None
3111 : CombinerFailureKind::Assignment};
3118 return {BinOpRes, CombinerFailureKind::BinOp};
3122 BinaryOperatorKind::BO_Assign,
3123 LHSDRE, BinOpRes.
get(),
3126 ? CombinerFailureKind::None
3127 : CombinerFailureKind::Assignment};
3130 llvm_unreachable(
"Invalid should have been caught above");
3132 llvm_unreachable(
"Unhandled case");
3135 auto tryCombiner = [&,
this](DeclRefExpr *LHSDRE, DeclRefExpr *RHSDRE,
3139 Sema::TentativeAnalysisScope Trap{
SemaRef};
3140 return genCombiner(LHSDRE, RHSDRE);
3142 return genCombiner(LHSDRE, RHSDRE);
3145 struct CombinerAttemptTy {
3146 CombinerFailureKind FailKind;
3148 DeclRefExpr *LHSDRE;
3150 DeclRefExpr *RHSDRE;
3154 auto formCombiner = [&,
this](QualType Ty) -> CombinerAttemptTy {
3155 VarDecl *LHSDecl = CreateAllocaDecl(
3157 &
getASTContext().Idents.get(
"openacc.reduction.combiner.lhs"), Ty);
3159 getASTContext(), NestedNameSpecifierLoc{}, SourceLocation{}, LHSDecl,
3161 DeclarationNameInfo{DeclarationName{LHSDecl->
getDeclName()},
3164 VarDecl *RHSDecl = CreateAllocaDecl(
3166 &
getASTContext().Idents.get(
"openacc.reduction.combiner.lhs"), Ty);
3168 getASTContext(), NestedNameSpecifierLoc{}, SourceLocation{}, RHSDecl,
3170 DeclarationNameInfo{DeclarationName{RHSDecl->getDeclName()},
3171 RHSDecl->getBeginLoc()},
3174 std::pair<ExprResult, CombinerFailureKind> BinOpResult =
3175 tryCombiner(LHSDRE, RHSDRE,
true);
3177 return {BinOpResult.second, LHSDecl, LHSDRE, RHSDecl, RHSDRE,
3178 BinOpResult.first.get()};
3181 CombinerAttemptTy TopLevelCombinerInfo = formCombiner(VarTy);
3183 if (TopLevelCombinerInfo.Op) {
3184 if (!TopLevelCombinerInfo.Op->containsErrors() &&
3185 TopLevelCombinerInfo.Op->isInstantiationDependent()) {
3188 CombinerRecipes.push_back({
nullptr,
nullptr,
nullptr});
3190 }
else if (!TopLevelCombinerInfo.Op->containsErrors()) {
3192 CombinerRecipes.push_back({TopLevelCombinerInfo.LHS,
3193 TopLevelCombinerInfo.RHS,
3194 TopLevelCombinerInfo.Op});
3199 auto EmitFailureNote = [&](CombinerFailureKind CFK) {
3200 if (CFK == CombinerFailureKind::BinOp)
3201 return Diag(Loc, diag::note_acc_reduction_combiner_forming)
3203 return Diag(Loc, diag::note_acc_reduction_combiner_forming) << CFK;
3211 Diag(Loc, diag::err_acc_reduction_recipe_no_op) << VarTy;
3212 EmitFailureNote(TopLevelCombinerInfo.FailKind);
3213 tryCombiner(TopLevelCombinerInfo.LHSDRE, TopLevelCombinerInfo.RHSDRE,
3218 for (
const FieldDecl *FD : RD->
fields()) {
3219 CombinerAttemptTy FieldCombinerInfo = formCombiner(FD->getType());
3221 if (!FieldCombinerInfo.Op || FieldCombinerInfo.Op->containsErrors()) {
3222 Diag(Loc, diag::err_acc_reduction_recipe_no_op) << FD->getType();
3223 Diag(FD->getBeginLoc(), diag::note_acc_reduction_recipe_noop_field) << RD;
3224 EmitFailureNote(FieldCombinerInfo.FailKind);
3225 tryCombiner(FieldCombinerInfo.LHSDRE, FieldCombinerInfo.RHSDRE,
3230 if (FieldCombinerInfo.Op->isInstantiationDependent()) {
3233 CombinerRecipes.push_back({
nullptr,
nullptr,
nullptr});
3235 CombinerRecipes.push_back(
3236 {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.
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ Invalid
Invalid Reduction Clause Kind.
bool isa(CodeGen::Address addr)
@ Conditional
A conditional (?:) operator.
@ OK_Ordinary
An ordinary object is located at an address in memory.
OpenACCClauseKind
Represents the kind of an OpenACC clause.
@ Collapse
'collapse' clause, allowed on 'loop' and Combined constructs.
@ Private
'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...
@ Invalid
Represents an invalid clause, for the purposes of parsing.
@ UseDevice
'use_device' clause, allowed on 'host_data' construct.
@ Reduction
'reduction' clause, allowed on Parallel, Serial, Loop, and the combined constructs.
@ FirstPrivate
'firstprivate' clause, allowed on 'parallel', 'serial', 'parallel loop', and 'serial loop' constructs...
@ Tile
'tile' clause, allowed on 'loop' and Combined constructs.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Result
The result type of a method or function.
const FunctionProtoType * T
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
U cast(CodeGen::Address addr)
@ None
The alignment was not explicit in code.
ActionResult< Expr * > ExprResult
ActionResult< Stmt * > StmtResult
@ NOUR_None
This is an odr-use.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
static OpenACCFirstPrivateRecipe Empty()
static OpenACCPrivateRecipe Empty()
static OpenACCReductionRecipeWithStorage Empty()