@@ -118,6 +118,43 @@ class SemaOpenACC : public SemaBase {
118
118
// / 'loop' clause enforcement, where this is 'blocked' by a compute construct.
119
119
llvm::SmallVector<OpenACCReductionClause *> ActiveReductionClauses;
120
120
121
+ // Type to check the info about the 'for stmt'.
122
+ struct ForStmtBeginChecker {
123
+ SemaOpenACC &SemaRef;
124
+ SourceLocation ForLoc;
125
+ bool IsRangeFor = false ;
126
+ std::optional<const CXXForRangeStmt *> RangeFor = nullptr ;
127
+ const Stmt *Init = nullptr ;
128
+ bool InitChanged = false ;
129
+ std::optional<const Stmt *> Cond = nullptr ;
130
+ std::optional<const Stmt *> Inc = nullptr ;
131
+ // Prevent us from checking 2x, which can happen with collapse & tile.
132
+ bool AlreadyChecked = false ;
133
+
134
+ ForStmtBeginChecker (SemaOpenACC &SemaRef, SourceLocation ForLoc,
135
+ std::optional<const CXXForRangeStmt *> S)
136
+ : SemaRef(SemaRef), ForLoc(ForLoc), IsRangeFor(true ), RangeFor(S) {}
137
+
138
+ ForStmtBeginChecker (SemaOpenACC &SemaRef, SourceLocation ForLoc,
139
+ const Stmt *I, bool InitChanged,
140
+ std::optional<const Stmt *> C,
141
+ std::optional<const Stmt *> Inc)
142
+ : SemaRef(SemaRef), ForLoc(ForLoc), IsRangeFor(false ), Init(I),
143
+ InitChanged (InitChanged), Cond(C), Inc(Inc) {}
144
+ // Do the checking for the For/Range-For. Currently this implements the 'not
145
+ // seq' restrictions only, and should be called either if we know we are a
146
+ // top-level 'for' (the one associated via associated-stmt), or extended via
147
+ // 'collapse'.
148
+ void check ();
149
+
150
+ const ValueDecl *checkInit ();
151
+ void checkCond ();
152
+ void checkInc (const ValueDecl *Init);
153
+ };
154
+
155
+ // / Helper function for checking the 'for' and 'range for' stmts.
156
+ void ForStmtBeginHelper (SourceLocation ForLoc, ForStmtBeginChecker &C);
157
+
121
158
public:
122
159
ComputeConstructInfo &getActiveComputeConstructInfo () {
123
160
return ActiveComputeConstructInfo;
@@ -137,6 +174,11 @@ class SemaOpenACC : public SemaBase {
137
174
// / permits us to implement the restriction of no further 'gang', 'vector', or
138
175
// / 'worker' clauses.
139
176
SourceLocation LoopVectorClauseLoc;
177
+ // / If there is a current 'active' loop construct that does NOT have a 'seq'
178
+ // / clause on it, this has that source location. This permits us to implement
179
+ // / the 'loop' restrictions on the loop variable. This can be extended via
180
+ // / 'collapse', so we need to keep this around for a while.
181
+ SourceLocation LoopWithoutSeqLoc;
140
182
141
183
// Redeclaration of the version in OpenACCClause.h.
142
184
using DeviceTypeArgument = std::pair<IdentifierInfo *, SourceLocation>;
@@ -568,8 +610,19 @@ class SemaOpenACC : public SemaBase {
568
610
void ActOnWhileStmt (SourceLocation WhileLoc);
569
611
// Called when we encounter a 'do' statement, before looking at its 'body'.
570
612
void ActOnDoStmt (SourceLocation DoLoc);
613
+ // Called when we encounter a 'for' statement, before looking at its 'body',
614
+ // for the 'range-for'. 'ActOnForStmtEnd' is used after the body.
615
+ void ActOnRangeForStmtBegin (SourceLocation ForLoc, const Stmt *OldRangeFor,
616
+ const Stmt *RangeFor);
617
+ void ActOnRangeForStmtBegin (SourceLocation ForLoc, const Stmt *RangeFor);
571
618
// Called when we encounter a 'for' statement, before looking at its 'body'.
572
- void ActOnForStmtBegin (SourceLocation ForLoc);
619
+ // 'ActOnForStmtEnd' is used after the body.
620
+ void ActOnForStmtBegin (SourceLocation ForLoc, const Stmt *First,
621
+ const Stmt *Second, const Stmt *Third);
622
+ void ActOnForStmtBegin (SourceLocation ForLoc, const Stmt *OldFirst,
623
+ const Stmt *First, const Stmt *OldSecond,
624
+ const Stmt *Second, const Stmt *OldThird,
625
+ const Stmt *Third);
573
626
// Called when we encounter a 'for' statement, after we've consumed/checked
574
627
// the body. This is necessary for a number of checks on the contents of the
575
628
// 'for' statement.
@@ -598,7 +651,9 @@ class SemaOpenACC : public SemaBase {
598
651
// / Called when we encounter an associated statement for our construct, this
599
652
// / should check legality of the statement as it appertains to this Construct.
600
653
StmtResult ActOnAssociatedStmt (SourceLocation DirectiveLoc,
601
- OpenACCDirectiveKind K, StmtResult AssocStmt);
654
+ OpenACCDirectiveKind K,
655
+ ArrayRef<const OpenACCClause *> Clauses,
656
+ StmtResult AssocStmt);
602
657
603
658
// / Called after the directive has been completely parsed, including the
604
659
// / declaration group or associated statement.
@@ -712,12 +767,13 @@ class SemaOpenACC : public SemaBase {
712
767
SourceLocation OldLoopGangClauseOnKernelLoc;
713
768
SourceLocation OldLoopWorkerClauseLoc;
714
769
SourceLocation OldLoopVectorClauseLoc;
770
+ SourceLocation OldLoopWithoutSeqLoc;
715
771
llvm::SmallVector<OpenACCLoopConstruct *> ParentlessLoopConstructs;
716
772
llvm::SmallVector<OpenACCReductionClause *> ActiveReductionClauses;
717
773
LoopInConstructRAII LoopRAII;
718
774
719
775
public:
720
- AssociatedStmtRAII (SemaOpenACC &, OpenACCDirectiveKind,
776
+ AssociatedStmtRAII (SemaOpenACC &, OpenACCDirectiveKind, SourceLocation,
721
777
ArrayRef<const OpenACCClause *>,
722
778
ArrayRef<OpenACCClause *>);
723
779
void SetCollapseInfoBeforeAssociatedStmt (
0 commit comments