@@ -118,6 +118,43 @@ class SemaOpenACC : public SemaBase {
118118 // / 'loop' clause enforcement, where this is 'blocked' by a compute construct.
119119 llvm::SmallVector<OpenACCReductionClause *> ActiveReductionClauses;
120120
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+
121158public:
122159 ComputeConstructInfo &getActiveComputeConstructInfo () {
123160 return ActiveComputeConstructInfo;
@@ -137,6 +174,11 @@ class SemaOpenACC : public SemaBase {
137174 // / permits us to implement the restriction of no further 'gang', 'vector', or
138175 // / 'worker' clauses.
139176 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;
140182
141183 // Redeclaration of the version in OpenACCClause.h.
142184 using DeviceTypeArgument = std::pair<IdentifierInfo *, SourceLocation>;
@@ -568,8 +610,19 @@ class SemaOpenACC : public SemaBase {
568610 void ActOnWhileStmt (SourceLocation WhileLoc);
569611 // Called when we encounter a 'do' statement, before looking at its 'body'.
570612 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);
571618 // 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);
573626 // Called when we encounter a 'for' statement, after we've consumed/checked
574627 // the body. This is necessary for a number of checks on the contents of the
575628 // 'for' statement.
@@ -598,7 +651,9 @@ class SemaOpenACC : public SemaBase {
598651 // / Called when we encounter an associated statement for our construct, this
599652 // / should check legality of the statement as it appertains to this Construct.
600653 StmtResult ActOnAssociatedStmt (SourceLocation DirectiveLoc,
601- OpenACCDirectiveKind K, StmtResult AssocStmt);
654+ OpenACCDirectiveKind K,
655+ ArrayRef<const OpenACCClause *> Clauses,
656+ StmtResult AssocStmt);
602657
603658 // / Called after the directive has been completely parsed, including the
604659 // / declaration group or associated statement.
@@ -712,12 +767,13 @@ class SemaOpenACC : public SemaBase {
712767 SourceLocation OldLoopGangClauseOnKernelLoc;
713768 SourceLocation OldLoopWorkerClauseLoc;
714769 SourceLocation OldLoopVectorClauseLoc;
770+ SourceLocation OldLoopWithoutSeqLoc;
715771 llvm::SmallVector<OpenACCLoopConstruct *> ParentlessLoopConstructs;
716772 llvm::SmallVector<OpenACCReductionClause *> ActiveReductionClauses;
717773 LoopInConstructRAII LoopRAII;
718774
719775 public:
720- AssociatedStmtRAII (SemaOpenACC &, OpenACCDirectiveKind,
776+ AssociatedStmtRAII (SemaOpenACC &, OpenACCDirectiveKind, SourceLocation,
721777 ArrayRef<const OpenACCClause *>,
722778 ArrayRef<OpenACCClause *>);
723779 void SetCollapseInfoBeforeAssociatedStmt (
0 commit comments