23#include "llvm/ADT/StringExtras.h"
24#include "llvm/Support/Casting.h"
33 case OpenACCDirectiveKind::Invalid:
37 case OpenACCDirectiveKind::Parallel:
38 case OpenACCDirectiveKind::ParallelLoop:
39 case OpenACCDirectiveKind::Serial:
40 case OpenACCDirectiveKind::SerialLoop:
41 case OpenACCDirectiveKind::Kernels:
42 case OpenACCDirectiveKind::KernelsLoop:
43 case OpenACCDirectiveKind::Loop:
44 case OpenACCDirectiveKind::Data:
45 case OpenACCDirectiveKind::EnterData:
46 case OpenACCDirectiveKind::ExitData:
47 case OpenACCDirectiveKind::HostData:
48 case OpenACCDirectiveKind::Wait:
49 case OpenACCDirectiveKind::Update:
50 case OpenACCDirectiveKind::Init:
51 case OpenACCDirectiveKind::Shutdown:
52 case OpenACCDirectiveKind::Cache:
53 case OpenACCDirectiveKind::Atomic:
55 return S.
Diag(StartLoc, diag::err_acc_construct_appertainment) << K;
61void CollectActiveReductionClauses(
64 for (
auto *CurClause : CurClauses) {
65 if (
auto *RedClause = dyn_cast<OpenACCReductionClause>(CurClause);
66 RedClause && !RedClause->getVarList().empty())
67 ActiveClauses.push_back(RedClause);
75 case OpenACCDirectiveKind::Parallel:
76 case OpenACCDirectiveKind::ParallelLoop:
77 case OpenACCDirectiveKind::Serial:
78 case OpenACCDirectiveKind::SerialLoop:
79 case OpenACCDirectiveKind::Kernels:
80 case OpenACCDirectiveKind::KernelsLoop:
81 case OpenACCDirectiveKind::Loop:
83 case OpenACCDirectiveKind::Data:
84 case OpenACCDirectiveKind::HostData:
85 case OpenACCDirectiveKind::Atomic:
87 case OpenACCDirectiveKind::Cache:
88 case OpenACCDirectiveKind::Routine:
89 case OpenACCDirectiveKind::Declare:
90 case OpenACCDirectiveKind::EnterData:
91 case OpenACCDirectiveKind::ExitData:
92 case OpenACCDirectiveKind::Wait:
93 case OpenACCDirectiveKind::Init:
94 case OpenACCDirectiveKind::Shutdown:
95 case OpenACCDirectiveKind::Set:
96 case OpenACCDirectiveKind::Update:
97 llvm_unreachable(
"Doesn't have an associated stmt");
98 case OpenACCDirectiveKind::Invalid:
99 llvm_unreachable(
"Unhandled directive kind?");
101 llvm_unreachable(
"Unhandled directive kind?");
112 : SemaRef(S), OldActiveComputeConstructInfo(S.ActiveComputeConstructInfo),
113 DirKind(DK), OldLoopGangClauseOnKernel(S.LoopGangClauseOnKernel),
114 OldLoopWorkerClauseLoc(S.LoopWorkerClauseLoc),
115 OldLoopVectorClauseLoc(S.LoopVectorClauseLoc),
116 OldLoopWithoutSeqInfo(S.LoopWithoutSeqInfo),
117 ActiveReductionClauses(S.ActiveReductionClauses),
118 LoopRAII(SemaRef, PreserveLoopRAIIDepthInAssociatedStmtRAII(DirKind)) {
124 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
125 SemaRef.ActiveComputeConstructInfo.Kind = DirKind;
126 SemaRef.ActiveComputeConstructInfo.Clauses = Clauses;
141 SemaRef.ActiveComputeConstructInfo.Kind = DirKind;
142 SemaRef.ActiveComputeConstructInfo.Clauses = Clauses;
144 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
156 llvm::find_if(Clauses, llvm::IsaPred<OpenACCSeqClause>))
169 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCGangClause>);
170 if (Itr != Clauses.end())
174 if (UnInstClauses.empty()) {
175 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCWorkerClause>);
176 if (Itr != Clauses.end())
179 auto *Itr2 = llvm::find_if(Clauses, llvm::IsaPred<OpenACCVectorClause>);
180 if (Itr2 != Clauses.end())
184 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
192 llvm::find_if(Clauses, llvm::IsaPred<OpenACCSeqClause>))
205 UnInstClauses.empty()) {
207 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCGangClause>);
208 if (Itr != Clauses.end())
213 if (UnInstClauses.empty()) {
214 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCWorkerClause>);
215 if (Itr != Clauses.end())
218 auto *Itr2 = llvm::find_if(Clauses, llvm::IsaPred<OpenACCVectorClause>);
219 if (Itr2 != Clauses.end())
235 if (!
New->getLoopCount())
239 if (!
New->getLoopCount())
243 if (
New->getLoopCount()->isInstantiationDependent())
259 if (cast<ConstantExpr>(Old->
getLoopCount())->getResultAsAPSInt() <
260 cast<ConstantExpr>(
New->getLoopCount())->getResultAsAPSInt())
272 SemaRef.LoopInfo.CurLevelHasLoopAlready =
false;
273 SemaRef.CollapseInfo.CollapseDepthSatisfied =
true;
274 SemaRef.CollapseInfo.CurCollapseCount = 0;
275 SemaRef.TileInfo.TileDepthSatisfied =
true;
286 auto *UnInstClauseItr =
287 llvm::find_if(UnInstClauses, llvm::IsaPred<OpenACCCollapseClause>);
289 llvm::find_if(Clauses, llvm::IsaPred<OpenACCCollapseClause>);
298 while (ClauseItr != Clauses.end()) {
300 cast<OpenACCCollapseClause>(*ClauseItr);
302 UnInstClauseItr == UnInstClauses.end()
304 : cast<OpenACCCollapseClause>(*UnInstClauseItr);
307 getBestCollapseCandidate(FoundClause, CurClause, UnInstCurClause);
310 UnInstClauseItr == UnInstClauses.end()
312 : std::find_if(std::next(UnInstClauseItr), UnInstClauses.end(),
313 llvm::IsaPred<OpenACCCollapseClause>);
314 ClauseItr = std::find_if(std::next(ClauseItr), Clauses.end(),
315 llvm::IsaPred<OpenACCCollapseClause>);
321 SemaRef.CollapseInfo.ActiveCollapse = FoundClause;
322 SemaRef.CollapseInfo.CollapseDepthSatisfied =
false;
323 SemaRef.CollapseInfo.CurCollapseCount =
324 cast<ConstantExpr>(FoundClause->
getLoopCount())->getResultAsAPSInt();
325 SemaRef.CollapseInfo.DirectiveKind = DirKind;
334 if (UnInstClauses.size() > 0)
336 auto *TileClauseItr =
337 llvm::find_if(Clauses, llvm::IsaPred<OpenACCTileClause>);
339 if (Clauses.end() == TileClauseItr)
346 while (Clauses.end() !=
347 (TileClauseItr = std::find_if(std::next(TileClauseItr), Clauses.end(),
348 llvm::IsaPred<OpenACCTileClause>))) {
350 if (NewClause->getSizeExprs().size() > TileClause->
getSizeExprs().size())
351 TileClause = NewClause;
354 SemaRef.TileInfo.ActiveTile = TileClause;
355 SemaRef.TileInfo.TileDepthSatisfied =
false;
356 SemaRef.TileInfo.CurTileCount =
357 static_cast<unsigned>(TileClause->
getSizeExprs().size());
358 SemaRef.TileInfo.DirectiveKind = DirKind;
369 SemaRef.ActiveComputeConstructInfo = OldActiveComputeConstructInfo;
370 SemaRef.LoopGangClauseOnKernel = OldLoopGangClauseOnKernel;
371 SemaRef.LoopWorkerClauseLoc = OldLoopWorkerClauseLoc;
372 SemaRef.LoopVectorClauseLoc = OldLoopVectorClauseLoc;
373 SemaRef.LoopWithoutSeqInfo = OldLoopWithoutSeqInfo;
374 SemaRef.ActiveReductionClauses.swap(ActiveReductionClauses);
402 "Only one of directive or clause kind should be provided");
411 unsigned getDiagKind()
const {
412 if (ClauseKind != OpenACCClauseKind::Invalid)
414 if (DirectiveKind != OpenACCDirectiveKind::Invalid)
422 : ICEConvertDiagnoser(
false,
425 DirectiveKind(DK), ClauseKind(CK), IntExpr(IntExpr) {}
434 return S.
Diag(
Loc, diag::err_acc_int_expr_requires_integer)
435 << getDiagKind() << ClauseKind << DirectiveKind <<
T;
440 return S.
Diag(
Loc, diag::err_acc_int_expr_incomplete_class_type)
447 return S.
Diag(
Loc, diag::err_acc_int_expr_explicit_conversion)
460 return S.
Diag(
Loc, diag::err_acc_int_expr_multiple_conversions) <<
T;
472 llvm_unreachable(
"conversion functions are permitted");
474 } IntExprDiagnoser(DK, CK, IntExpr);
480 Loc, IntExpr, IntExprDiagnoser);
484 IntExpr = IntExprResult.
get();
518 return Diag(VarExpr->
getExprLoc(), diag::err_acc_var_not_pointer_type)
526 CacheInfo.ParsingCacheVarList =
true;
527 CacheInfo.IsInvalidCacheRef =
false;
532 CacheInfo.ParsingCacheVarList =
false;
533 CacheInfo.IsInvalidCacheRef =
false;
543 bool WasParsingInvalidCacheRef =
544 CacheInfo.ParsingCacheVarList && CacheInfo.IsInvalidCacheRef;
545 CacheInfo.ParsingCacheVarList =
false;
546 CacheInfo.IsInvalidCacheRef =
false;
548 if (!isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
555 while (isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
556 if (
auto *SubScrpt = dyn_cast<ArraySubscriptExpr>(CurVarExpr))
564 if (
const auto *DRE = dyn_cast<DeclRefExpr>(CurVarExpr)) {
565 if (isa<VarDecl, NonTypeTemplateParmDecl>(
566 DRE->getFoundDecl()->getCanonicalDecl()))
567 return WasParsingInvalidCacheRef ?
ExprEmpty() : VarExpr;
570 if (
const auto *ME = dyn_cast<MemberExpr>(CurVarExpr)) {
571 if (isa<FieldDecl>(ME->getMemberDecl()->getCanonicalDecl())) {
572 return WasParsingInvalidCacheRef ?
ExprEmpty() : VarExpr;
578 if (isa<DependentScopeDeclRefExpr, CXXDependentScopeMemberExpr>(CurVarExpr))
579 return WasParsingInvalidCacheRef ?
ExprEmpty() : VarExpr;
583 if (isa<RecoveryExpr>(CurVarExpr))
591 if (!
getLangOpts().OpenACC || !CacheInfo.ParsingCacheVarList || !
D ||
617 Diag(
Loc, diag::warn_acc_cache_var_not_outside_loop);
619 CacheInfo.IsInvalidCacheRef =
true;
652 if (!ArrTy->isConstantArrayType()) {
653 S.
Diag(InnerLoc, clang::diag::warn_acc_var_referenced_non_const_array)
658 return CheckVarType(S, CK, VarExpr, InnerLoc, ArrTy->getElementType());
669 bool HasNonDeletedDefaultCtor =
671 return CD->isDefaultConstructor() && !CD->isDeleted();
672 }) != RD->ctors().end();
673 if (!HasNonDeletedDefaultCtor && !RD->needsImplicitDefaultConstructor()) {
674 S.
Diag(InnerLoc, clang::diag::warn_acc_var_referenced_lacks_op)
675 << InnerTy << CK << clang::diag::AccVarReferencedReason::DefCtor;
679 if (!RD->hasSimpleCopyConstructor()) {
687 S.
Diag(InnerLoc, clang::diag::warn_acc_var_referenced_lacks_op)
688 << InnerTy << CK << clang::diag::AccVarReferencedReason::CopyCtor;
699 bool DestructorDeleted =
700 RD->getDestructor() && RD->getDestructor()->isDeleted();
701 if (DestructorDeleted && !RD->needsImplicitDestructor()) {
702 S.
Diag(InnerLoc, clang::diag::warn_acc_var_referenced_lacks_op)
703 << InnerTy << CK << clang::diag::AccVarReferencedReason::Dtor;
713 return CheckVarType(S, CK, VarExpr, InnerExpr->
getBeginLoc(),
734 if (isa<ArraySubscriptExpr>(CurVarExpr)) {
736 diag::err_acc_not_a_var_ref_use_device_declare)
742 if (isa<ArraySectionExpr>(CurVarExpr))
744 diag::ext_acc_array_section_use_device_declare)
750 while (isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
751 if (
auto *SubScrpt = dyn_cast<ArraySubscriptExpr>(CurVarExpr))
759 if (
const auto *DRE = dyn_cast<DeclRefExpr>(CurVarExpr)) {
760 if (isa<VarDecl, NonTypeTemplateParmDecl>(
761 DRE->getFoundDecl()->getCanonicalDecl()))
762 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
771 if (
const auto *ME = dyn_cast<MemberExpr>(CurVarExpr)) {
772 if (isa<FieldDecl>(ME->getMemberDecl()->getCanonicalDecl())) {
779 const auto *
This = dyn_cast<CXXThisExpr>(ME->getBase());
781 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
783 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
792 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
796 if (isa<DependentScopeDeclRefExpr>(CurVarExpr) ||
798 isa<CXXDependentScopeMemberExpr>(CurVarExpr)))
799 return CheckVarType(*
this, CK, VarExpr, CurVarExpr);
803 if (isa<RecoveryExpr>(CurVarExpr))
807 Diag(VarExpr->
getExprLoc(), diag::err_acc_not_a_var_ref_use_device_declare)
810 Diag(VarExpr->
getExprLoc(), diag::err_acc_not_a_var_ref_use_device_declare)
826 if (
Base->hasPlaceholderType() &&
827 !
Base->hasPlaceholderType(BuiltinType::ArraySection)) {
840 LowerBound =
Result.get();
842 if (Length && Length->getType()->isNonOverloadPlaceholderType()) {
856 if (!
Base->isTypeDependent()) {
863 Diag(
Base->getExprLoc(), diag::err_acc_typecheck_subarray_value)
864 <<
Base->getSourceRange());
868 Diag(
Base->getExprLoc(), diag::err_acc_subarray_function_type)
869 << ResultTy <<
Base->getSourceRange();
874 diag::err_acc_subarray_incomplete_type,
878 if (!
Base->hasPlaceholderType(BuiltinType::ArraySection)) {
889 return Recovery.
isUsable() ? Recovery.
get() :
nullptr;
904 if (Length && !Length->isTypeDependent()) {
907 Length->getExprLoc(), Length);
916 if (!Length && (OriginalBaseTy.
isNull() ||
922 Diag(DiagLoc, diag::err_acc_subarray_no_length) << IsArray;
927 Length = Recovery.
isUsable() ? Recovery.
get() :
nullptr;
938 std::optional<llvm::APSInt> BaseSize;
944 auto GetBoundValue = [&](
Expr *
E) -> std::optional<llvm::APSInt> {
954 std::optional<llvm::APSInt> LowerBoundValue = GetBoundValue(LowerBound);
955 std::optional<llvm::APSInt> LengthValue = GetBoundValue(Length);
958 if (LowerBoundValue.has_value()) {
959 if (LowerBoundValue->isNegative()) {
961 << 0 <<
toString(*LowerBoundValue, 10);
962 LowerBoundValue.reset();
963 LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
964 }
else if (BaseSize.has_value() &&
965 llvm::APSInt::compareValues(*LowerBoundValue, *BaseSize) >= 0) {
967 Diag(LowerBound->
getExprLoc(), diag::err_acc_subarray_out_of_range)
968 << 0 <<
toString(*LowerBoundValue, 10)
970 LowerBoundValue.reset();
971 LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
976 if (LengthValue.has_value()) {
977 if (LengthValue->isNegative()) {
978 Diag(Length->getExprLoc(), diag::err_acc_subarray_negative)
981 Length = GetRecovery(Length, Length->getType());
982 }
else if (BaseSize.has_value() &&
983 llvm::APSInt::compareValues(*LengthValue, *BaseSize) > 0) {
985 Diag(Length->getExprLoc(), diag::err_acc_subarray_out_of_range)
989 Length = GetRecovery(Length, Length->getType());
994 auto AddAPSInt = [](llvm::APSInt LHS, llvm::APSInt RHS) -> llvm::APSInt {
995 if (LHS.isSigned() == RHS.isSigned())
998 unsigned Width = std::max(LHS.getBitWidth(), RHS.getBitWidth()) + 1;
999 return llvm::APSInt(LHS.sext(Width) + RHS.sext(Width),
true);
1004 if (BaseSize.has_value() && LowerBoundValue.has_value() &&
1005 LengthValue.has_value() &&
1006 llvm::APSInt::compareValues(AddAPSInt(*LowerBoundValue, *LengthValue),
1009 diag::err_acc_subarray_base_plus_length_out_of_range)
1014 LowerBoundValue.reset();
1015 LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
1016 LengthValue.reset();
1017 Length = GetRecovery(Length, Length->getType());
1022 if (
Base->isTypeDependent() ||
1024 (Length && Length->isInstantiationDependent()))
1027 return new (Context)
1036 if (!LoopInfo.TopLevelLoopSeen)
1039 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
1040 Diag(WhileLoc, diag::err_acc_invalid_in_loop)
1041 << 1 << CollapseInfo.DirectiveKind
1043 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
1044 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1045 diag::note_acc_active_clause_here)
1050 CollapseInfo.CurCollapseCount = std::nullopt;
1053 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
1054 Diag(WhileLoc, diag::err_acc_invalid_in_loop)
1055 << 1 << TileInfo.DirectiveKind
1057 assert(TileInfo.ActiveTile &&
"tile count without object?");
1058 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
1063 TileInfo.CurTileCount = std::nullopt;
1071 if (!LoopInfo.TopLevelLoopSeen)
1074 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
1075 Diag(DoLoc, diag::err_acc_invalid_in_loop)
1076 << 2 << CollapseInfo.DirectiveKind
1078 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
1079 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1080 diag::note_acc_active_clause_here)
1085 CollapseInfo.CurCollapseCount = std::nullopt;
1088 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
1089 Diag(DoLoc, diag::err_acc_invalid_in_loop)
1091 assert(TileInfo.ActiveTile &&
"tile count without object?");
1092 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
1097 TileInfo.CurTileCount = std::nullopt;
1102 ForStmtBeginChecker &
C) {
1103 assert(
getLangOpts().OpenACC &&
"Check enabled when not OpenACC?");
1106 LoopInfo.TopLevelLoopSeen =
true;
1108 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
1117 if (LoopInfo.CurLevelHasLoopAlready) {
1118 Diag(ForLoc, diag::err_acc_clause_multiple_loops)
1120 assert(CollapseInfo.ActiveCollapse &&
"No collapse object?");
1121 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1122 diag::note_acc_active_clause_here)
1125 --(*CollapseInfo.CurCollapseCount);
1129 if (*CollapseInfo.CurCollapseCount == 0)
1130 CollapseInfo.CollapseDepthSatisfied =
true;
1134 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
1138 if (LoopInfo.CurLevelHasLoopAlready) {
1139 Diag(ForLoc, diag::err_acc_clause_multiple_loops)
1141 assert(TileInfo.ActiveTile &&
"No tile object?");
1142 Diag(TileInfo.ActiveTile->getBeginLoc(),
1143 diag::note_acc_active_clause_here)
1146 TileInfo.CurTileCount = *TileInfo.CurTileCount - 1;
1149 if (*TileInfo.CurTileCount == 0)
1150 TileInfo.TileDepthSatisfied =
true;
1156 LoopInfo.CurLevelHasLoopAlready =
false;
1160bool isValidLoopVariableType(
QualType LoopVarTy) {
1183 for (
const auto *TD :
1184 llvm::make_filter_range(RD->decls(), llvm::IsaPred<TypedefNameDecl>)) {
1185 const auto *TDND = cast<TypedefNameDecl>(TD)->getCanonicalDecl();
1187 if (TDND->getName() !=
"iterator_category")
1191 if (TDND->getUnderlyingType().isNull())
1195 TDND->getUnderlyingType()->getAsCXXRecordDecl();
1198 if (!ItrCategoryDecl)
1201 auto IsRandomAccessIteratorTag = [](
const CXXRecordDecl *RD) {
1202 if (RD->getName() !=
"random_access_iterator_tag")
1208 if (IsRandomAccessIteratorTag(ItrCategoryDecl))
1214 if (IsRandomAccessIteratorTag(BS.getType()->getAsCXXRecordDecl()))
1225 if (
const auto *FE = dyn_cast<FullExpr>(
E))
1226 E = FE->getSubExpr();
1232 if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E))
1233 return dyn_cast<ValueDecl>(DRE->getDecl());
1235 if (
const auto *ME = dyn_cast<MemberExpr>(
E))
1236 if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
1237 return ME->getMemberDecl();
1243void SemaOpenACC::ForStmtBeginChecker::checkRangeFor() {
1244 const RangeForInfo &RFI = std::get<RangeForInfo>(Info);
1246 if (RFI.Uninstantiated == RFI.CurrentVersion)
1250 IsInstantiation ? RFI.Uninstantiated->getBeginStmt() :
nullptr;
1251 const DeclStmt *RangeStmt = RFI.CurrentVersion->getBeginStmt();
1255 if (UninstRangeStmt) {
1260 if (!isValidLoopVariableType(VarType))
1270 if (!isValidLoopVariableType(VarType)) {
1272 <<
SemaRef.LoopWithoutSeqInfo.Kind << VarType;
1274 diag::note_acc_construct_here)
1275 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1280bool SemaOpenACC::ForStmtBeginChecker::checkForInit(
const Stmt *InitStmt,
1287 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1289 diag::note_acc_construct_here)
1290 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1294 auto DiagLoopVar = [
this,
Diag, InitStmt]() {
1297 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1299 diag::note_acc_construct_here)
1300 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1305 if (
const auto *ExprTemp = dyn_cast<ExprWithCleanups>(InitStmt))
1306 InitStmt = ExprTemp->getSubExpr();
1307 if (
const auto *
E = dyn_cast<Expr>(InitStmt))
1311 if (
const auto *BO = dyn_cast<BinaryOperator>(InitStmt)) {
1314 if (!BO->isAssignmentOp())
1315 return DiagLoopVar();
1318 if (
const auto *DRE = dyn_cast<DeclRefExpr>(LHS))
1319 InitVar = DRE->getDecl();
1320 }
else if (
const auto *DS = dyn_cast<DeclStmt>(InitStmt)) {
1322 if (!DS->isSingleDecl())
1323 return DiagLoopVar();
1324 InitVar = dyn_cast<ValueDecl>(DS->getSingleDecl());
1328 if (!isa<VarDecl>(InitVar))
1329 return DiagLoopVar();
1333 !cast<VarDecl>(InitVar)->hasInit())
1334 return DiagLoopVar();
1336 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(InitStmt)) {
1338 if (CE->getOperator() != OO_Equal)
1339 return DiagLoopVar();
1342 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
1343 InitVar = DRE->getDecl();
1344 }
else if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
1345 if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
1346 InitVar = ME->getMemberDecl();
1352 return DiagLoopVar();
1358 if (!isValidLoopVariableType(VarType)) {
1361 <<
SemaRef.LoopWithoutSeqInfo.Kind << VarType;
1363 diag::note_acc_construct_here)
1364 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1372bool SemaOpenACC::ForStmtBeginChecker::checkForCond(
const Stmt *CondStmt,
1378 SemaRef.
Diag(ForLoc, diag::err_acc_loop_terminating_condition)
1379 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1381 diag::note_acc_construct_here)
1382 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1387 auto DiagCondVar = [
this,
Diag, CondStmt] {
1390 diag::err_acc_loop_terminating_condition)
1391 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1393 diag::note_acc_construct_here)
1394 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1399 if (
const auto *ExprTemp = dyn_cast<ExprWithCleanups>(CondStmt))
1400 CondStmt = ExprTemp->getSubExpr();
1401 if (
const auto *
E = dyn_cast<Expr>(CondStmt))
1405 if (
const auto *BO = dyn_cast<BinaryOperator>(CondStmt)) {
1406 switch (BO->getOpcode()) {
1408 return DiagCondVar();
1421 CondVar = getDeclFromExpr(BO->getLHS());
1424 CondVar = getDeclFromExpr(BO->getRHS());
1426 }
else if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(CondStmt)) {
1429 if (!CE->isComparisonOp() || CE->getOperator() == OO_Spaceship)
1430 return DiagCondVar();
1434 CondVar = getDeclFromExpr(CE->getArg(0));
1438 CE->getNumArgs() > 1))
1439 CondVar = getDeclFromExpr(CE->getArg(1));
1441 return DiagCondVar();
1445 return DiagCondVar();
1450 return DiagCondVar();
1459bool isValidForIncRHSAssign(
const ValueDecl *InitVar,
const Expr *RHS) {
1461 auto isValid = [](
const ValueDecl *InitVar,
const Expr *InnerLHS,
1462 const Expr *InnerRHS,
bool IsAddition) {
1464 if (!InnerLHS->getType()->isIntegerType() &&
1465 !InnerRHS->getType()->isIntegerType())
1473 const ValueDecl *LHSDecl = getDeclFromExpr(InnerLHS);
1474 const ValueDecl *RHSDecl = getDeclFromExpr(InnerRHS);
1476 if (!LHSDecl || !RHSDecl)
1492 if (
const auto *BO = dyn_cast<BinaryOperator>(RHS)) {
1494 if (OpC != BO_Add && OpC != BO_Sub)
1496 return isValid(InitVar, BO->getLHS(), BO->getRHS(), OpC == BO_Add);
1497 }
else if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
1499 if (Op != OO_Plus && Op != OO_Minus)
1501 return isValid(InitVar, CE->getArg(0), CE->getArg(1), Op == OO_Plus);
1508bool SemaOpenACC::ForStmtBeginChecker::checkForInc(
const Stmt *IncStmt,
1513 SemaRef.
Diag(ForLoc, diag::err_acc_loop_not_monotonic)
1514 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1516 diag::note_acc_construct_here)
1517 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1521 auto DiagIncVar = [
this,
Diag, IncStmt] {
1524 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1526 diag::note_acc_construct_here)
1527 <<
SemaRef.LoopWithoutSeqInfo.Kind;
1532 if (
const auto *ExprTemp = dyn_cast<ExprWithCleanups>(IncStmt))
1533 IncStmt = ExprTemp->getSubExpr();
1534 if (
const auto *
E = dyn_cast<Expr>(IncStmt))
1539 if (
const auto *UO = dyn_cast<UnaryOperator>(IncStmt)) {
1541 if (!UO->isIncrementDecrementOp())
1542 return DiagIncVar();
1543 IncVar = getDeclFromExpr(UO->getSubExpr());
1544 }
else if (
const auto *BO = dyn_cast<BinaryOperator>(IncStmt)) {
1545 switch (BO->getOpcode()) {
1547 return DiagIncVar();
1554 if (!isValidForIncRHSAssign(InitVar, BO->getRHS()))
1555 return DiagIncVar();
1558 IncVar = getDeclFromExpr(BO->getLHS());
1559 }
else if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(IncStmt)) {
1560 switch (CE->getOperator()) {
1562 return DiagIncVar();
1571 if (!isValidForIncRHSAssign(InitVar, CE->getArg(1)))
1572 return DiagIncVar();
1576 IncVar = getDeclFromExpr(CE->getArg(0));
1578 return DiagIncVar();
1582 return DiagIncVar();
1588 return DiagIncVar();
1593void SemaOpenACC::ForStmtBeginChecker::checkFor() {
1594 const CheckForInfo &CFI = std::get<CheckForInfo>(Info);
1596 if (!IsInstantiation) {
1600 checkForInit(CFI.Current.Init, CurInitVar,
true);
1601 checkForCond(CFI.Current.Condition, CurInitVar,
true);
1602 checkForInc(CFI.Current.Increment, CurInitVar,
true);
1604 const ValueDecl *UninstInitVar =
nullptr;
1608 bool UninstInitFailed =
1609 checkForInit(CFI.Uninst.Init, UninstInitVar,
false);
1615 auto InitChanged = [=]() {
1616 if (CFI.Uninst.Init == CFI.Current.Init)
1622 if (
const auto *DS = dyn_cast<DeclStmt>(CFI.Uninst.Init))
1623 if (
const VarDecl *VD = dyn_cast_if_present<VarDecl>(
1624 DS->isSingleDecl() ? DS->getSingleDecl() :
nullptr))
1625 OldVDTy = VD->getType();
1626 if (
const auto *DS = dyn_cast<DeclStmt>(CFI.Current.Init))
1627 if (
const VarDecl *VD = dyn_cast_if_present<VarDecl>(
1628 DS->isSingleDecl() ? DS->getSingleDecl() :
nullptr))
1629 NewVDTy = VD->getType();
1640 bool ShouldDiagNewInit = !UninstInitFailed && InitChanged();
1642 checkForInit(CFI.Current.Init, CurInitVar, ShouldDiagNewInit);
1646 if (CFI.Uninst.Condition != CFI.Current.Condition &&
1647 !checkForCond(CFI.Uninst.Condition, UninstInitVar,
false))
1648 checkForCond(CFI.Current.Condition, CurInitVar,
true);
1649 if (CFI.Uninst.Increment != CFI.Current.Increment &&
1650 !checkForInc(CFI.Uninst.Increment, UninstInitVar,
false))
1651 checkForInc(CFI.Current.Increment, CurInitVar,
true);
1655void SemaOpenACC::ForStmtBeginChecker::check() {
1666 AlreadyChecked =
true;
1683 if (std::holds_alternative<RangeForInfo>(Info))
1684 return checkRangeFor();
1691 const Stmt *Second,
const Stmt *OldThird,
1692 const Stmt *Third) {
1696 ForStmtBeginChecker FSBC{*
this, ForLoc, OldFirst, OldSecond,
1697 OldThird,
First, Second, Third};
1700 if (!LoopInfo.TopLevelLoopSeen) {
1704 ForStmtBeginHelper(ForLoc, FSBC);
1708 const Stmt *Second,
const Stmt *Third) {
1712 ForStmtBeginChecker FSBC{*
this, ForLoc,
First, Second, Third};
1716 if (!LoopInfo.TopLevelLoopSeen)
1719 ForStmtBeginHelper(ForLoc, FSBC);
1723 const Stmt *OldRangeFor,
1724 const Stmt *RangeFor) {
1725 if (!
getLangOpts().OpenACC || OldRangeFor ==
nullptr || RangeFor ==
nullptr)
1728 ForStmtBeginChecker FSBC{*
this, ForLoc,
1729 cast_if_present<CXXForRangeStmt>(OldRangeFor),
1730 cast_if_present<CXXForRangeStmt>(RangeFor)};
1733 if (!LoopInfo.TopLevelLoopSeen) {
1736 ForStmtBeginHelper(ForLoc, FSBC);
1740 const Stmt *RangeFor) {
1741 if (!
getLangOpts().OpenACC || RangeFor ==
nullptr)
1744 ForStmtBeginChecker FSBC = {*
this, ForLoc,
1745 cast_if_present<CXXForRangeStmt>(RangeFor)};
1749 if (!LoopInfo.TopLevelLoopSeen)
1752 ForStmtBeginHelper(ForLoc, FSBC);
1762 isa<ForStmt, NullStmt, ForStmt, CXXForRangeStmt, WhileStmt, DoStmt>(
1767 if (isa<OpenACCConstructStmt>(CurStmt))
1772 if (
const auto *CS = dyn_cast<CompoundStmt>(CurStmt)) {
1773 for (
const auto *ChildStmt : CS->children()) {
1774 SourceLocation ChildStmtLoc = FindInterveningCodeInLoop(ChildStmt);
1776 return ChildStmtLoc;
1790 LoopInfo.CurLevelHasLoopAlready =
true;
1795 bool IsActiveCollapse = CollapseInfo.CurCollapseCount &&
1796 *CollapseInfo.CurCollapseCount > 0 &&
1797 !CollapseInfo.ActiveCollapse->hasForce();
1798 bool IsActiveTile = TileInfo.CurTileCount && *TileInfo.CurTileCount > 0;
1800 if (IsActiveCollapse || IsActiveTile) {
1803 if (OtherStmtLoc.
isValid() && IsActiveCollapse) {
1804 Diag(OtherStmtLoc, diag::err_acc_intervening_code)
1806 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1807 diag::note_acc_active_clause_here)
1811 if (OtherStmtLoc.
isValid() && IsActiveTile) {
1812 Diag(OtherStmtLoc, diag::err_acc_intervening_code)
1814 Diag(TileInfo.ActiveTile->getBeginLoc(),
1815 diag::note_acc_active_clause_here)
1828 if (isa<RecoveryExpr>(RoutineName)) {
1831 }
else if (isa<DependentScopeDeclRefExpr, CXXDependentScopeMemberExpr>(
1835 }
else if (
auto *DRE = dyn_cast<DeclRefExpr>(RoutineName)) {
1838 if (
auto *FD = dyn_cast<FunctionDecl>(VD))
1842 if (
auto *VarD = dyn_cast<VarDecl>(VD)) {
1846 if (RD->isGenericLambda())
1849 return RD->getLambdaCallOperator();
1856 }
else if (isa<OverloadExpr>(RoutineName)) {
1865 assert(RoutineName &&
"Routine name cannot be null here");
1868 if (isa<RecoveryExpr>(RoutineName)) {
1871 }
else if (isa<DependentScopeDeclRefExpr, CXXDependentScopeMemberExpr>(
1876 }
else if (
const auto *DRE = dyn_cast<DeclRefExpr>(RoutineName)) {
1879 if (isa<FunctionDecl>(VD))
1883 if (
const auto *VarD = dyn_cast<VarDecl>(VD)) {
1887 if (RD->isGenericLambda()) {
1905 }
else if (isa<OverloadExpr>(RoutineName)) {
1927 auto *ContextDecl = dyn_cast<FunctionDecl>(
getCurContext());
1935 for (
const auto *A : ContextDecl->attrs()) {
1936 if (isa<OpenACCRoutineDeclAttr, OpenACCRoutineAnnotAttr>(A)) {
1938 Diag(A->getLocation(), diag::note_acc_construct_here)
1944 MagicStaticLocs.insert({ContextDecl->getCanonicalDecl(), VD->
getBeginLoc()});
1946void SemaOpenACC::CheckLastRoutineDeclNameConflict(
const NamedDecl *ND) {
1955 if (!LastRoutineDecl)
1988 if (NDLine - LastLine > 1)
1996 diag::warn_acc_confusing_routine_name);
2012 if (!RD || !RD->isLambda())
2015 CheckLastRoutineDeclNameConflict(VD);
2021 CheckLastRoutineDeclNameConflict(FD);
2041 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
2042 Diag(StartLoc, diag::err_acc_invalid_in_loop)
2043 << 0 << CollapseInfo.DirectiveKind
2045 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
2046 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
2047 diag::note_acc_active_clause_here)
2050 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
2051 Diag(StartLoc, diag::err_acc_invalid_in_loop)
2052 << 0 << TileInfo.DirectiveKind
2054 assert(TileInfo.ActiveTile &&
"Tile count without object?");
2055 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
2059 if (DiagnoseRequiredClauses(K, StartLoc, Clauses))
2061 return diagnoseConstructAppertainment(*
this, K, StartLoc,
true);
2078 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2085 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2089 getASTContext(), ActiveComputeConstructInfo.Kind, StartLoc, DirLoc,
2090 EndLoc, Clauses, AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2095 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2108 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2112 getASTContext(), StartLoc, DirLoc, LParenLoc, Exprs.front(), MiscLoc,
2113 Exprs.drop_front(), RParenLoc, EndLoc, Clauses);
2133 getASTContext(), StartLoc, DirLoc, AtomicKind, EndLoc, Clauses,
2134 AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
2137 assert(Clauses.empty() &&
"Cache doesn't allow clauses");
2139 LParenLoc, MiscLoc, Exprs, RParenLoc,
2143 llvm_unreachable(
"routine shouldn't handled here");
2148 RParenLoc, EndLoc, Clauses);
2153 llvm_unreachable(
"Unhandled case in directive handling?");
2162 llvm_unreachable(
"Unimplemented associated statement application");
2171 "these don't have associated statements, so shouldn't get here");
2196 if (!isa<CXXForRangeStmt, ForStmt>(AssocStmt.
get())) {
2199 Diag(DirectiveLoc, diag::note_acc_construct_here) << K;
2203 if (!CollapseInfo.CollapseDepthSatisfied || !TileInfo.TileDepthSatisfied) {
2204 if (!CollapseInfo.CollapseDepthSatisfied) {
2205 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
2207 assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
2208 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
2209 diag::note_acc_active_clause_here)
2213 if (!TileInfo.TileDepthSatisfied) {
2214 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
2216 assert(TileInfo.ActiveTile &&
"Collapse count without object?");
2217 Diag(TileInfo.ActiveTile->getBeginLoc(),
2218 diag::note_acc_active_clause_here)
2224 return AssocStmt.
get();
2226 llvm_unreachable(
"Invalid associated statement application");
2234bool CheckValidRoutineGangWorkerVectorSeqClauses(
2246 auto *FirstDeviceType =
2247 llvm::find_if(Clauses, llvm::IsaPred<OpenACCDeviceTypeClause>);
2252 std::find_if(Clauses.begin(), FirstDeviceType, RequiredPred);
2254 if (ClauseItr != FirstDeviceType)
2258 if (FirstDeviceType == Clauses.end())
2259 return SemaRef.
Diag(DirectiveLoc, diag::err_acc_construct_one_clause_of)
2261 <<
"'gang', 'seq', 'vector', or 'worker'";
2265 auto *PrevDeviceType = FirstDeviceType;
2267 while (PrevDeviceType != Clauses.end()) {
2268 auto *NextDeviceType =
2269 std::find_if(std::next(PrevDeviceType), Clauses.end(),
2270 llvm::IsaPred<OpenACCDeviceTypeClause>);
2272 ClauseItr = std::find_if(PrevDeviceType, NextDeviceType, RequiredPred);
2274 if (ClauseItr == NextDeviceType)
2275 return SemaRef.
Diag((*PrevDeviceType)->getBeginLoc(),
2276 diag::err_acc_clause_routine_one_of_in_region);
2278 PrevDeviceType = NextDeviceType;
2294 if (DiagnoseRequiredClauses(K, StartLoc, Clauses))
2297 CheckValidRoutineGangWorkerVectorSeqClauses(*
this, StartLoc, Clauses))
2300 return diagnoseConstructAppertainment(*
this, K, StartLoc,
false);
2313 if (Clauses.empty()) {
2314 Diag(EndLoc, diag::err_acc_declare_required_clauses);
2328 llvm_unreachable(
"routine shouldn't be handled here");
2330 llvm_unreachable(
"unhandled case in directive handling?");
2341 if (
auto *FD = dyn_cast<FunctionDecl>(
D))
2345 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(
D))
2346 return FTD->getTemplatedDecl();
2348 if (
auto *FD = dyn_cast<FieldDecl>(
D)) {
2350 FD->
getType().
isNull() ? nullptr : FD->getType()->getAsCXXRecordDecl();
2352 if (RD && RD->isGenericLambda())
2353 return RD->getDependentLambdaCallOperator()->getTemplatedDecl();
2354 if (RD && RD->isLambda())
2355 return RD->getLambdaCallOperator();
2359 if (
auto *VD = dyn_cast<VarDecl>(
D)) {
2361 if (!
Init ||
Init->getType().isNull())
2364 const auto *RD =
Init->getType()->getAsCXXRecordDecl();
2365 if (RD && RD->isGenericLambda())
2366 return RD->getDependentLambdaCallOperator()->getTemplatedDecl();
2367 if (RD && RD->isLambda())
2368 return RD->getLambdaCallOperator();
2385 OpenACCRoutineDeclAttr *A =
2387 A->Clauses.assign(Clauses.begin(), Clauses.end());
2395 Decl *NextParsedDecl) {
2397 FunctionDecl *NextParsedFDecl = LegalizeNextParsedDecl(NextParsedDecl);
2399 if (!NextParsedFDecl) {
2401 SemaRef.
Diag(DirLoc, diag::err_acc_decl_for_routine);
2409 Itr != MagicStaticLocs.end()) {
2410 Diag(Itr->second, diag::err_acc_magic_static_in_routine);
2411 Diag(DirLoc, diag::note_acc_construct_here)
2417 auto BindItr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCBindClause>);
2418 for (
auto *A : NextParsedFDecl->
attrs()) {
2422 if (
auto *RA = dyn_cast<OpenACCRoutineDeclAttr>(A)) {
2424 llvm::find_if(RA->Clauses, llvm::IsaPred<OpenACCBindClause>);
2425 if (OtherBindItr != RA->Clauses.end() &&
2426 (*cast<OpenACCBindClause>(*BindItr)) !=
2427 (*cast<OpenACCBindClause>(*OtherBindItr))) {
2428 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_unnamed_bind);
2429 Diag((*OtherBindItr)->getEndLoc(), diag::note_acc_previous_clause_here)
2430 << (*BindItr)->getClauseKind();
2441 if (
auto *RA = dyn_cast<OpenACCRoutineAnnotAttr>(A);
2442 RA && RA->getRange().getEnd().isValid()) {
2443 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
2444 Diag(RA->getRange().getEnd(), diag::note_acc_previous_clause_here)
2450 CreateRoutineDeclAttr(*
this, DirLoc, Clauses, NextParsedFDecl);
2460 if (
FunctionDecl *FD = getFunctionFromRoutineName(FuncRef)) {
2464 if (
auto Itr = MagicStaticLocs.find(FD->getCanonicalDecl());
2465 Itr != MagicStaticLocs.end()) {
2466 Diag(Itr->second, diag::err_acc_magic_static_in_routine);
2467 Diag(DirLoc, diag::note_acc_construct_here)
2476 auto BindItr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCBindClause>);
2478 if (BindItr != Clauses.end()) {
2479 BindLoc = (*BindItr)->getBeginLoc();
2483 for (
auto *A : FD->attrs()) {
2484 if (
auto *RA = dyn_cast<OpenACCRoutineDeclAttr>(A)) {
2486 llvm::find_if(RA->Clauses, llvm::IsaPred<OpenACCBindClause>);
2487 if (OtherBindItr != RA->Clauses.end()) {
2488 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
2489 Diag((*OtherBindItr)->getEndLoc(),
2490 diag::note_acc_previous_clause_here)
2491 << (*BindItr)->getClauseKind();
2496 if (
auto *RA = dyn_cast<OpenACCRoutineAnnotAttr>(A);
2497 RA && RA->getRange().getEnd().isValid()) {
2498 Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
2499 Diag(RA->getRange().getEnd(), diag::note_acc_previous_clause_here)
2500 << (*BindItr)->getClauseKind();
2508 auto *RAA = OpenACCRoutineAnnotAttr::CreateImplicit(
getASTContext(),
2513 while (FD != FD->getMostRecentDecl()) {
2514 FD = FD->getMostRecentDecl();
2521 RParenLoc, EndLoc, Clauses);
2525 return LastRoutineDecl;
2533 assert((!ReferencedFunc || !NextDecl) &&
2534 "Only one of these should be filled");
2537 Decl *NextLineDecl =
nullptr;
2538 if (NextDecl && NextDecl.
get().isSingleDecl())
2539 NextLineDecl = NextDecl.
get().getSingleDecl();
2543 return NextDecl.
get();
2547 StartLoc, DirLoc, LParenLoc, ReferencedFunc, RParenLoc, Clauses, EndLoc)};
2555 assert((!ReferencedFunc || !NextStmt) &&
2556 "Only one of these should be filled");
2559 Decl *NextLineDecl =
nullptr;
2562 NextLineDecl = DS->getSingleDecl();
2569 RParenLoc, Clauses, EndLoc)};
2573OpenACCRoutineDeclAttr *
2575 OpenACCRoutineDeclAttr *
New =
2576 OpenACCRoutineDeclAttr::Create(
getASTContext(), Old.getLocation());
2579 New->Clauses = Old.Clauses;
2601 for (
auto *F : RD->fields()) {
2604 Exprs.push_back(NewExpr);
2609 for (uint64_t Idx = 0; Idx < AT->getZExtSize(); ++Idx) {
2611 AT->getElementType()))
2612 Exprs.push_back(NewExpr);
2638 Context, llvm::APInt(Context.
getTypeSize(Ty), 1), Ty,
2643 Expr *InitExpr =
new (Context)
2649std::pair<VarDecl *, VarDecl *>
2652 const Expr *VarExpr) {
2655 while (isa_and_present<ArraySectionExpr, ArraySubscriptExpr>(VarExpr)) {
2656 if (
const auto *AS = dyn_cast<ArraySectionExpr>(VarExpr))
2658 else if (
const auto *Sub = dyn_cast<ArraySubscriptExpr>(VarExpr))
2659 VarExpr = Sub->getBase()->IgnoreParenImpCasts();
2666 return {
nullptr,
nullptr};
2680 llvm_unreachable(
"Unknown clause kind?");
2697 auto FinishValueInit = [&](
Expr *InitExpr) {
2731 Expr *InitExpr =
nullptr;
2733 if (
const auto *ArrTy =
getASTContext().getAsConstantArrayType(VarTy)) {
2743 CK_ArrayToPointerDecay, TemporaryDRE,
nullptr,
2746 for (std::size_t I = 0; I < ArrTy->getLimitedSize(); ++I) {
2774 Args.push_back(ElemRes.
get());
2785 InitExpr = TemporaryDRE;
2788 Init = FinishValueInit(InitExpr);
2793 switch (ReductionOperator) {
2814 Init = FinishValueInit(InitExpr);
2830 Init = FinishValueInit(InitExpr);
2835 llvm_unreachable(
"Unknown clause kind in CreateInitRecipe");
2844 return {Recipe, Temporary};
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.
static Expr * GenerateReductionInitRecipeExpr(ASTContext &Context, SourceRange ExprRange, QualType Ty)
Loops through a type and generates an appropriate InitListExpr to generate type initialization.
This file declares semantic analysis for OpenACC constructs and clauses.
Defines the SourceManager interface.
This file defines OpenACC AST classes for statement-level contructs.
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
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
CanQualType ArraySectionTy
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
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
Represents a base class of a C++ class.
Represents a C++ constructor within a class.
Represents a C++ conversion function within a class.
Represents a C++ struct/union/class.
Represents the canonical version of C arrays with a specified constant size.
llvm::APInt getSize() const
Return the constant array size as an APInt.
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 isStdNamespace() const
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl.
const Decl * getSingleDecl() const
Decl - This represents one declaration (or definition), e.g.
bool isInvalidDecl() const
void setAccess(AccessSpecifier AS)
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.
One of these records is kept for each identifier that is lexed.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
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.
Wrapper for void* pointer.
static OpaquePtr make(PtrTy P)
static OpenACCAsteriskSizeExpr * Create(const ASTContext &C, SourceLocation Loc)
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)
Represents a 'collapse' clause on a 'loop' construct.
const Expr * getLoopCount() const
static OpenACCCombinedConstruct * Create(const ASTContext &C, OpenACCDirectiveKind K, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses, Stmt *StructuredBlock)
static OpenACCComputeConstruct * Create(const ASTContext &C, OpenACCDirectiveKind K, SourceLocation BeginLoc, SourceLocation DirectiveLoc, SourceLocation EndLoc, 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 OpenACCDeclareDecl * Create(ASTContext &Ctx, DeclContext *DC, SourceLocation StartLoc, SourceLocation DirLoc, SourceLocation EndLoc, ArrayRef< const OpenACCClause * > Clauses)
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 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
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)
ArrayRef< Expr * > getSizeExprs()
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 (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.
Represents a struct/union/class.
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.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
DeclContext * getCurContext() const
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)
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...
ComputeConstructInfo & getActiveComputeConstructInfo()
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)
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.
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.
std::pair< VarDecl *, VarDecl * > CreateInitRecipe(OpenACCClauseKind CK, const Expr *VarExpr)
SpecialMemberOverloadResult - The overloading result for a special member function.
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.
Scope * getCurScope() const
Retrieve the parser's current scope.
void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl=nullptr, ExpressionEvaluationContextRecord::ExpressionKind Type=ExpressionEvaluationContextRecord::EK_Other)
ExprResult PerformContextualImplicitConversion(SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter)
Perform a contextual implicit conversion.
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
ASTContext & getASTContext() const
void PopExpressionEvaluationContext()
ExprResult DefaultLvalueConversion(Expr *E)
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc)
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
void DiscardCleanupsInEvaluationContext()
SourceManager & SourceMgr
SpecialMemberOverloadResult LookupSpecialMember(CXXRecordDecl *D, CXXSpecialMemberKind SM, bool ConstArg, bool VolatileArg, bool RValueThis, bool ConstThis, bool VolatileThis)
ExprResult CreateRecoveryExpr(SourceLocation Begin, SourceLocation End, ArrayRef< Expr * > SubExprs, QualType T=QualType())
Attempts to produce a RecoveryExpr after some AST node cannot be created.
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
A trivial tuple used to represent a source range.
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
bool isDependentSizedArrayType() const
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.
@ 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.
@ Result
The result type of a method or function.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
const FunctionProtoType * T
@ 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.