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();
1350 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
1351 InitVar = DRE->getDecl();
1352 }
else if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
1354 InitVar = ME->getMemberDecl();
1360 return DiagLoopVar();
1366 if (!isValidLoopVariableType(VarType)) {
1369 <<
SemaRef.LoopWithoutSeqInfo.Kind << VarType;
1371 diag::note_acc_construct_here)
1372 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1380bool SemaOpenACC::ForStmtBeginChecker::checkForCond(
const Stmt *CondStmt,
1381 const ValueDecl *InitVar,
1386 SemaRef.Diag(ForLoc, diag::err_acc_loop_terminating_condition)
1387 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1389 diag::note_acc_construct_here)
1390 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1395 auto DiagCondVar = [
this,
Diag, CondStmt] {
1398 diag::err_acc_loop_terminating_condition)
1399 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1401 diag::note_acc_construct_here)
1402 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1407 if (
const auto *ExprTemp = dyn_cast<ExprWithCleanups>(CondStmt))
1408 CondStmt = ExprTemp->getSubExpr();
1409 if (
const auto *E = dyn_cast<Expr>(CondStmt))
1412 const ValueDecl *CondVar =
nullptr;
1413 if (
const auto *BO = dyn_cast<BinaryOperator>(CondStmt)) {
1414 switch (BO->getOpcode()) {
1416 return DiagCondVar();
1429 CondVar = getDeclFromExpr(BO->getLHS());
1432 CondVar = getDeclFromExpr(BO->getRHS());
1434 }
else if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(CondStmt)) {
1437 if (!CE->isComparisonOp() || CE->getOperator() == OO_Spaceship)
1438 return DiagCondVar();
1442 CondVar = getDeclFromExpr(CE->getArg(0));
1446 CE->getNumArgs() > 1))
1447 CondVar = getDeclFromExpr(CE->getArg(1));
1449 return DiagCondVar();
1453 return DiagCondVar();
1458 return DiagCondVar();
1467bool isValidForIncRHSAssign(
const ValueDecl *InitVar,
const Expr *RHS) {
1469 auto isValid = [](
const ValueDecl *InitVar,
const Expr *InnerLHS,
1470 const Expr *InnerRHS,
bool IsAddition) {
1472 if (!InnerLHS->getType()->isIntegerType() &&
1473 !InnerRHS->getType()->isIntegerType())
1481 const ValueDecl *LHSDecl = getDeclFromExpr(InnerLHS);
1482 const ValueDecl *RHSDecl = getDeclFromExpr(InnerRHS);
1484 if (!LHSDecl || !RHSDecl)
1500 if (
const auto *BO = dyn_cast<BinaryOperator>(RHS)) {
1502 if (OpC != BO_Add && OpC != BO_Sub)
1504 return isValid(InitVar, BO->getLHS(), BO->getRHS(), OpC == BO_Add);
1505 }
else if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
1507 if (Op != OO_Plus && Op != OO_Minus)
1509 return isValid(InitVar, CE->getArg(0), CE->getArg(1), Op == OO_Plus);
1516bool SemaOpenACC::ForStmtBeginChecker::checkForInc(
const Stmt *IncStmt,
1517 const ValueDecl *InitVar,
1521 SemaRef.Diag(ForLoc, diag::err_acc_loop_not_monotonic)
1522 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1524 diag::note_acc_construct_here)
1525 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1529 auto DiagIncVar = [
this,
Diag, IncStmt] {
1532 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1534 diag::note_acc_construct_here)
1535 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1540 if (
const auto *ExprTemp = dyn_cast<ExprWithCleanups>(IncStmt))
1541 IncStmt = ExprTemp->getSubExpr();
1542 if (
const auto *E = dyn_cast<Expr>(IncStmt))
1545 const ValueDecl *IncVar =
nullptr;
1547 if (
const auto *UO = dyn_cast<UnaryOperator>(IncStmt)) {
1549 if (!UO->isIncrementDecrementOp())
1550 return DiagIncVar();
1551 IncVar = getDeclFromExpr(UO->getSubExpr());
1552 }
else if (
const auto *BO = dyn_cast<BinaryOperator>(IncStmt)) {
1553 switch (BO->getOpcode()) {
1555 return DiagIncVar();
1562 if (!isValidForIncRHSAssign(InitVar, BO->getRHS()))
1563 return DiagIncVar();
1566 IncVar = getDeclFromExpr(BO->getLHS());
1567 }
else if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(IncStmt)) {
1568 switch (CE->getOperator()) {
1570 return DiagIncVar();
1579 if (!isValidForIncRHSAssign(InitVar, CE->getArg(1)))
1580 return DiagIncVar();
1584 IncVar = getDeclFromExpr(CE->getArg(0));
1586 return DiagIncVar();
1590 return DiagIncVar();
1596 return DiagIncVar();
1601void SemaOpenACC::ForStmtBeginChecker::checkFor() {
1602 const CheckForInfo &CFI = std::get<CheckForInfo>(Info);
1604 if (!IsInstantiation) {
1607 const ValueDecl *CurInitVar =
nullptr;
1608 checkForInit(CFI.Current.Init, CurInitVar,
true);
1609 checkForCond(CFI.Current.Condition, CurInitVar,
true);
1610 checkForInc(CFI.Current.Increment, CurInitVar,
true);
1612 const ValueDecl *UninstInitVar =
nullptr;
1616 bool UninstInitFailed =
1617 checkForInit(CFI.Uninst.Init, UninstInitVar,
false);
1623 auto InitChanged = [=]() {
1624 if (CFI.Uninst.Init == CFI.Current.Init)
1630 if (
const auto *DS = dyn_cast<DeclStmt>(CFI.Uninst.Init))
1631 if (
const VarDecl *VD = dyn_cast_if_present<VarDecl>(
1632 DS->isSingleDecl() ? DS->getSingleDecl() :
nullptr))
1633 OldVDTy = VD->getType();
1634 if (
const auto *DS = dyn_cast<DeclStmt>(CFI.Current.Init))
1635 if (
const VarDecl *VD = dyn_cast_if_present<VarDecl>(
1636 DS->isSingleDecl() ? DS->getSingleDecl() :
nullptr))
1637 NewVDTy = VD->getType();
1648 bool ShouldDiagNewInit = !UninstInitFailed && InitChanged();
1649 const ValueDecl *CurInitVar =
nullptr;
1650 checkForInit(CFI.Current.Init, CurInitVar, ShouldDiagNewInit);
1654 if (CFI.Uninst.Condition != CFI.Current.Condition &&
1655 !checkForCond(CFI.Uninst.Condition, UninstInitVar,
false))
1656 checkForCond(CFI.Current.Condition, CurInitVar,
true);
1657 if (CFI.Uninst.Increment != CFI.Current.Increment &&
1658 !checkForInc(CFI.Uninst.Increment, UninstInitVar,
false))
1659 checkForInc(CFI.Current.Increment, CurInitVar,
true);
1663void SemaOpenACC::ForStmtBeginChecker::check() {
1674 AlreadyChecked =
true;
1691 if (std::holds_alternative<RangeForInfo>(Info))
1692 return checkRangeFor();
1699 const Stmt *Second,
const Stmt *OldThird,
1700 const Stmt *Third) {
1704 ForStmtBeginChecker FSBC{*
this, ForLoc, OldFirst, OldSecond,
1705 OldThird,
First, Second, Third};
1708 if (!LoopInfo.TopLevelLoopSeen) {
1712 ForStmtBeginHelper(ForLoc, FSBC);
1716 const Stmt *Second,
const Stmt *Third) {
1720 ForStmtBeginChecker FSBC{*
this, ForLoc,
First, Second, Third};
1724 if (!LoopInfo.TopLevelLoopSeen)
1727 ForStmtBeginHelper(ForLoc, FSBC);
1731 const Stmt *OldRangeFor,
1732 const Stmt *RangeFor) {
1733 if (!
getLangOpts().OpenACC || OldRangeFor ==
nullptr || RangeFor ==
nullptr)
1736 ForStmtBeginChecker FSBC{*
this, ForLoc,
1737 cast_if_present<CXXForRangeStmt>(OldRangeFor),
1738 cast_if_present<CXXForRangeStmt>(RangeFor)};
1741 if (!LoopInfo.TopLevelLoopSeen) {
1744 ForStmtBeginHelper(ForLoc, FSBC);
1748 const Stmt *RangeFor) {
1749 if (!
getLangOpts().OpenACC || RangeFor ==
nullptr)
1752 ForStmtBeginChecker FSBC = {*
this, ForLoc,
1753 cast_if_present<CXXForRangeStmt>(RangeFor)};
1757 if (!LoopInfo.TopLevelLoopSeen)
1760 ForStmtBeginHelper(ForLoc, FSBC);
1780 if (
const auto *CS = dyn_cast<CompoundStmt>(CurStmt)) {
1781 for (
const auto *ChildStmt : CS->children()) {
1782 SourceLocation ChildStmtLoc = FindInterveningCodeInLoop(ChildStmt);
1784 return ChildStmtLoc;
1787 return SourceLocation{};
1798 LoopInfo.CurLevelHasLoopAlready =
true;
1803 bool IsActiveCollapse = CollapseInfo.CurCollapseCount &&
1804 *CollapseInfo.CurCollapseCount > 0 &&
1805 !CollapseInfo.ActiveCollapse->hasForce();
1806 bool IsActiveTile = TileInfo.CurTileCount && *TileInfo.CurTileCount > 0;
1808 if (IsActiveCollapse || IsActiveTile) {
1811 if (OtherStmtLoc.
isValid() && IsActiveCollapse) {
1812 Diag(OtherStmtLoc, diag::err_acc_intervening_code)
1814 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1815 diag::note_acc_active_clause_here)
1819 if (OtherStmtLoc.
isValid() && IsActiveTile) {
1820 Diag(OtherStmtLoc, diag::err_acc_intervening_code)
1822 Diag(TileInfo.ActiveTile->getBeginLoc(),
1823 diag::note_acc_active_clause_here)
1843 }
else if (
auto *DRE = dyn_cast<DeclRefExpr>(RoutineName)) {
1844 ValueDecl *VD = DRE->getDecl();
1846 if (
auto *FD = dyn_cast<FunctionDecl>(VD))
1850 if (
auto *VarD = dyn_cast<VarDecl>(VD)) {
1851 QualType VarDTy = VarD->getType();
1854 if (RD->isGenericLambda())
1857 return RD->getLambdaCallOperator();
1873 assert(RoutineName &&
"Routine name cannot be null here");
1884 }
else if (
const auto *DRE = dyn_cast<DeclRefExpr>(RoutineName)) {
1891 if (
const auto *VarD = dyn_cast<VarDecl>(VD)) {
1895 if (RD->isGenericLambda()) {
1935 auto *ContextDecl = dyn_cast<FunctionDecl>(
getCurContext());
1943 for (
const auto *A : ContextDecl->attrs()) {
1946 Diag(A->getLocation(), diag::note_acc_construct_here)
1952 MagicStaticLocs.insert({ContextDecl->getCanonicalDecl(), VD->
getBeginLoc()});
1954void SemaOpenACC::CheckLastRoutineDeclNameConflict(
const NamedDecl *ND) {
1963 if (!LastRoutineDecl)
1996 if (NDLine - LastLine > 1)
2004 diag::warn_acc_confusing_routine_name);
2020 if (!RD || !RD->isLambda())
2023 CheckLastRoutineDeclNameConflict(VD);
2029 CheckLastRoutineDeclNameConflict(FD);
2041 SemaRef.DiscardCleanupsInEvaluationContext();
2042 SemaRef.PopExpressionEvaluationContext();
2049 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
2050 Diag(StartLoc, diag::err_acc_invalid_in_loop)
2051 << 0 << CollapseInfo.DirectiveKind
2053 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
2054 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
2055 diag::note_acc_active_clause_here)
2058 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
2059 Diag(StartLoc, diag::err_acc_invalid_in_loop)
2060 << 0 << TileInfo.DirectiveKind
2062 assert(TileInfo.ActiveTile &&
"Tile count without object?");
2063 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
2067 if (DiagnoseRequiredClauses(K, StartLoc, Clauses))
2069 return diagnoseConstructAppertainment(*
this, K, StartLoc,
true);
2084 return OpenACCComputeConstruct::Create(
2086 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2093 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2097 getASTContext(), ActiveComputeConstructInfo.Kind, StartLoc, DirLoc,
2098 EndLoc, Clauses, AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2103 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2116 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2120 getASTContext(), StartLoc, DirLoc, LParenLoc, Exprs.front(), MiscLoc,
2121 Exprs.drop_front(), RParenLoc, EndLoc, Clauses);
2141 getASTContext(), StartLoc, DirLoc, AtomicKind, EndLoc, Clauses,
2142 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2145 assert(Clauses.empty() &&
"Cache doesn't allow clauses");
2147 LParenLoc, MiscLoc, Exprs, RParenLoc,
2151 llvm_unreachable(
"routine shouldn't handled here");
2156 RParenLoc, EndLoc, Clauses);
2161 llvm_unreachable(
"Unhandled case in directive handling?");
2170 llvm_unreachable(
"Unimplemented associated statement application");
2179 "these don't have associated statements, so shouldn't get here");
2207 Diag(DirectiveLoc, diag::note_acc_construct_here) << K;
2211 if (!CollapseInfo.CollapseDepthSatisfied || !TileInfo.TileDepthSatisfied) {
2212 if (!CollapseInfo.CollapseDepthSatisfied) {
2213 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
2215 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
2216 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
2217 diag::note_acc_active_clause_here)
2221 if (!TileInfo.TileDepthSatisfied) {
2222 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
2224 assert(TileInfo.ActiveTile &&
"Collapse count without object?");
2225 Diag(TileInfo.ActiveTile->getBeginLoc(),
2226 diag::note_acc_active_clause_here)
2232 return AssocStmt.
get();
2234 llvm_unreachable(
"Invalid associated statement application");
2242bool CheckValidRoutineGangWorkerVectorSeqClauses(
2254 auto *FirstDeviceType =
2255 llvm::find_if(Clauses, llvm::IsaPred<OpenACCDeviceTypeClause>);
2260 std::find_if(Clauses.begin(), FirstDeviceType, RequiredPred);
2262 if (ClauseItr != FirstDeviceType)
2266 if (FirstDeviceType == Clauses.end())
2267 return SemaRef.
Diag(DirectiveLoc, diag::err_acc_construct_one_clause_of)
2269 <<
"'gang', 'seq', 'vector', or 'worker'";
2273 auto *PrevDeviceType = FirstDeviceType;
2275 while (PrevDeviceType != Clauses.end()) {
2276 auto *NextDeviceType =
2277 std::find_if(std::next(PrevDeviceType), Clauses.end(),
2278 llvm::IsaPred<OpenACCDeviceTypeClause>);
2280 ClauseItr = std::find_if(PrevDeviceType, NextDeviceType, RequiredPred);
2282 if (ClauseItr == NextDeviceType)
2283 return SemaRef.
Diag((*PrevDeviceType)->getBeginLoc(),
2284 diag::err_acc_clause_routine_one_of_in_region);
2286 PrevDeviceType = NextDeviceType;
2299 SemaRef.DiscardCleanupsInEvaluationContext();
2300 SemaRef.PopExpressionEvaluationContext();
2302 if (DiagnoseRequiredClauses(K, StartLoc, Clauses))
2305 CheckValidRoutineGangWorkerVectorSeqClauses(*
this, StartLoc, Clauses))
2308 return diagnoseConstructAppertainment(*
this, K, StartLoc,
false);
2321 if (Clauses.empty()) {
2322 Diag(EndLoc, diag::err_acc_declare_required_clauses);
2336 llvm_unreachable(
"routine shouldn't be handled here");
2338 llvm_unreachable(
"unhandled case in directive handling?");
2349 if (
auto *FD = dyn_cast<FunctionDecl>(D))
2353 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
2354 return FTD->getTemplatedDecl();
2356 if (
auto *FD = dyn_cast<FieldDecl>(D)) {
2358 FD->getType().isNull() ?
nullptr : FD->getType()->getAsCXXRecordDecl();
2360 if (RD && RD->isGenericLambda())
2361 return RD->getDependentLambdaCallOperator()->getTemplatedDecl();
2362 if (RD && RD->isLambda())
2363 return RD->getLambdaCallOperator();
2367 if (
auto *VD = dyn_cast<VarDecl>(D)) {
2369 if (!
Init ||
Init->getType().isNull())
2372 const auto *RD =
Init->getType()->getAsCXXRecordDecl();
2373 if (RD && RD->isGenericLambda())
2374 return RD->getDependentLambdaCallOperator()->getTemplatedDecl();
2375 if (RD && RD->isLambda())
2376 return RD->getLambdaCallOperator();
2391 ArrayRef<const OpenACCClause *> Clauses,
2393 OpenACCRoutineDeclAttr *A =
2394 OpenACCRoutineDeclAttr::Create(
SemaRef.getASTContext(), DirLoc);
2395 A->Clauses.assign(Clauses.begin(), Clauses.end());
2403 Decl *NextParsedDecl) {
2405 FunctionDecl *NextParsedFDecl = LegalizeNextParsedDecl(NextParsedDecl);
2407 if (!NextParsedFDecl) {
2409 SemaRef.Diag(DirLoc, diag::err_acc_decl_for_routine);
2417 Itr != MagicStaticLocs.end()) {
2418 Diag(Itr->second, diag::err_acc_magic_static_in_routine);
2419 Diag(DirLoc, diag::note_acc_construct_here)
2425 auto BindItr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCBindClause>);
2426 if (BindItr != Clauses.end()) {
2427 for (
auto *A : NextParsedFDecl->
attrs()) {
2431 if (
auto *RA = dyn_cast<OpenACCRoutineDeclAttr>(A)) {
2433 llvm::find_if(RA->Clauses, llvm::IsaPred<OpenACCBindClause>);
2434 if (OtherBindItr != RA->Clauses.end() &&
2437 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_unnamed_bind);
2438 Diag((*OtherBindItr)->getEndLoc(),
2439 diag::note_acc_previous_clause_here)
2440 << (*BindItr)->getClauseKind();
2451 if (
auto *RA = dyn_cast<OpenACCRoutineAnnotAttr>(A);
2452 RA && RA->getRange().getEnd().isValid()) {
2453 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
2454 Diag(RA->getRange().getEnd(), diag::note_acc_previous_clause_here)
2461 CreateRoutineDeclAttr(*
this, DirLoc, Clauses, NextParsedFDecl);
2472 if ((FD = getFunctionFromRoutineName(FuncRef))) {
2477 Itr != MagicStaticLocs.end()) {
2478 Diag(Itr->second, diag::err_acc_magic_static_in_routine);
2479 Diag(DirLoc, diag::note_acc_construct_here)
2488 auto BindItr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCBindClause>);
2490 if (BindItr != Clauses.end()) {
2491 BindLoc = (*BindItr)->getBeginLoc();
2495 for (
auto *A : FD->
attrs()) {
2496 if (
auto *RA = dyn_cast<OpenACCRoutineDeclAttr>(A)) {
2498 llvm::find_if(RA->Clauses, llvm::IsaPred<OpenACCBindClause>);
2499 if (OtherBindItr != RA->Clauses.end()) {
2500 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
2501 Diag((*OtherBindItr)->getEndLoc(),
2502 diag::note_acc_previous_clause_here)
2503 << (*BindItr)->getClauseKind();
2508 if (
auto *RA = dyn_cast<OpenACCRoutineAnnotAttr>(A);
2509 RA && RA->getRange().getEnd().isValid()) {
2510 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
2511 Diag(RA->getRange().getEnd(), diag::note_acc_previous_clause_here)
2512 << (*BindItr)->getClauseKind();
2520 auto *RAA = OpenACCRoutineAnnotAttr::CreateImplicit(
getASTContext(),
2525 for (
auto *CurFD : FD->
redecls())
2531 RParenLoc, EndLoc, Clauses);
2539 RoutineRefList.emplace_back(FD, LastRoutineDecl);
2541 return LastRoutineDecl;
2545 for (
auto [FD, RoutineDecl] : RoutineRefList)
2546 SemaRef.Consumer.HandleOpenACCRoutineReference(FD, RoutineDecl);
2554 assert((!ReferencedFunc || !NextDecl) &&
2555 "Only one of these should be filled");
2558 Decl *NextLineDecl =
nullptr;
2564 return NextDecl.
get();
2568 StartLoc, DirLoc, LParenLoc, ReferencedFunc, RParenLoc, Clauses, EndLoc)};
2576 assert((!ReferencedFunc || !NextStmt) &&
2577 "Only one of these should be filled");
2580 Decl *NextLineDecl =
nullptr;
2583 NextLineDecl = DS->getSingleDecl();
2590 RParenLoc, Clauses, EndLoc)};
2594OpenACCRoutineDeclAttr *
2596 OpenACCRoutineDeclAttr *
New =
2597 OpenACCRoutineDeclAttr::Create(
getASTContext(), Old.getLocation());
2600 New->Clauses = Old.Clauses;
2614enum class InitKind {
Invalid,
Zero, One, AllOnes, Least, Largest };
2617 case InitKind::Invalid:
2618 llvm_unreachable(
"invalid init kind");
2619 case InitKind::Zero:
2620 return llvm::APFloat::getZero(Context.getFloatTypeSemantics(Ty));
2622 return llvm::APFloat::getOne(Context.getFloatTypeSemantics(Ty));
2623 case InitKind::AllOnes:
2624 return llvm::APFloat::getAllOnesValue(Context.getFloatTypeSemantics(Ty));
2625 case InitKind::Least:
2626 return llvm::APFloat::getLargest(Context.getFloatTypeSemantics(Ty),
2628 case InitKind::Largest:
2629 return llvm::APFloat::getLargest(Context.getFloatTypeSemantics(Ty));
2631 llvm_unreachable(
"unknown init kind");
2634llvm::APInt getInitIntValue(ASTContext &Context, InitKind IK, QualType Ty) {
2636 case InitKind::Invalid:
2637 llvm_unreachable(
"invalid init kind");
2638 case InitKind::Zero:
2642 case InitKind::AllOnes:
2643 return llvm::APInt::getAllOnes(Context.
getIntWidth(Ty));
2644 case InitKind::Least:
2646 return llvm::APInt::getSignedMinValue(Context.
getIntWidth(Ty));
2647 return llvm::APInt::getMinValue(Context.
getIntWidth(Ty));
2648 case InitKind::Largest:
2650 return llvm::APInt::getSignedMaxValue(Context.
getIntWidth(Ty));
2651 return llvm::APInt::getMaxValue(Context.
getIntWidth(Ty));
2653 llvm_unreachable(
"unknown init kind");
2658Expr *GenerateReductionInitRecipeExpr(ASTContext &Context,
2659 SourceRange ExprRange, QualType Ty,
2661 if (IK == InitKind::Invalid)
2664 if (IK == InitKind::Zero) {
2665 Expr *InitExpr =
new (Context)
2666 InitListExpr(Context, ExprRange.
getBegin(), {}, ExprRange.
getEnd());
2672 llvm::SmallVector<Expr *> Exprs;
2675 for (
auto *F : RD->fields()) {
2676 if (Expr *NewExpr = GenerateReductionInitRecipeExpr(Context, ExprRange,
2678 Exprs.push_back(NewExpr);
2683 for (uint64_t Idx = 0; Idx < AT->getZExtSize(); ++Idx) {
2684 if (Expr *NewExpr = GenerateReductionInitRecipeExpr(
2685 Context, ExprRange, AT->getElementType(), IK))
2686 Exprs.push_back(NewExpr);
2704 if (
const auto *Cplx = Ty->
getAs<ComplexType>()) {
2709 QualType EltTy = Cplx->getElementType();
2712 Context, getInitFloatValue(Context, InitKind::Zero, EltTy),
2713 true, EltTy, ExprRange.
getBegin()));
2715 Context, getInitFloatValue(Context, InitKind::Zero, EltTy),
2716 true, EltTy, ExprRange.
getBegin()));
2719 Context, getInitIntValue(Context, InitKind::Zero, EltTy), EltTy,
2722 Context, getInitIntValue(Context, InitKind::Zero, EltTy), EltTy,
2732 (IK == InitKind::One ||
2733 IK == InitKind::AllOnes ||
2734 IK == InitKind::Largest),
2738 Context, getInitIntValue(Context, IK, Ty), Ty, ExprRange.
getBegin()));
2742 Expr *InitExpr =
new (Context)
2743 InitListExpr(Context, ExprRange.
getBegin(), Exprs, ExprRange.
getEnd());
2748VarDecl *CreateAllocaDecl(ASTContext &Ctx, DeclContext *DC,
2749 SourceLocation BeginLoc, IdentifierInfo *VarName,
2751 auto *VD =
VarDecl::Create(Ctx, DC, BeginLoc, BeginLoc, VarName, VarTy,
2757ExprResult FinishValueInit(Sema &S, InitializedEntity &Entity,
2758 SourceLocation Loc, QualType VarTy, Expr *InitExpr) {
2762 InitializationKind
Kind =
2764 InitializationSequence InitSeq(S, Entity, Kind, InitExpr,
2768 return InitSeq.Perform(S, Entity, Kind, InitExpr, &VarTy);
2783 if (
const auto *ASE =
2785 VarTy = ASE->getElementType();
2787 VarDecl *AllocaDecl = CreateAllocaDecl(
2789 &
getASTContext().Idents.get(
"openacc.private.init"), VarTy);
2800 if (
Init.isUsable()) {
2819 if (
const auto *ASE =
2821 VarTy = ASE->getElementType();
2823 VarDecl *AllocaDecl = CreateAllocaDecl(
2825 &
getASTContext().Idents.get(
"openacc.firstprivate.init"), VarTy);
2827 VarDecl *Temporary = CreateAllocaDecl(
2848 if (
Init.isUsable()) {
2862 CK_ArrayToPointerDecay, TemporaryDRE,
nullptr,
2865 for (std::size_t I = 0; I < ArrTy->getLimitedSize(); ++I) {
2888 CopySeq.
Perform(
SemaRef.SemaRef, CopyEntity, CopyKind, Subscript);
2889 Args.push_back(ElemRes.
get());
2901 if (
Init.isUsable()) {
2920 if (
const auto *ASE =
2922 VarTy = ASE->getElementType();
2929 if (CreateReductionCombinerRecipe(VarExpr->
getBeginLoc(), ReductionOperator,
2930 VarTy, CombinerRecipes))
2933 VarDecl *AllocaDecl = CreateAllocaDecl(
2935 &
getASTContext().Idents.get(
"openacc.reduction.init"), VarTy);
2940 InitKind IK = InitKind::Invalid;
2941 switch (ReductionOperator) {
2946 IK = InitKind::Invalid;
2949 IK = InitKind::Least;
2952 IK = InitKind::Largest;
2955 IK = InitKind::AllOnes;
2965 IK = InitKind::Zero;
2969 Expr *InitExpr = GenerateReductionInitRecipeExpr(
2977 if (
Init.isUsable()) {
2985bool SemaOpenACC::CreateReductionCombinerRecipe(
2997 switch (ReductionOperator) {
3002 CombinerRecipes.push_back({
nullptr,
nullptr,
nullptr});
3005 BinOp = BinaryOperatorKind::BO_AddAssign;
3008 BinOp = BinaryOperatorKind::BO_MulAssign;
3011 BinOp = BinaryOperatorKind::BO_AndAssign;
3014 BinOp = BinaryOperatorKind::BO_OrAssign;
3017 BinOp = BinaryOperatorKind::BO_XorAssign;
3022 BinOp = BinaryOperatorKind::BO_LT;
3025 BinOp = BinaryOperatorKind::BO_LAnd;
3028 BinOp = BinaryOperatorKind::BO_LOr;
3035 VarTy = AT->getElementType();
3037 assert(!VarTy->
isArrayType() &&
"Only 1 level of array allowed");
3039 enum class CombinerFailureKind {
3046 auto genCombiner = [&,
this](DeclRefExpr *LHSDRE, DeclRefExpr *RHSDRE)
3047 -> std::pair<ExprResult, CombinerFailureKind> {
3049 SemaRef.BuildBinOp(
SemaRef.getCurScope(), Loc, BinOp, LHSDRE, RHSDRE,
3051 switch (ReductionOperator) {
3059 return {BinOpRes, BinOpRes.
isUsable() ? CombinerFailureKind::None
3060 : CombinerFailureKind::BinOp};
3069 return {BinOpRes, CombinerFailureKind::BinOp};
3075 CondRes =
SemaRef.ActOnConditionalOp(Loc, Loc, BinOpRes.
get(), LHSDRE,
3078 CondRes =
SemaRef.ActOnConditionalOp(Loc, Loc, BinOpRes.
get(), RHSDRE,
3082 return {CondRes, CombinerFailureKind::Conditional};
3086 BinaryOperatorKind::BO_Assign,
3087 LHSDRE, CondRes.
get(),
3090 ? CombinerFailureKind::None
3091 : CombinerFailureKind::Assignment};
3098 return {BinOpRes, CombinerFailureKind::BinOp};
3102 BinaryOperatorKind::BO_Assign,
3103 LHSDRE, BinOpRes.
get(),
3106 ? CombinerFailureKind::None
3107 : CombinerFailureKind::Assignment};
3110 llvm_unreachable(
"Invalid should have been caught above");
3112 llvm_unreachable(
"Unhandled case");
3115 auto tryCombiner = [&,
this](DeclRefExpr *LHSDRE, DeclRefExpr *RHSDRE,
3119 Sema::TentativeAnalysisScope Trap{
SemaRef};
3120 return genCombiner(LHSDRE, RHSDRE);
3122 return genCombiner(LHSDRE, RHSDRE);
3125 struct CombinerAttemptTy {
3126 CombinerFailureKind FailKind;
3128 DeclRefExpr *LHSDRE;
3130 DeclRefExpr *RHSDRE;
3134 auto formCombiner = [&,
this](QualType Ty) -> CombinerAttemptTy {
3135 VarDecl *LHSDecl = CreateAllocaDecl(
3137 &
getASTContext().Idents.get(
"openacc.reduction.combiner.lhs"), Ty);
3139 getASTContext(), NestedNameSpecifierLoc{}, SourceLocation{}, LHSDecl,
3141 DeclarationNameInfo{DeclarationName{LHSDecl->
getDeclName()},
3144 VarDecl *RHSDecl = CreateAllocaDecl(
3146 &
getASTContext().Idents.get(
"openacc.reduction.combiner.lhs"), Ty);
3148 getASTContext(), NestedNameSpecifierLoc{}, SourceLocation{}, RHSDecl,
3150 DeclarationNameInfo{DeclarationName{RHSDecl->getDeclName()},
3151 RHSDecl->getBeginLoc()},
3154 std::pair<ExprResult, CombinerFailureKind> BinOpResult =
3155 tryCombiner(LHSDRE, RHSDRE,
true);
3157 return {BinOpResult.second, LHSDecl, LHSDRE, RHSDecl, RHSDRE,
3158 BinOpResult.first.get()};
3161 CombinerAttemptTy TopLevelCombinerInfo = formCombiner(VarTy);
3163 if (TopLevelCombinerInfo.Op) {
3164 if (!TopLevelCombinerInfo.Op->containsErrors() &&
3165 TopLevelCombinerInfo.Op->isInstantiationDependent()) {
3168 CombinerRecipes.push_back({
nullptr,
nullptr,
nullptr});
3170 }
else if (!TopLevelCombinerInfo.Op->containsErrors()) {
3172 CombinerRecipes.push_back({TopLevelCombinerInfo.LHS,
3173 TopLevelCombinerInfo.RHS,
3174 TopLevelCombinerInfo.Op});
3179 auto EmitFailureNote = [&](CombinerFailureKind CFK) {
3180 if (CFK == CombinerFailureKind::BinOp)
3181 return Diag(Loc, diag::note_acc_reduction_combiner_forming)
3183 return Diag(Loc, diag::note_acc_reduction_combiner_forming) << CFK;
3191 Diag(Loc, diag::err_acc_reduction_recipe_no_op) << VarTy;
3192 EmitFailureNote(TopLevelCombinerInfo.FailKind);
3193 tryCombiner(TopLevelCombinerInfo.LHSDRE, TopLevelCombinerInfo.RHSDRE,
3198 for (
const FieldDecl *FD : RD->
fields()) {
3199 CombinerAttemptTy FieldCombinerInfo = formCombiner(FD->getType());
3201 if (!FieldCombinerInfo.Op || FieldCombinerInfo.Op->containsErrors()) {
3202 Diag(Loc, diag::err_acc_reduction_recipe_no_op) << FD->getType();
3203 Diag(FD->getBeginLoc(), diag::note_acc_reduction_recipe_noop_field) << RD;
3204 EmitFailureNote(FieldCombinerInfo.FailKind);
3205 tryCombiner(FieldCombinerInfo.LHSDRE, FieldCombinerInfo.RHSDRE,
3210 if (FieldCombinerInfo.Op->isInstantiationDependent()) {
3213 CombinerRecipes.push_back({
nullptr,
nullptr,
nullptr});
3215 CombinerRecipes.push_back(
3216 {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 isRecordType() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
void setInitStyle(InitializationStyle Style)
@ CallInit
Call-style initialization (C++98)
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)
Returns the results of matching Matcher on Node.
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ Invalid
Invalid Reduction Clause Kind.
bool isa(CodeGen::Address addr)
@ Conditional
A conditional (?:) operator.
@ OK_Ordinary
An ordinary object is located at an address in memory.
OpenACCClauseKind
Represents the kind of an OpenACC clause.
@ Collapse
'collapse' clause, allowed on 'loop' and Combined constructs.
@ Private
'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...
@ Invalid
Represents an invalid clause, for the purposes of parsing.
@ UseDevice
'use_device' clause, allowed on 'host_data' construct.
@ Reduction
'reduction' clause, allowed on Parallel, Serial, Loop, and the combined constructs.
@ FirstPrivate
'firstprivate' clause, allowed on 'parallel', 'serial', 'parallel loop', and 'serial loop' constructs...
@ Tile
'tile' clause, allowed on 'loop' and Combined constructs.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Result
The result type of a method or function.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
U cast(CodeGen::Address addr)
@ None
The alignment was not explicit in code.
ActionResult< Expr * > ExprResult
ActionResult< Stmt * > StmtResult
@ NOUR_None
This is an odr-use.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
static OpenACCFirstPrivateRecipe Empty()
static OpenACCPrivateRecipe Empty()
static OpenACCReductionRecipeWithStorage Empty()