clang: lib/Sema/SemaOpenACC.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
19#include "llvm/ADT/StringExtras.h"
20#include "llvm/Support/Casting.h"
21
22using namespace clang;
23
24namespace {
27 switch (K) {
28 default:
29 case OpenACCDirectiveKind::Invalid:
30
31
32 break;
33 case OpenACCDirectiveKind::ParallelLoop:
34 case OpenACCDirectiveKind::SerialLoop:
35 case OpenACCDirectiveKind::KernelsLoop:
36 case OpenACCDirectiveKind::Parallel:
37 case OpenACCDirectiveKind::Serial:
38 case OpenACCDirectiveKind::Kernels:
39 case OpenACCDirectiveKind::Loop:
40 case OpenACCDirectiveKind::Data:
41 case OpenACCDirectiveKind::EnterData:
42 case OpenACCDirectiveKind::ExitData:
43 case OpenACCDirectiveKind::HostData:
44 case OpenACCDirectiveKind::Wait:
45 if (!IsStmt)
46 return S.Diag(StartLoc, diag::err_acc_construct_appertainment) << K;
47 break;
48 }
49 return false;
50}
51
52void CollectActiveReductionClauses(
55 for (auto *CurClause : CurClauses) {
56 if (auto *RedClause = dyn_cast(CurClause);
57 RedClause && !RedClause->getVarList().empty())
58 ActiveClauses.push_back(RedClause);
59 }
60}
61
62
63
65 switch (DK) {
66 case OpenACCDirectiveKind::Parallel:
67 case OpenACCDirectiveKind::ParallelLoop:
68 case OpenACCDirectiveKind::Serial:
69 case OpenACCDirectiveKind::SerialLoop:
70 case OpenACCDirectiveKind::Kernels:
71 case OpenACCDirectiveKind::KernelsLoop:
72 case OpenACCDirectiveKind::Loop:
73 return false;
74 case OpenACCDirectiveKind::Data:
75 case OpenACCDirectiveKind::HostData:
76 return true;
77 case OpenACCDirectiveKind::EnterData:
78 case OpenACCDirectiveKind::ExitData:
79 case OpenACCDirectiveKind::Wait:
80 case OpenACCDirectiveKind::Init:
81 case OpenACCDirectiveKind::Shutdown:
82 case OpenACCDirectiveKind::Set:
83 case OpenACCDirectiveKind::Update:
84 llvm_unreachable("Doesn't have an associated stmt");
85 default:
86 case OpenACCDirectiveKind::Invalid:
87 llvm_unreachable("Unhandled directive kind?");
88 }
89 llvm_unreachable("Unhandled directive kind?");
90}
91
92}
93
95
100 : SemaRef(S), OldActiveComputeConstructInfo(S.ActiveComputeConstructInfo),
101 DirKind(DK), OldLoopGangClauseOnKernel(S.LoopGangClauseOnKernel),
102 OldLoopWorkerClauseLoc(S.LoopWorkerClauseLoc),
103 OldLoopVectorClauseLoc(S.LoopVectorClauseLoc),
104 OldLoopWithoutSeqInfo(S.LoopWithoutSeqInfo),
105 ActiveReductionClauses(S.ActiveReductionClauses),
106 LoopRAII(SemaRef, PreserveLoopRAIIDepthInAssociatedStmtRAII(DirKind)) {
107
108
112 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
113 SemaRef.ActiveComputeConstructInfo.Kind = DirKind;
114 SemaRef.ActiveComputeConstructInfo.Clauses = Clauses;
115
116
117
118
119
120
121
129 SemaRef.ActiveComputeConstructInfo.Kind = DirKind;
130 SemaRef.ActiveComputeConstructInfo.Clauses = Clauses;
131
132 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
135
139
140
141
143 if (Clauses.end() ==
144 llvm::find_if(Clauses, llvm::IsaPred))
146
147
148
149
150
151
152
153
154
156
157 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred);
158 if (Itr != Clauses.end())
160 }
161
162 if (UnInstClauses.empty()) {
163 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred);
164 if (Itr != Clauses.end())
166
167 auto *Itr2 = llvm::find_if(Clauses, llvm::IsaPred);
168 if (Itr2 != Clauses.end())
170 }
172 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
175
176
177
179 if (Clauses.end() ==
180 llvm::find_if(Clauses, llvm::IsaPred))
182
183
184
185
186
187
188
189
190
193 UnInstClauses.empty()) {
194
195 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred);
196 if (Itr != Clauses.end())
199 }
200
201 if (UnInstClauses.empty()) {
202 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred);
203 if (Itr != Clauses.end())
205
206 auto *Itr2 = llvm::find_if(Clauses, llvm::IsaPred);
207 if (Itr2 != Clauses.end())
209 }
210 }
211}
212
216
217
218 SemaRef.LoopInfo.CurLevelHasLoopAlready = false;
219 SemaRef.CollapseInfo.CollapseDepthSatisfied = true;
220 SemaRef.TileInfo.TileDepthSatisfied = true;
221
222
223
224
225
226
227 auto *CollapseClauseItr =
228 llvm::find_if(Clauses, llvm::IsaPred);
229 auto *UnInstCollapseClauseItr =
230 llvm::find_if(UnInstClauses, llvm::IsaPred);
231
232 if (Clauses.end() == CollapseClauseItr)
233 return;
234
236 cast(*CollapseClauseItr);
237
238 SemaRef.CollapseInfo.ActiveCollapse = CollapseClause;
240
241
242
244 return;
245
246
247
248 if (UnInstCollapseClauseItr != UnInstClauses.end() &&
249 !cast(*UnInstCollapseClauseItr)
250 ->getLoopCount()
251 ->isInstantiationDependent())
252 return;
253
254 SemaRef.CollapseInfo.CollapseDepthSatisfied = false;
255 SemaRef.CollapseInfo.CurCollapseCount =
256 cast(LoopCount)->getResultAsAPSInt();
257 SemaRef.CollapseInfo.DirectiveKind = DirKind;
258}
259
263
264
265
266 if (UnInstClauses.size() > 0)
267 return;
268 auto *TileClauseItr =
269 llvm::find_if(Clauses, llvm::IsaPred);
270
271 if (Clauses.end() == TileClauseItr)
272 return;
273
274 OpenACCTileClause *TileClause = cast(*TileClauseItr);
275 SemaRef.TileInfo.ActiveTile = TileClause;
276 SemaRef.TileInfo.TileDepthSatisfied = false;
278 SemaRef.TileInfo.DirectiveKind = DirKind;
279}
280
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);
297
298
299 }
300}
301
304
307
308 switch (K) {
310
311
312
313
314 break;
330
331
332 break;
334
335
336 break;
337 default:
338 Diag(DirLoc, diag::warn_acc_construct_unimplemented) << K;
339 break;
340 }
341}
342
345 Expr *IntExpr) {
346
353 "Only one of directive or clause kind should be provided");
354
358 Expr *IntExpr;
359
360
361
362 unsigned getDiagKind() const {
363 if (ClauseKind != OpenACCClauseKind::Invalid)
364 return 0;
365 if (DirectiveKind != OpenACCDirectiveKind::Invalid)
366 return 1;
367 return 2;
368 }
369
370 public:
372 Expr *IntExpr)
373 : ICEConvertDiagnoser(false,
374 false,
375 true),
376 DirectiveKind(DK), ClauseKind(CK), IntExpr(IntExpr) {}
377
379
380
382 }
385 return S.Diag(Loc, diag::err_acc_int_expr_requires_integer)
386 << getDiagKind() << ClauseKind << DirectiveKind << T;
387 }
388
391 return S.Diag(Loc, diag::err_acc_int_expr_incomplete_class_type)
393 }
394
398 return S.Diag(Loc, diag::err_acc_int_expr_explicit_conversion)
399 << T << ConvTy;
400 }
401
405 return S.Diag(Conv->getLocation(), diag::note_acc_int_expr_conversion)
407 }
408
411 return S.Diag(Loc, diag::err_acc_int_expr_multiple_conversions) << T;
412 }
413
416 return S.Diag(Conv->getLocation(), diag::note_acc_int_expr_conversion)
418 }
419
423 llvm_unreachable("conversion functions are permitted");
424 }
425 } IntExprDiagnoser(DK, CK, IntExpr);
426
427 if (!IntExpr)
429
431 Loc, IntExpr, IntExprDiagnoser);
434
435 IntExpr = IntExprResult.get();
438
439
440
441 return IntExpr;
442}
443
445 Expr *VarExpr) {
446
447
448
449
450
452 return false;
453
456 Diag(VarExpr->getExprLoc(), diag::err_array_section_use) << 0;
457 Diag(VarExpr->getExprLoc(), diag::note_acc_expected_pointer_var);
458 return true;
459 }
460
463
464
466 return false;
467
469 return Diag(VarExpr->getExprLoc(), diag::err_acc_var_not_pointer_type)
470 << ClauseKind << Ty;
471 return false;
472}
473
476
477
478
479
481 isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
482 Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref_use_device);
484 }
485
486
487
488 while (isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
489 if (auto *SubScrpt = dyn_cast(CurVarExpr))
491 else
492 CurVarExpr =
494 }
495
496
497 if (const auto *DRE = dyn_cast(CurVarExpr)) {
498 if (isa<VarDecl, NonTypeTemplateParmDecl>(
499 DRE->getFoundDecl()->getCanonicalDecl()))
500 return VarExpr;
501 }
502
503
504
505
506
507
508
511 if (const auto *ME = dyn_cast(CurVarExpr)) {
512 if (isa(ME->getMemberDecl()->getCanonicalDecl()))
513 return VarExpr;
514 }
515 }
516
517
518
520 return VarExpr;
521
522
523
524 if (isa(CurVarExpr) ||
526 isa(CurVarExpr)))
527 return VarExpr;
528
529
530
531 if (isa(CurVarExpr))
533
535 Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref_use_device);
536 else
537 Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref)
540}
541
543 Expr *LowerBound,
545 Expr *Length,
548
549
550 if (Base->hasPlaceholderType() &&
551 ->hasPlaceholderType(BuiltinType::ArraySection)) {
553 if (Result.isInvalid())
556 }
559 if (Result.isInvalid())
562 if (Result.isInvalid())
564 LowerBound = Result.get();
565 }
566 if (Length && Length->getType()->isNonOverloadPlaceholderType()) {
568 if (Result.isInvalid())
571 if (Result.isInvalid())
573 Length = Result.get();
574 }
575
576
577
580 if (->isTypeDependent()) {
583 } else if (OriginalBaseTy->isArrayType()) {
585 } else {
587 Diag(Base->getExprLoc(), diag::err_acc_typecheck_subarray_value)
588 << Base->getSourceRange());
589 }
590
592 Diag(Base->getExprLoc(), diag::err_acc_subarray_function_type)
593 << ResultTy << Base->getSourceRange();
595 }
596
598 diag::err_acc_subarray_incomplete_type,
601
602 if (->hasPlaceholderType(BuiltinType::ArraySection)) {
604 if (Result.isInvalid())
607 }
608 }
609
613 return Recovery.isUsable() ? Recovery.get() : nullptr;
614 };
615
616
620 LowerBound->getExprLoc(), LowerBound);
621
624 LowerBound =
625 LBRes.isUsable() ? LBRes.get() : GetRecovery(LowerBound, Context.IntTy);
626 }
627
628 if (Length && !Length->isTypeDependent()) {
631 Length->getExprLoc(), Length);
632
635 Length =
636 LenRes.isUsable() ? LenRes.get() : GetRecovery(Length, Context.IntTy);
637 }
638
639
640 if (!Length && (OriginalBaseTy.isNull() ||
644 bool IsArray = !OriginalBaseTy.isNull() && OriginalBaseTy->isArrayType();
645 Diag(ColonLoc, diag::err_acc_subarray_no_length) << IsArray;
646
647
650 Length = Recovery.isUsable() ? Recovery.get() : nullptr;
651 }
652
653
654
655
656
657
658
659
660
661 std::optionalllvm::APSInt BaseSize;
664 BaseSize = ArrayTy->getSize();
665 }
666
667 auto GetBoundValue = [&](Expr *E) -> std::optionalllvm::APSInt {
669 return std::nullopt;
670
673 return std::nullopt;
675 };
676
677 std::optionalllvm::APSInt LowerBoundValue = GetBoundValue(LowerBound);
678 std::optionalllvm::APSInt LengthValue = GetBoundValue(Length);
679
680
681 if (LowerBoundValue.has_value()) {
682 if (LowerBoundValue->isNegative()) {
683 Diag(LowerBound->getExprLoc(), diag::err_acc_subarray_negative)
684 << 0 << toString(*LowerBoundValue, 10);
685 LowerBoundValue.reset();
686 LowerBound = GetRecovery(LowerBound, LowerBound->getType());
687 } else if (BaseSize.has_value() &&
688 llvm::APSInt::compareValues(*LowerBoundValue, *BaseSize) >= 0) {
689
690 Diag(LowerBound->getExprLoc(), diag::err_acc_subarray_out_of_range)
691 << 0 << toString(*LowerBoundValue, 10)
692 << toString(*BaseSize, 10);
693 LowerBoundValue.reset();
694 LowerBound = GetRecovery(LowerBound, LowerBound->getType());
695 }
696 }
697
698
699 if (LengthValue.has_value()) {
700 if (LengthValue->isNegative()) {
701 Diag(Length->getExprLoc(), diag::err_acc_subarray_negative)
702 << 1 << toString(*LengthValue, 10);
703 LengthValue.reset();
704 Length = GetRecovery(Length, Length->getType());
705 } else if (BaseSize.has_value() &&
706 llvm::APSInt::compareValues(*LengthValue, *BaseSize) > 0) {
707
708 Diag(Length->getExprLoc(), diag::err_acc_subarray_out_of_range)
709 << 1 << toString(*LengthValue, 10)
710 << toString(*BaseSize, 10);
711 LengthValue.reset();
712 Length = GetRecovery(Length, Length->getType());
713 }
714 }
715
716
717 auto AddAPSInt = [](llvm::APSInt LHS, llvm::APSInt RHS) -> llvm::APSInt {
718 if (LHS.isSigned() == RHS.isSigned())
719 return LHS + RHS;
720
721 unsigned Width = std::max(LHS.getBitWidth(), RHS.getBitWidth()) + 1;
722 return llvm::APSInt(LHS.sext(Width) + RHS.sext(Width), true);
723 };
724
725
726
727 if (BaseSize.has_value() && LowerBoundValue.has_value() &&
728 LengthValue.has_value() &&
729 llvm::APSInt::compareValues(AddAPSInt(*LowerBoundValue, *LengthValue),
730 *BaseSize) > 0) {
732 diag::err_acc_subarray_base_plus_length_out_of_range)
733 << toString(*LowerBoundValue, 10)
734 << toString(*LengthValue, 10)
735 << toString(*BaseSize, 10);
736
737 LowerBoundValue.reset();
738 LowerBound = GetRecovery(LowerBound, LowerBound->getType());
739 LengthValue.reset();
740 Length = GetRecovery(Length, Length->getType());
741 }
742
743
745 if (Base->isTypeDependent() ||
747 (Length && Length->isInstantiationDependent()))
749
750 return new (Context)
753}
754
757 return;
758
759 if (!LoopInfo.TopLevelLoopSeen)
760 return;
761
762 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
763 Diag(WhileLoc, diag::err_acc_invalid_in_loop)
764 << 1 << CollapseInfo.DirectiveKind
766 assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");
767 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
768 diag::note_acc_active_clause_here)
770
771
772
773 CollapseInfo.CurCollapseCount = std::nullopt;
774 }
775
776 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
777 Diag(WhileLoc, diag::err_acc_invalid_in_loop)
778 << 1 << TileInfo.DirectiveKind
780 assert(TileInfo.ActiveTile && "tile count without object?");
781 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
783
784
785
786 TileInfo.CurTileCount = std::nullopt;
787 }
788}
789
792 return;
793
794 if (!LoopInfo.TopLevelLoopSeen)
795 return;
796
797 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
798 Diag(DoLoc, diag::err_acc_invalid_in_loop)
799 << 2 << CollapseInfo.DirectiveKind
801 assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");
802 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
803 diag::note_acc_active_clause_here)
805
806
807
808 CollapseInfo.CurCollapseCount = std::nullopt;
809 }
810
811 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
812 Diag(DoLoc, diag::err_acc_invalid_in_loop)
814 assert(TileInfo.ActiveTile && "tile count without object?");
815 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
817
818
819
820 TileInfo.CurTileCount = std::nullopt;
821 }
822}
823
824void SemaOpenACC::ForStmtBeginHelper(SourceLocation ForLoc,
825 ForStmtBeginChecker &C) {
826 assert(getLangOpts().OpenACC && "Check enabled when not OpenACC?");
827
828
829 LoopInfo.TopLevelLoopSeen = true;
830
831 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
832 C.check();
833
834
835
836
837
838
839 if (LoopInfo.CurLevelHasLoopAlready) {
840 Diag(ForLoc, diag::err_acc_clause_multiple_loops)
842 assert(CollapseInfo.ActiveCollapse && "No collapse object?");
843 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
844 diag::note_acc_active_clause_here)
846 } else {
847 --(*CollapseInfo.CurCollapseCount);
848
849
850
851 if (*CollapseInfo.CurCollapseCount == 0)
852 CollapseInfo.CollapseDepthSatisfied = true;
853 }
854 }
855
856 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
857 C.check();
858
859 if (LoopInfo.CurLevelHasLoopAlready) {
860 Diag(ForLoc, diag::err_acc_clause_multiple_loops)
862 assert(TileInfo.ActiveTile && "No tile object?");
863 Diag(TileInfo.ActiveTile->getBeginLoc(),
864 diag::note_acc_active_clause_here)
866 } else {
867 --(*TileInfo.CurTileCount);
868
869
870 if (*TileInfo.CurTileCount == 0)
871 TileInfo.TileDepthSatisfied = true;
872 }
873 }
874
875
876
877 LoopInfo.CurLevelHasLoopAlready = false;
878}
879
880namespace {
881bool isValidLoopVariableType(QualType LoopVarTy) {
882
884 return true;
885
886
888 return true;
889
890
892 return true;
893
894
896
897
898
899
900
901
902
903
904 for (const auto *TD :
905 llvm::make_filter_range(RD->decls(), llvm::IsaPred)) {
906 const auto *TDND = cast(TD)->getCanonicalDecl();
907
908 if (TDND->getName() != "iterator_category")
909 continue;
910
911
912 if (TDND->getUnderlyingType().isNull())
913 return false;
914
916 TDND->getUnderlyingType()->getAsCXXRecordDecl();
917
918
919 if (!ItrCategoryDecl)
920 return false;
921
922 auto IsRandomAccessIteratorTag = [](const CXXRecordDecl *RD) {
923 if (RD->getName() != "random_access_iterator_tag")
924 return false;
925
927 };
928
929 if (IsRandomAccessIteratorTag(ItrCategoryDecl))
930 return true;
931
932
933
935
936 if (IsRandomAccessIteratorTag(BS.getType()->getAsCXXRecordDecl()))
937 return true;
938 }
939
940 return false;
941 }
942 }
943
944 return false;
945}
946
947}
948
949void SemaOpenACC::ForStmtBeginChecker::check() {
951 return;
952
953 if (AlreadyChecked)
954 return;
955 AlreadyChecked = true;
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972 if (IsRangeFor) {
973
974
975 if (!RangeFor.has_value())
976 return;
977
978
979 const DeclStmt *RangeStmt = (*RangeFor)->getBeginStmt();
980
981
982
983 if (!RangeStmt)
984 return;
985
988 if (!isValidLoopVariableType(VarType)) {
990 << SemaRef.LoopWithoutSeqInfo.Kind << VarType;
992 diag::note_acc_construct_here)
993 << SemaRef.LoopWithoutSeqInfo.Kind;
994 }
995 return;
996 }
997
998
999
1000
1001 const ValueDecl *InitVar = checkInit();
1002 if (Cond.has_value())
1003 checkCond();
1004 if (Inc.has_value())
1005 checkInc(InitVar);
1006}
1007const ValueDecl *SemaOpenACC::ForStmtBeginChecker::checkInit() {
1008 if () {
1009 if (InitChanged) {
1010 SemaRef.Diag(ForLoc, diag::err_acc_loop_variable)
1011 << SemaRef.LoopWithoutSeqInfo.Kind;
1013 diag::note_acc_construct_here)
1014 << SemaRef.LoopWithoutSeqInfo.Kind;
1015 }
1016 return nullptr;
1017 }
1018
1019 auto DiagLoopVar = [&]() {
1020 if (InitChanged) {
1021 SemaRef.Diag(Init->getBeginLoc(), diag::err_acc_loop_variable)
1022 << SemaRef.LoopWithoutSeqInfo.Kind;
1024 diag::note_acc_construct_here)
1025 << SemaRef.LoopWithoutSeqInfo.Kind;
1026 }
1027 return nullptr;
1028 };
1029
1030 if (const auto *ExprTemp = dyn_cast(Init))
1031 Init = ExprTemp->getSubExpr();
1032 if (const auto *E = dyn_cast(Init))
1034
1035 const ValueDecl *InitVar = nullptr;
1036
1037 if (const auto *BO = dyn_cast(Init)) {
1038
1039
1040 if (!BO->isAssignmentOp())
1041 return DiagLoopVar();
1042
1044
1045 if (const auto *DRE = dyn_cast(LHS))
1046 InitVar = DRE->getDecl();
1047 } else if (const auto *DS = dyn_cast(Init)) {
1048
1049 if (!DS->isSingleDecl())
1050 return DiagLoopVar();
1051
1052 InitVar = dyn_cast(DS->getSingleDecl());
1053
1054
1055
1056 if (InitVar) {
1057 if (!isa(InitVar))
1058 return DiagLoopVar();
1059
1062 !cast(InitVar)->hasInit())
1063 return DiagLoopVar();
1064 }
1065 } else if (auto *CE = dyn_cast(Init)) {
1066
1067 if (CE->getOperator() != OO_Equal)
1068 return DiagLoopVar();
1069
1071
1072 if (auto *DRE = dyn_cast(LHS)) {
1073 InitVar = DRE->getDecl();
1074 } else if (auto *ME = dyn_cast(LHS)) {
1075 if (isa(ME->getBase()->IgnoreParenImpCasts()))
1076 InitVar = ME->getMemberDecl();
1077 }
1078 }
1079
1080 if (!InitVar)
1081 return DiagLoopVar();
1082
1085
1086
1087 if (!isValidLoopVariableType(VarType)) {
1088 if (InitChanged) {
1090 << SemaRef.LoopWithoutSeqInfo.Kind << VarType;
1092 diag::note_acc_construct_here)
1093 << SemaRef.LoopWithoutSeqInfo.Kind;
1094 }
1095 return nullptr;
1096 }
1097
1098 return InitVar;
1099}
1100void SemaOpenACC::ForStmtBeginChecker::checkCond() {
1101 if (!*Cond) {
1102 SemaRef.Diag(ForLoc, diag::err_acc_loop_terminating_condition)
1103 << SemaRef.LoopWithoutSeqInfo.Kind;
1104 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc, diag::note_acc_construct_here)
1105 << SemaRef.LoopWithoutSeqInfo.Kind;
1106 }
1107
1108
1109
1110
1111
1112}
1113
1114void SemaOpenACC::ForStmtBeginChecker::checkInc(const ValueDecl *Init) {
1115
1116 if (!*Inc) {
1117 SemaRef.Diag(ForLoc, diag::err_acc_loop_not_monotonic)
1118 << SemaRef.LoopWithoutSeqInfo.Kind;
1119 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc, diag::note_acc_construct_here)
1120 << SemaRef.LoopWithoutSeqInfo.Kind;
1121 return;
1122 }
1123 auto DiagIncVar = [this] {
1124 SemaRef.Diag((*Inc)->getBeginLoc(), diag::err_acc_loop_not_monotonic)
1125 << SemaRef.LoopWithoutSeqInfo.Kind;
1126 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc, diag::note_acc_construct_here)
1127 << SemaRef.LoopWithoutSeqInfo.Kind;
1128 return;
1129 };
1130
1131 if (const auto *ExprTemp = dyn_cast(*Inc))
1132 Inc = ExprTemp->getSubExpr();
1133 if (const auto *E = dyn_cast(*Inc))
1135
1138 if (const auto *FE = dyn_cast(E))
1139 E = FE->getSubExpr();
1140
1142
1143 if ()
1144 return nullptr;
1145 if (const auto *DRE = dyn_cast(E))
1146 return dyn_cast(DRE->getDecl());
1147
1148 if (const auto *ME = dyn_cast(E))
1149 if (isa(ME->getBase()->IgnoreParenImpCasts()))
1150 return ME->getMemberDecl();
1151
1152 return nullptr;
1153 };
1154
1155 const ValueDecl *IncVar = nullptr;
1156
1157
1158 if (const auto *UO = dyn_cast(*Inc)) {
1159
1160 if (!UO->isIncrementDecrementOp())
1161 return DiagIncVar();
1163 } else if (const auto *BO = dyn_cast(*Inc)) {
1164 switch (BO->getOpcode()) {
1165 default:
1166 return DiagIncVar();
1167 case BO_AddAssign:
1168 case BO_SubAssign:
1169 case BO_MulAssign:
1170 case BO_DivAssign:
1171 case BO_Assign:
1172
1173
1174
1175
1176
1177 break;
1178 }
1180 } else if (const auto *CE = dyn_cast(*Inc)) {
1181 switch (CE->getOperator()) {
1182 default:
1183 return DiagIncVar();
1184 case OO_PlusPlus:
1185 case OO_MinusMinus:
1186 case OO_PlusEqual:
1187 case OO_MinusEqual:
1188 case OO_StarEqual:
1189 case OO_SlashEqual:
1190 case OO_Equal:
1191
1192
1193
1194
1195
1196 break;
1197 }
1198
1200
1201 } else if (const auto *ME = dyn_cast(*Inc)) {
1202 IncVar = getDeclFromExpr(ME->getImplicitObjectArgument());
1203
1204
1205 }
1206
1207 if (!IncVar)
1208 return DiagIncVar();
1209
1210
1211
1212
1214 return DiagIncVar();
1215
1216 return;
1217}
1218
1221 const Stmt *Second, const Stmt *OldThird,
1222 const Stmt *Third) {
1224 return;
1225
1226 std::optional<const Stmt *> S;
1227 if (OldSecond == Second)
1228 S = std::nullopt;
1229 else
1230 S = Second;
1231 std::optional<const Stmt *> T;
1232 if (OldThird == Third)
1233 S = std::nullopt;
1234 else
1235 S = Third;
1236
1237 bool InitChanged = false;
1238 if (OldFirst != First) {
1239 InitChanged = true;
1240
1241
1242
1243
1246 if (const auto *DS = dyn_cast(OldFirst))
1247 if (const VarDecl *VD = dyn_cast_if_present(
1248 DS->isSingleDecl() ? DS->getSingleDecl() : nullptr))
1249 OldVDTy = VD->getType();
1250 if (const auto *DS = dyn_cast(First))
1251 if (const VarDecl *VD = dyn_cast_if_present(
1252 DS->isSingleDecl() ? DS->getSingleDecl() : nullptr))
1253 NewVDTy = VD->getType();
1254
1258 }
1259
1260 ForStmtBeginChecker FSBC{*this, ForLoc, First, InitChanged, S, T};
1261 if (!LoopInfo.TopLevelLoopSeen) {
1262 FSBC.check();
1263 }
1264
1265 ForStmtBeginHelper(ForLoc, FSBC);
1266}
1267
1269 const Stmt *Second, const Stmt *Third) {
1271 return;
1272
1273 ForStmtBeginChecker FSBC{*this, ForLoc, First, true,
1274 Second, Third};
1275 if (!LoopInfo.TopLevelLoopSeen) {
1276 FSBC.check();
1277 }
1278
1279 ForStmtBeginHelper(ForLoc, FSBC);
1280}
1281
1283 const Stmt *OldRangeFor,
1284 const Stmt *RangeFor) {
1286 return;
1287
1288 std::optional<const CXXForRangeStmt *> RF;
1289
1290 if (OldRangeFor == RangeFor)
1291 RF = std::nullopt;
1292 else
1293 RF = cast(RangeFor);
1294
1295 ForStmtBeginChecker FSBC{*this, ForLoc, RF};
1296 if (!LoopInfo.TopLevelLoopSeen) {
1297 FSBC.check();
1298 }
1299 ForStmtBeginHelper(ForLoc, FSBC);
1300}
1301
1303 const Stmt *RangeFor) {
1305 return;
1306
1307 ForStmtBeginChecker FSBC{*this, ForLoc, cast(RangeFor)};
1308 if (!LoopInfo.TopLevelLoopSeen) {
1309 FSBC.check();
1310 }
1311 ForStmtBeginHelper(ForLoc, FSBC);
1312}
1313
1314namespace {
1316
1317
1318
1319
1320 if (!CurStmt ||
1321 isa<ForStmt, NullStmt, ForStmt, CXXForRangeStmt, WhileStmt, DoStmt>(
1322 CurStmt))
1324
1325
1326 if (isa(CurStmt))
1328
1329
1330
1331 if (const auto *CS = dyn_cast(CurStmt)) {
1332 for (const auto *ChildStmt : CS->children()) {
1333 SourceLocation ChildStmtLoc = FindInterveningCodeInLoop(ChildStmt);
1334 if (ChildStmtLoc.isValid())
1335 return ChildStmtLoc;
1336 }
1337
1339 }
1341}
1342}
1343
1346 return;
1347
1348
1349 LoopInfo.CurLevelHasLoopAlready = true;
1350
1352 return;
1353
1354 bool IsActiveCollapse = CollapseInfo.CurCollapseCount &&
1355 *CollapseInfo.CurCollapseCount > 0 &&
1356 !CollapseInfo.ActiveCollapse->hasForce();
1357 bool IsActiveTile = TileInfo.CurTileCount && *TileInfo.CurTileCount > 0;
1358
1359 if (IsActiveCollapse || IsActiveTile) {
1360 SourceLocation OtherStmtLoc = FindInterveningCodeInLoop(Body.get());
1361
1362 if (OtherStmtLoc.isValid() && IsActiveCollapse) {
1363 Diag(OtherStmtLoc, diag::err_acc_intervening_code)
1365 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1366 diag::note_acc_active_clause_here)
1368 }
1369
1370 if (OtherStmtLoc.isValid() && IsActiveTile) {
1371 Diag(OtherStmtLoc, diag::err_acc_intervening_code)
1373 Diag(TileInfo.ActiveTile->getBeginLoc(),
1374 diag::note_acc_active_clause_here)
1376 }
1377 }
1378}
1379
1380namespace {
1381
1382
1384 assert(!Clauses.empty() && "empty clause list not supported");
1385
1386 std::string Output;
1387 llvm::raw_string_ostream OS{Output};
1388
1389 if (Clauses.size() == 1) {
1390 OS << '\'' << Clauses[0] << '\'';
1391 return Output;
1392 }
1393
1395 Clauses.end() - 1};
1396
1397 llvm::interleave(
1398 AllButLast, [&](OpenACCClauseKind K) { OS << '\'' << K << '\''; },
1399 [&] { OS << ", "; });
1400
1401 OS << " or \'" << Clauses.back() << '\'';
1402 return Output;
1403}
1404}
1405
1411
1412
1413
1414
1415
1416
1417 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
1418 Diag(StartLoc, diag::err_acc_invalid_in_loop)
1419 << 0 << CollapseInfo.DirectiveKind
1421 assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");
1422 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1423 diag::note_acc_active_clause_here)
1425 }
1426 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
1427 Diag(StartLoc, diag::err_acc_invalid_in_loop)
1428 << 0 << TileInfo.DirectiveKind
1430 assert(TileInfo.ActiveTile && "Tile count without object?");
1431 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
1433 }
1434
1435
1436
1437
1439 llvm::find_if(Clauses,
1445 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1446 << K
1447 << GetListOfClauses(
1453
1454
1455
1457 llvm::find_if(Clauses,
1460 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1461 << K
1462 << GetListOfClauses({
1466 });
1467
1468
1470 llvm::find_if(Clauses,
1473 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1474 << K
1475 << GetListOfClauses({
1479 });
1480
1481
1483 llvm::find_if(Clauses, llvm::IsaPred) ==
1484 Clauses.end())
1485 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1487
1488
1489
1491 llvm::find_if(
1492 Clauses,
1495 Clauses.end())
1496 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1497 << K
1502
1503
1504
1508 Clauses.end())
1509 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1510 << K
1514
1515 return diagnoseConstructAppertainment(*this, K, StartLoc, true);
1516}
1517
1523 switch (K) {
1524 default:
1532 getASTContext(), K, StartLoc, DirLoc, EndLoc, Clauses,
1533 AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
1534 }
1539 getASTContext(), K, StartLoc, DirLoc, EndLoc, Clauses,
1540 AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
1541 }
1544 getASTContext(), ActiveComputeConstructInfo.Kind, StartLoc, DirLoc,
1545 EndLoc, Clauses, AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
1546 }
1549 getASTContext(), StartLoc, DirLoc, EndLoc, Clauses,
1550 AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
1551 }
1554 EndLoc, Clauses);
1555 }
1558 EndLoc, Clauses);
1559 }
1562 getASTContext(), StartLoc, DirLoc, EndLoc, Clauses,
1563 AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
1564 }
1567 getASTContext(), StartLoc, DirLoc, LParenLoc, Exprs.front(), MiscLoc,
1568 Exprs.drop_front(), RParenLoc, EndLoc, Clauses);
1569 }
1572 EndLoc, Clauses);
1573 }
1576 EndLoc, Clauses);
1577 }
1580 EndLoc, Clauses);
1581 }
1584 EndLoc, Clauses);
1585 }
1586 }
1587 llvm_unreachable("Unhandled case in directive handling?");
1588}
1589
1593 switch (K) {
1594 default:
1595 llvm_unreachable("Unimplemented associated statement application");
1602 llvm_unreachable(
1603 "these don't have associated statements, so shouldn't get here");
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618 return AssocStmt;
1625
1626 if (!isa<CXXForRangeStmt, ForStmt>(AssocStmt.get())) {
1627 Diag(AssocStmt.get()->getBeginLoc(), diag::err_acc_loop_not_for_loop)
1628 << K;
1629 Diag(DirectiveLoc, diag::note_acc_construct_here) << K;
1631 }
1632
1633 if (!CollapseInfo.CollapseDepthSatisfied || !TileInfo.TileDepthSatisfied) {
1634 if (!CollapseInfo.CollapseDepthSatisfied) {
1635 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
1637 assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");
1638 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1639 diag::note_acc_active_clause_here)
1641 }
1642
1643 if (!TileInfo.TileDepthSatisfied) {
1644 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
1646 assert(TileInfo.ActiveTile && "Collapse count without object?");
1647 Diag(TileInfo.ActiveTile->getBeginLoc(),
1648 diag::note_acc_active_clause_here)
1650 }
1652 }
1653
1654 return AssocStmt.get();
1655 }
1656 llvm_unreachable("Invalid associated statement application");
1657}
1658
1661
1662
1663
1666 return diagnoseConstructAppertainment(*this, K, StartLoc, false);
1667}
1668
1670
1674}
1675
1679}
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)
- 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.