;
29 caseOpenACCDirectiveKind::Invalid:
33 caseOpenACCDirectiveKind::ParallelLoop:
34 caseOpenACCDirectiveKind::SerialLoop:
35 caseOpenACCDirectiveKind::KernelsLoop:
36 caseOpenACCDirectiveKind::Parallel:
37 caseOpenACCDirectiveKind::Serial:
38 caseOpenACCDirectiveKind::Kernels:
39 caseOpenACCDirectiveKind::Loop:
40 caseOpenACCDirectiveKind::Data:
41 caseOpenACCDirectiveKind::EnterData:
42 caseOpenACCDirectiveKind::ExitData:
43 caseOpenACCDirectiveKind::HostData:
44 caseOpenACCDirectiveKind::Wait:
46 returnS.
Diag(StartLoc, diag::err_acc_construct_appertainment) << K;
52voidCollectActiveReductionClauses(
55 for(
auto*CurClause : CurClauses) {
56 if(
auto*RedClause = dyn_cast<OpenACCReductionClause>(CurClause);
57RedClause && !RedClause->getVarList().empty())
58ActiveClauses.push_back(RedClause);
66 caseOpenACCDirectiveKind::Parallel:
67 caseOpenACCDirectiveKind::ParallelLoop:
68 caseOpenACCDirectiveKind::Serial:
69 caseOpenACCDirectiveKind::SerialLoop:
70 caseOpenACCDirectiveKind::Kernels:
71 caseOpenACCDirectiveKind::KernelsLoop:
72 caseOpenACCDirectiveKind::Loop:
74 caseOpenACCDirectiveKind::Data:
75 caseOpenACCDirectiveKind::HostData:
77 caseOpenACCDirectiveKind::EnterData:
78 caseOpenACCDirectiveKind::ExitData:
79 caseOpenACCDirectiveKind::Wait:
80 caseOpenACCDirectiveKind::Init:
81 caseOpenACCDirectiveKind::Shutdown:
82 caseOpenACCDirectiveKind::Set:
83 caseOpenACCDirectiveKind::Update:
84llvm_unreachable(
"Doesn't have an associated stmt");
86 caseOpenACCDirectiveKind::Invalid:
87llvm_unreachable(
"Unhandled directive kind?");
89llvm_unreachable(
"Unhandled directive kind?");
100: SemaRef(S), OldActiveComputeConstructInfo(S.ActiveComputeConstructInfo),
101DirKind(DK), OldLoopGangClauseOnKernel(S.LoopGangClauseOnKernel),
102OldLoopWorkerClauseLoc(S.LoopWorkerClauseLoc),
103OldLoopVectorClauseLoc(S.LoopVectorClauseLoc),
104OldLoopWithoutSeqInfo(S.LoopWithoutSeqInfo),
105ActiveReductionClauses(S.ActiveReductionClauses),
106LoopRAII(SemaRef, PreserveLoopRAIIDepthInAssociatedStmtRAII(DirKind)) {
112CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
113SemaRef.ActiveComputeConstructInfo.Kind = DirKind;
114SemaRef.ActiveComputeConstructInfo.Clauses = Clauses;
129SemaRef.ActiveComputeConstructInfo.Kind = DirKind;
130SemaRef.ActiveComputeConstructInfo.Clauses = Clauses;
132CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
144llvm::find_if(Clauses, llvm::IsaPred<OpenACCSeqClause>))
157 auto*Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCGangClause>);
158 if(Itr != Clauses.end())
162 if(UnInstClauses.empty()) {
163 auto*Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCWorkerClause>);
164 if(Itr != Clauses.end())
167 auto*Itr2 = llvm::find_if(Clauses, llvm::IsaPred<OpenACCVectorClause>);
168 if(Itr2 != Clauses.end())
172CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
180llvm::find_if(Clauses, llvm::IsaPred<OpenACCSeqClause>))
193UnInstClauses.empty()) {
195 auto*Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCGangClause>);
196 if(Itr != Clauses.end())
201 if(UnInstClauses.empty()) {
202 auto*Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCWorkerClause>);
203 if(Itr != Clauses.end())
206 auto*Itr2 = llvm::find_if(Clauses, llvm::IsaPred<OpenACCVectorClause>);
207 if(Itr2 != Clauses.end())
218 SemaRef.LoopInfo.CurLevelHasLoopAlready =
false;
219 SemaRef.CollapseInfo.CollapseDepthSatisfied =
true;
220 SemaRef.TileInfo.TileDepthSatisfied =
true;
227 auto*CollapseClauseItr =
228llvm::find_if(Clauses, llvm::IsaPred<OpenACCCollapseClause>);
229 auto*UnInstCollapseClauseItr =
230llvm::find_if(UnInstClauses, llvm::IsaPred<OpenACCCollapseClause>);
232 if(Clauses.end() == CollapseClauseItr)
236cast<OpenACCCollapseClause>(*CollapseClauseItr);
238 SemaRef.CollapseInfo.ActiveCollapse = CollapseClause;
248 if(UnInstCollapseClauseItr != UnInstClauses.end() &&
249!cast<OpenACCCollapseClause>(*UnInstCollapseClauseItr)
251->isInstantiationDependent())
254 SemaRef.CollapseInfo.CollapseDepthSatisfied =
false;
255 SemaRef.CollapseInfo.CurCollapseCount =
256cast<ConstantExpr>(LoopCount)->getResultAsAPSInt();
257 SemaRef.CollapseInfo.DirectiveKind = DirKind;
266 if(UnInstClauses.size() > 0)
268 auto*TileClauseItr =
269llvm::find_if(Clauses, llvm::IsaPred<OpenACCTileClause>);
271 if(Clauses.end() == TileClauseItr)
275 SemaRef.TileInfo.ActiveTile = TileClause;
276 SemaRef.TileInfo.TileDepthSatisfied =
false;
278 SemaRef.TileInfo.DirectiveKind = DirKind;
289 SemaRef.ActiveComputeConstructInfo = OldActiveComputeConstructInfo;
290 SemaRef.LoopGangClauseOnKernel = OldLoopGangClauseOnKernel;
291 SemaRef.LoopWorkerClauseLoc = OldLoopWorkerClauseLoc;
292 SemaRef.LoopVectorClauseLoc = OldLoopVectorClauseLoc;
293 SemaRef.LoopWithoutSeqInfo = OldLoopWithoutSeqInfo;
294 SemaRef.ActiveReductionClauses.swap(ActiveReductionClauses);
338 Diag(DirLoc, diag::warn_acc_construct_unimplemented) << K;
353 "Only one of directive or clause kind should be provided");
362 unsignedgetDiagKind()
const{
363 if(ClauseKind != OpenACCClauseKind::Invalid)
365 if(DirectiveKind != OpenACCDirectiveKind::Invalid)
373: ICEConvertDiagnoser(
false,
376DirectiveKind(DK), ClauseKind(CK), IntExpr(IntExpr) {}
385 returnS.
Diag(
Loc, diag::err_acc_int_expr_requires_integer)
386<< getDiagKind() << ClauseKind << DirectiveKind <<
T;
391 returnS.
Diag(
Loc, diag::err_acc_int_expr_incomplete_class_type)
398 returnS.
Diag(
Loc, diag::err_acc_int_expr_explicit_conversion)
405 returnS.
Diag(Conv->
getLocation(), diag::note_acc_int_expr_conversion)
411 returnS.
Diag(
Loc, diag::err_acc_int_expr_multiple_conversions) <<
T;
416 returnS.
Diag(Conv->
getLocation(), diag::note_acc_int_expr_conversion)
423llvm_unreachable(
"conversion functions are permitted");
425} IntExprDiagnoser(DK, CK, IntExpr);
431 Loc, IntExpr, IntExprDiagnoser);
435IntExpr = IntExprResult.
get();
457 Diag(VarExpr->
getExprLoc(), diag::note_acc_expected_pointer_var);
469 return Diag(VarExpr->
getExprLoc(), diag::err_acc_var_not_pointer_type)
481isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
482 Diag(VarExpr->
getExprLoc(), diag::err_acc_not_a_var_ref_use_device);
488 while(isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
489 if(
auto*SubScrpt = dyn_cast<ArraySubscriptExpr>(CurVarExpr))
497 if(
const auto*DRE = dyn_cast<DeclRefExpr>(CurVarExpr)) {
498 if(isa<VarDecl, NonTypeTemplateParmDecl>(
499DRE->getFoundDecl()->getCanonicalDecl()))
511 if(
const auto*ME = dyn_cast<MemberExpr>(CurVarExpr)) {
512 if(isa<FieldDecl>(ME->getMemberDecl()->getCanonicalDecl()))
524 if(isa<DependentScopeDeclRefExpr>(CurVarExpr) ||
526isa<CXXDependentScopeMemberExpr>(CurVarExpr)))
531 if(isa<RecoveryExpr>(CurVarExpr))
535 Diag(VarExpr->
getExprLoc(), diag::err_acc_not_a_var_ref_use_device);
550 if(
Base->hasPlaceholderType() &&
551!
Base->hasPlaceholderType(BuiltinType::ArraySection)) {
564LowerBound =
Result.get();
566 if(Length && Length->getType()->isNonOverloadPlaceholderType()) {
580 if(!
Base->isTypeDependent()) {
587 Diag(
Base->getExprLoc(), diag::err_acc_typecheck_subarray_value)
588<<
Base->getSourceRange());
592 Diag(
Base->getExprLoc(), diag::err_acc_subarray_function_type)
593<< ResultTy <<
Base->getSourceRange();
598diag::err_acc_subarray_incomplete_type,
602 if(!
Base->hasPlaceholderType(BuiltinType::ArraySection)) {
613 returnRecovery.
isUsable() ? Recovery.
get() :
nullptr;
625LBRes.
isUsable() ? LBRes.
get() : GetRecovery(LowerBound, Context.
IntTy);
628 if(Length && !Length->isTypeDependent()) {
631Length->getExprLoc(), Length);
636LenRes.
isUsable() ? LenRes.
get() : GetRecovery(Length, Context.
IntTy);
640 if(!Length && (OriginalBaseTy.
isNull() ||
645 Diag(ColonLoc, diag::err_acc_subarray_no_length) << IsArray;
650Length = Recovery.
isUsable() ? Recovery.
get() :
nullptr;
661std::optional<llvm::APSInt> BaseSize;
664BaseSize = ArrayTy->
getSize();
667 autoGetBoundValue = [&](
Expr*
E) -> std::optional<llvm::APSInt> {
677std::optional<llvm::APSInt> LowerBoundValue = GetBoundValue(LowerBound);
678std::optional<llvm::APSInt> LengthValue = GetBoundValue(Length);
681 if(LowerBoundValue.has_value()) {
682 if(LowerBoundValue->isNegative()) {
683 Diag(LowerBound->
getExprLoc(), diag::err_acc_subarray_negative)
684<<
0 <<
toString(*LowerBoundValue,
10);
685LowerBoundValue.reset();
686LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
687}
else if(BaseSize.has_value() &&
688llvm::APSInt::compareValues(*LowerBoundValue, *BaseSize) >= 0) {
690 Diag(LowerBound->
getExprLoc(), diag::err_acc_subarray_out_of_range)
691<<
0 <<
toString(*LowerBoundValue,
10)
693LowerBoundValue.reset();
694LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
699 if(LengthValue.has_value()) {
700 if(LengthValue->isNegative()) {
701 Diag(Length->getExprLoc(), diag::err_acc_subarray_negative)
702<<
1 <<
toString(*LengthValue,
10);
704Length = GetRecovery(Length, Length->getType());
705}
else if(BaseSize.has_value() &&
706llvm::APSInt::compareValues(*LengthValue, *BaseSize) > 0) {
708 Diag(Length->getExprLoc(), diag::err_acc_subarray_out_of_range)
712Length = GetRecovery(Length, Length->getType());
717 autoAddAPSInt = [](llvm::APSInt LHS, llvm::APSInt RHS) -> llvm::APSInt {
718 if(LHS.isSigned() == RHS.isSigned())
721 unsignedWidth = std::max(LHS.getBitWidth(), RHS.getBitWidth()) + 1;
722 returnllvm::APSInt(LHS.sext(Width) + RHS.sext(Width),
true);
727 if(BaseSize.has_value() && LowerBoundValue.has_value() &&
728LengthValue.has_value() &&
729llvm::APSInt::compareValues(AddAPSInt(*LowerBoundValue, *LengthValue),
732diag::err_acc_subarray_base_plus_length_out_of_range)
737LowerBoundValue.reset();
738LowerBound = GetRecovery(LowerBound, LowerBound->
getType());
740Length = GetRecovery(Length, Length->getType());
745 if(
Base->isTypeDependent() ||
747(Length && Length->isInstantiationDependent()))
759 if(!LoopInfo.TopLevelLoopSeen)
762 if(CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
763 Diag(WhileLoc, diag::err_acc_invalid_in_loop)
764<<
1 << CollapseInfo.DirectiveKind
766assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
767 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
768diag::note_acc_active_clause_here)
773CollapseInfo.CurCollapseCount = std::nullopt;
776 if(TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
777 Diag(WhileLoc, diag::err_acc_invalid_in_loop)
778<<
1 << TileInfo.DirectiveKind
780assert(TileInfo.ActiveTile &&
"tile count without object?");
781 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
786TileInfo.CurTileCount = std::nullopt;
794 if(!LoopInfo.TopLevelLoopSeen)
797 if(CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
798 Diag(DoLoc, diag::err_acc_invalid_in_loop)
799<<
2 << CollapseInfo.DirectiveKind
801assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
802 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
803diag::note_acc_active_clause_here)
808CollapseInfo.CurCollapseCount = std::nullopt;
811 if(TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
812 Diag(DoLoc, diag::err_acc_invalid_in_loop)
814assert(TileInfo.ActiveTile &&
"tile count without object?");
815 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
820TileInfo.CurTileCount = std::nullopt;
825ForStmtBeginChecker &
C) {
826assert(
getLangOpts().OpenACC &&
"Check enabled when not OpenACC?");
829LoopInfo.TopLevelLoopSeen =
true;
831 if(CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
839 if(LoopInfo.CurLevelHasLoopAlready) {
840 Diag(ForLoc, diag::err_acc_clause_multiple_loops)
842assert(CollapseInfo.ActiveCollapse &&
"No collapse object?");
843 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
844diag::note_acc_active_clause_here)
847--(*CollapseInfo.CurCollapseCount);
851 if(*CollapseInfo.CurCollapseCount == 0)
852CollapseInfo.CollapseDepthSatisfied =
true;
856 if(TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
859 if(LoopInfo.CurLevelHasLoopAlready) {
860 Diag(ForLoc, diag::err_acc_clause_multiple_loops)
862assert(TileInfo.ActiveTile &&
"No tile object?");
863 Diag(TileInfo.ActiveTile->getBeginLoc(),
864diag::note_acc_active_clause_here)
867--(*TileInfo.CurTileCount);
870 if(*TileInfo.CurTileCount == 0)
871TileInfo.TileDepthSatisfied =
true;
877LoopInfo.CurLevelHasLoopAlready =
false;
881boolisValidLoopVariableType(
QualTypeLoopVarTy) {
904 for(
const auto*TD :
905llvm::make_filter_range(RD->decls(), llvm::IsaPred<TypedefNameDecl>)) {
906 const auto*TDND = cast<TypedefNameDecl>(TD)->getCanonicalDecl();
908 if(TDND->getName() !=
"iterator_category")
912 if(TDND->getUnderlyingType().isNull())
916TDND->getUnderlyingType()->getAsCXXRecordDecl();
919 if(!ItrCategoryDecl)
922 autoIsRandomAccessIteratorTag = [](
const CXXRecordDecl*RD) {
923 if(RD->getName() !=
"random_access_iterator_tag")
929 if(IsRandomAccessIteratorTag(ItrCategoryDecl))
936 if(IsRandomAccessIteratorTag(BS.getType()->getAsCXXRecordDecl()))
949voidSemaOpenACC::ForStmtBeginChecker::check() {
955AlreadyChecked =
true;
975 if(!RangeFor.has_value())
979 const DeclStmt*RangeStmt = (*RangeFor)->getBeginStmt();
988 if(!isValidLoopVariableType(VarType)) {
990<<
SemaRef.LoopWithoutSeqInfo.Kind << VarType;
992diag::note_acc_construct_here)
993<<
SemaRef.LoopWithoutSeqInfo.Kind;
1002 if(Cond.has_value())
1004 if(
Inc.has_value())
1007const ValueDecl*SemaOpenACC::ForStmtBeginChecker::checkInit() {
1010 SemaRef.
Diag(ForLoc, diag::err_acc_loop_variable)
1011<<
SemaRef.LoopWithoutSeqInfo.Kind;
1013diag::note_acc_construct_here)
1014<<
SemaRef.LoopWithoutSeqInfo.Kind;
1019 autoDiagLoopVar = [&]() {
1022<<
SemaRef.LoopWithoutSeqInfo.Kind;
1024diag::note_acc_construct_here)
1025<<
SemaRef.LoopWithoutSeqInfo.Kind;
1030 if(
const auto*ExprTemp = dyn_cast<ExprWithCleanups>(
Init))
1031 Init= ExprTemp->getSubExpr();
1032 if(
const auto*
E= dyn_cast<Expr>(
Init))
1037 if(
const auto*BO = dyn_cast<BinaryOperator>(
Init)) {
1040 if(!BO->isAssignmentOp())
1041 returnDiagLoopVar();
1045 if(
const auto*DRE = dyn_cast<DeclRefExpr>(LHS))
1046InitVar = DRE->getDecl();
1047}
else if(
const auto*DS = dyn_cast<DeclStmt>(
Init)) {
1049 if(!DS->isSingleDecl())
1050 returnDiagLoopVar();
1052InitVar = dyn_cast<ValueDecl>(DS->getSingleDecl());
1057 if(!isa<VarDecl>(InitVar))
1058 returnDiagLoopVar();
1062!cast<VarDecl>(InitVar)->hasInit())
1063 returnDiagLoopVar();
1065}
else if(
auto*CE = dyn_cast<CXXOperatorCallExpr>(
Init)) {
1067 if(CE->getOperator() != OO_Equal)
1068 returnDiagLoopVar();
1072 if(
auto*DRE = dyn_cast<DeclRefExpr>(LHS)) {
1073InitVar = DRE->getDecl();
1074}
else if(
auto*ME = dyn_cast<MemberExpr>(LHS)) {
1075 if(isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
1076InitVar = ME->getMemberDecl();
1081 returnDiagLoopVar();
1087 if(!isValidLoopVariableType(VarType)) {
1090<<
SemaRef.LoopWithoutSeqInfo.Kind << VarType;
1092diag::note_acc_construct_here)
1093<<
SemaRef.LoopWithoutSeqInfo.Kind;
1100voidSemaOpenACC::ForStmtBeginChecker::checkCond() {
1102 SemaRef.
Diag(ForLoc, diag::err_acc_loop_terminating_condition)
1103<<
SemaRef.LoopWithoutSeqInfo.Kind;
1105<<
SemaRef.LoopWithoutSeqInfo.Kind;
1114voidSemaOpenACC::ForStmtBeginChecker::checkInc(
const ValueDecl*
Init) {
1117 SemaRef.
Diag(ForLoc, diag::err_acc_loop_not_monotonic)
1118<<
SemaRef.LoopWithoutSeqInfo.Kind;
1120<<
SemaRef.LoopWithoutSeqInfo.Kind;
1123 autoDiagIncVar = [
this] {
1124 SemaRef.
Diag((*Inc)->getBeginLoc(), diag::err_acc_loop_not_monotonic)
1125<<
SemaRef.LoopWithoutSeqInfo.Kind;
1127<<
SemaRef.LoopWithoutSeqInfo.Kind;
1131 if(
const auto*ExprTemp = dyn_cast<ExprWithCleanups>(*Inc))
1132 Inc= ExprTemp->getSubExpr();
1133 if(
const auto*
E= dyn_cast<Expr>(*Inc))
1138 if(
const auto*FE = dyn_cast<FullExpr>(
E))
1139 E= FE->getSubExpr();
1145 if(
const auto*DRE = dyn_cast<DeclRefExpr>(
E))
1146 returndyn_cast<ValueDecl>(DRE->getDecl());
1148 if(
const auto*ME = dyn_cast<MemberExpr>(
E))
1149 if(isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
1150 returnME->getMemberDecl();
1158 if(
const auto*UO = dyn_cast<UnaryOperator>(*Inc)) {
1160 if(!UO->isIncrementDecrementOp())
1161 returnDiagIncVar();
1163}
else if(
const auto*BO = dyn_cast<BinaryOperator>(*Inc)) {
1164 switch(BO->getOpcode()) {
1166 returnDiagIncVar();
1180}
else if(
const auto*CE = dyn_cast<CXXOperatorCallExpr>(*Inc)) {
1181 switch(CE->getOperator()) {
1183 returnDiagIncVar();
1201}
else if(
const auto*ME = dyn_cast<CXXMemberCallExpr>(*Inc)) {
1208 returnDiagIncVar();
1214 returnDiagIncVar();
1221 const Stmt*Second,
const Stmt*OldThird,
1222 const Stmt*Third) {
1226std::optional<const Stmt *> S;
1227 if(OldSecond == Second)
1231std::optional<const Stmt *>
T;
1232 if(OldThird == Third)
1237 boolInitChanged =
false;
1238 if(OldFirst !=
First) {
1239InitChanged =
true;
1246 if(
const auto*DS = dyn_cast<DeclStmt>(OldFirst))
1247 if(
const VarDecl*VD = dyn_cast_if_present<VarDecl>(
1248DS->isSingleDecl() ? DS->getSingleDecl() :
nullptr))
1249OldVDTy = VD->getType();
1250 if(
const auto*DS = dyn_cast<DeclStmt>(
First))
1251 if(
const VarDecl*VD = dyn_cast_if_present<VarDecl>(
1252DS->isSingleDecl() ? DS->getSingleDecl() :
nullptr))
1253NewVDTy = VD->getType();
1260ForStmtBeginChecker FSBC{*
this, ForLoc,
First, InitChanged, S,
T};
1261 if(!LoopInfo.TopLevelLoopSeen) {
1265ForStmtBeginHelper(ForLoc, FSBC);
1269 const Stmt*Second,
const Stmt*Third) {
1273ForStmtBeginChecker FSBC{*
this, ForLoc,
First,
true,
1275 if(!LoopInfo.TopLevelLoopSeen) {
1279ForStmtBeginHelper(ForLoc, FSBC);
1283 const Stmt*OldRangeFor,
1284 const Stmt*RangeFor) {
1288std::optional<const CXXForRangeStmt *> RF;
1290 if(OldRangeFor == RangeFor)
1293RF = cast<CXXForRangeStmt>(RangeFor);
1295ForStmtBeginChecker FSBC{*
this, ForLoc, RF};
1296 if(!LoopInfo.TopLevelLoopSeen) {
1299ForStmtBeginHelper(ForLoc, FSBC);
1303 const Stmt*RangeFor) {
1307ForStmtBeginChecker FSBC{*
this, ForLoc, cast<CXXForRangeStmt>(RangeFor)};
1308 if(!LoopInfo.TopLevelLoopSeen) {
1311ForStmtBeginHelper(ForLoc, FSBC);
1321isa<ForStmt, NullStmt, ForStmt, CXXForRangeStmt, WhileStmt, DoStmt>(
1326 if(isa<OpenACCConstructStmt>(CurStmt))
1331 if(
const auto*CS = dyn_cast<CompoundStmt>(CurStmt)) {
1332 for(
const auto*ChildStmt : CS->children()) {
1333 SourceLocationChildStmtLoc = FindInterveningCodeInLoop(ChildStmt);
1335 returnChildStmtLoc;
1349LoopInfo.CurLevelHasLoopAlready =
true;
1354 boolIsActiveCollapse = CollapseInfo.CurCollapseCount &&
1355*CollapseInfo.CurCollapseCount > 0 &&
1356!CollapseInfo.ActiveCollapse->hasForce();
1357 boolIsActiveTile = TileInfo.CurTileCount && *TileInfo.CurTileCount > 0;
1359 if(IsActiveCollapse || IsActiveTile) {
1362 if(OtherStmtLoc.
isValid() && IsActiveCollapse) {
1363 Diag(OtherStmtLoc, diag::err_acc_intervening_code)
1365 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1366diag::note_acc_active_clause_here)
1370 if(OtherStmtLoc.
isValid() && IsActiveTile) {
1371 Diag(OtherStmtLoc, diag::err_acc_intervening_code)
1373 Diag(TileInfo.ActiveTile->getBeginLoc(),
1374diag::note_acc_active_clause_here)
1384assert(!Clauses.empty() &&
"empty clause list not supported");
1387llvm::raw_string_ostream OS{Output};
1389 if(Clauses.size() == 1) {
1390OS <<
'\''<< Clauses[0] <<
'\'';
1399[&] { OS <<
", "; });
1401OS <<
" or \'"<< Clauses.back() <<
'\'';
1417 if(CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
1418 Diag(StartLoc, diag::err_acc_invalid_in_loop)
1419<<
0 << CollapseInfo.DirectiveKind
1421assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
1422 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1423diag::note_acc_active_clause_here)
1426 if(TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
1427 Diag(StartLoc, diag::err_acc_invalid_in_loop)
1428<<
0 << TileInfo.DirectiveKind
1430assert(TileInfo.ActiveTile &&
"Tile count without object?");
1431 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
1439llvm::find_if(Clauses,
1445 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1447<< GetListOfClauses(
1457llvm::find_if(Clauses,
1460 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1462<< GetListOfClauses({
1470llvm::find_if(Clauses,
1473 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1475<< GetListOfClauses({
1483llvm::find_if(Clauses, llvm::IsaPred<OpenACCUseDeviceClause>) ==
1485 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1496 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1509 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1515 returndiagnoseConstructAppertainment(*
this, K, StartLoc,
true);
1533AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
1540AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
1544 getASTContext(), ActiveComputeConstructInfo.Kind, StartLoc, DirLoc,
1545EndLoc, Clauses, AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
1550AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
1563AssocStmt.
isUsable() ? AssocStmt.
get() :
nullptr);
1567 getASTContext(), StartLoc, DirLoc, LParenLoc, Exprs.front(), MiscLoc,
1568Exprs.drop_front(), RParenLoc, EndLoc, Clauses);
1587llvm_unreachable(
"Unhandled case in directive handling?");
1595llvm_unreachable(
"Unimplemented associated statement application");
1603 "these don't have associated statements, so shouldn't get here");
1626 if(!isa<CXXForRangeStmt, ForStmt>(AssocStmt.
get())) {
1629 Diag(DirectiveLoc, diag::note_acc_construct_here) << K;
1633 if(!CollapseInfo.CollapseDepthSatisfied || !TileInfo.TileDepthSatisfied) {
1634 if(!CollapseInfo.CollapseDepthSatisfied) {
1635 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
1637assert(CollapseInfo.ActiveCollapse &&
"Collapse count without object?");
1638 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1639diag::note_acc_active_clause_here)
1643 if(!TileInfo.TileDepthSatisfied) {
1644 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
1646assert(TileInfo.ActiveTile &&
"Collapse count without object?");
1647 Diag(TileInfo.ActiveTile->getBeginLoc(),
1648diag::note_acc_active_clause_here)
1654 returnAssocStmt.
get();
1656llvm_unreachable(
"Invalid associated statement application");
1666 returndiagnoseConstructAppertainment(*
this, K, StartLoc,
false);
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 NamedDecl * getDeclFromExpr(Expr *E)
This file declares semantic analysis for OpenACC constructs and clauses.
This file defines OpenACC AST classes for statement-level contructs.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
CanQualType ArraySectionTy
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.
QualType getElementType() const
Represents a base class of a C++ class.
Represents a C++ conversion function within a class.
Represents a C++ struct/union/class.
llvm::APInt getSize() const
Return the constant array size as an APInt.
bool isStdNamespace() const
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
const Decl * getSingleDecl() const
SourceLocation getLocation() const
SourceLocation getBeginLoc() const LLVM_READONLY
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
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, e.g.
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.
static OpenACCAsteriskSizeExpr * Create(const ASTContext &C, SourceLocation Loc)
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)
A 'default' clause, has the optional 'none' or 'present' argument.
A 'device_type' or 'dtype' clause, takes a list of either an 'asterisk' or an identifier.
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)
An 'if' clause, which has a required condition expression.
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)
A 'self' clause, which has an optional condition expression, or, in the event of an 'update' directiv...
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)
llvm::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 getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
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
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 ActOnVar(OpenACCClauseKind CK, Expr *VarExpr)
Called when encountering a 'var' for OpenACC, ensures it is actually a declaration reference to a var...
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 ActOnWhileStmt(SourceLocation WhileLoc)
SourceLocation LoopWorkerClauseLoc
If there is a current 'active' loop construct with a 'worker' clause on it (on any sort of construct)...
bool ActOnStartDeclDirective(OpenACCDirectiveKind K, SourceLocation StartLoc)
Called after the directive, including its clauses, have been parsed and parsing has consumed the 'ann...
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
struct clang::SemaOpenACC::LoopWithoutSeqCheckingInfo LoopWithoutSeqInfo
StmtResult ActOnEndStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc, SourceLocation LParenLoc, SourceLocation MiscLoc, ArrayRef< Expr * > Exprs, SourceLocation RParenLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses, StmtResult AssocStmt)
Called after the directive has been completely parsed, including the declaration group or associated ...
DeclGroupRef ActOnEndDeclDirective()
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)...
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 ActOnRangeForStmtBegin(SourceLocation ForLoc, const Stmt *OldRangeFor, const Stmt *RangeFor)
void ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body)
StmtResult ActOnAssociatedStmt(SourceLocation DirectiveLoc, OpenACCDirectiveKind K, ArrayRef< const OpenACCClause * > Clauses, StmtResult AssocStmt)
Called when we encounter an associated statement for our construct, this should check legality of the...
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.
Sema - This implements semantic analysis and AST building for C.
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)
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...
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
void DiscardCleanupsInEvaluationContext()
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.
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
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isDependentSizedArrayType() const
bool isConstantArrayType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
bool isEnumeralType() 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 isAnyPointerType() const
bool isRecordType() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)
Returns the results of matching Matcher on Node.
bool Inc(InterpState &S, CodePtr OpPC)
1) Pops a pointer from the stack 2) Load the value from the pointer 3) Writes the value increased by ...
The JSON file list parser is used to communicate input to InstallAPI.
@ OK_Ordinary
An ordinary object is located at an address in memory.
OpenACCClauseKind
Represents the kind of an OpenACC clause.
@ DevicePtr
'deviceptr' clause, allowed on Compute and Combined Constructs, plus 'data' and 'declare'.
@ Collapse
'collapse' clause, allowed on 'loop' and Combined constructs.
@ DeviceNum
'device_num' clause, allowed on 'init', 'shutdown', and 'set' constructs.
@ Invalid
Represents an invalid clause, for the purposes of parsing.
@ Copy
'copy' clause, allowed on Compute and Combined Constructs, plus 'data' and 'declare'.
@ Create
'create' clause, allowed on Compute and Combined constructs, plus 'data', 'enter data',...
@ DeviceType
'device_type' clause, allowed on Compute, 'data', 'init', 'shutdown', 'set', update',...
@ DefaultAsync
'default_async' clause, allowed on 'set' construct.
@ Attach
'attach' clause, allowed on Compute and Combined constructs, plus 'data' and 'enter data'.
@ If
'if' clause, allowed on all the Compute Constructs, Data Constructs, Executable Constructs,...
@ Default
'default' clause, allowed on parallel, serial, kernel (and compound) constructs.
@ UseDevice
'use_device' clause, allowed on 'host_data' construct.
@ NoCreate
'no_create' clause, allowed on allowed on Compute and Combined constructs, plus 'data'.
@ Reduction
'reduction' clause, allowed on Parallel, Serial, Loop, and the combined constructs.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ CopyOut
'copyout' clause, allowed on Compute and Combined constructs, plus 'data', 'exit data',...
@ Host
'host' clause, allowed on 'update' construct.
@ Tile
'tile' clause, allowed on 'loop' and Combined constructs.
@ Present
'present' clause, allowed on Compute and Combined constructs, plus 'data' and 'declare'.
@ CopyIn
'copyin' clause, allowed on Compute and Combined constructs, plus 'data', 'enter data',...
@ Device
'device' clause, allowed on the 'update' construct.
@ Detach
'detach' clause, allowed on the 'exit data' construct.
@ Delete
'delete' clause, allowed on the 'exit data' construct.
@ 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
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4