Skip to content

Commit fec003a

Browse files
committed
[OpenACC]Reimplement 'for' loop checks for a loop construct
The 'loop' construct has some pretty strict checks as to what the for loop associated with it has to look like. The previous implementation was a little convoluted and missed implementing the 'condition' checking. Additionally, it did a bad job double-diagnosing with templates. This patch rewrites it in a way that does a much better job with the double-diagnosing, and proeprly implements some checks for the 'condition' of the for loop.
1 parent b111da9 commit fec003a

File tree

4 files changed

+392
-217
lines changed

4 files changed

+392
-217
lines changed

clang/include/clang/Sema/SemaOpenACC.h

Lines changed: 59 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -125,38 +125,73 @@ class SemaOpenACC : public SemaBase {
125125
/// 'loop' clause enforcement, where this is 'blocked' by a compute construct.
126126
llvm::SmallVector<OpenACCReductionClause *> ActiveReductionClauses;
127127

128-
// Type to check the info about the 'for stmt'.
129-
struct ForStmtBeginChecker {
128+
// Type to check the 'for' (or range-for) statement for compatibility with the
129+
// 'loop' directive.
130+
class ForStmtBeginChecker {
130131
SemaOpenACC &SemaRef;
131132
SourceLocation ForLoc;
132-
bool IsRangeFor = false;
133-
std::optional<const CXXForRangeStmt *> RangeFor = nullptr;
134-
const Stmt *Init = nullptr;
135-
bool InitChanged = false;
136-
std::optional<const Stmt *> Cond = nullptr;
137-
std::optional<const Stmt *> Inc = nullptr;
133+
bool IsInstantiation = false;
134+
135+
struct RangeForInfo {
136+
const CXXForRangeStmt *Uninstantiated = nullptr;
137+
const CXXForRangeStmt *CurrentVersion = nullptr;
138+
};
139+
140+
struct ForInfo {
141+
const Stmt *Init = nullptr;
142+
const Stmt *Condition = nullptr;
143+
const Stmt *Increment = nullptr;
144+
};
145+
146+
struct CheckForInfo {
147+
ForInfo Uninst;
148+
ForInfo Current;
149+
};
150+
151+
std::variant<RangeForInfo, CheckForInfo> Info;
138152
// Prevent us from checking 2x, which can happen with collapse & tile.
139153
bool AlreadyChecked = false;
140154

141-
ForStmtBeginChecker(SemaOpenACC &SemaRef, SourceLocation ForLoc,
142-
std::optional<const CXXForRangeStmt *> S)
143-
: SemaRef(SemaRef), ForLoc(ForLoc), IsRangeFor(true), RangeFor(S) {}
155+
void checkRangeFor();
144156

157+
bool checkForInit(const Stmt *InitStmt, const ValueDecl *&InitVar,
158+
bool Diag);
159+
bool checkForCond(const Stmt *CondStmt, const ValueDecl *InitVar,
160+
bool Diag);
161+
bool checkForInc(const Stmt *IncStmt, const ValueDecl *InitVar, bool Diag);
162+
163+
void checkFor();
164+
165+
// void checkRangeFor(); ?? ERICH
166+
// const ValueDecl *checkInit();
167+
// void checkCond(const ValueDecl *Init);
168+
// void checkInc(const ValueDecl *Init);
169+
public:
170+
// Checking for non-instantiation version of a Range-for.
145171
ForStmtBeginChecker(SemaOpenACC &SemaRef, SourceLocation ForLoc,
146-
const Stmt *I, bool InitChanged,
147-
std::optional<const Stmt *> C,
148-
std::optional<const Stmt *> Inc)
149-
: SemaRef(SemaRef), ForLoc(ForLoc), IsRangeFor(false), Init(I),
150-
InitChanged(InitChanged), Cond(C), Inc(Inc) {}
151-
// Do the checking for the For/Range-For. Currently this implements the 'not
152-
// seq' restrictions only, and should be called either if we know we are a
153-
// top-level 'for' (the one associated via associated-stmt), or extended via
154-
// 'collapse'.
155-
void check();
172+
const CXXForRangeStmt *RangeFor)
173+
: SemaRef(SemaRef), ForLoc(ForLoc), IsInstantiation(false),
174+
Info(RangeForInfo{nullptr, RangeFor}) {}
175+
// Checking for an instantiation of the range-for.
176+
ForStmtBeginChecker(SemaOpenACC &SemaRef, SourceLocation ForLoc,
177+
const CXXForRangeStmt *OldRangeFor,
178+
const CXXForRangeStmt *RangeFor)
179+
: SemaRef(SemaRef), ForLoc(ForLoc), IsInstantiation(true),
180+
Info(RangeForInfo{OldRangeFor, RangeFor}) {}
181+
// Checking for a non-instantiation version of a traditional for.
182+
ForStmtBeginChecker(SemaOpenACC &SemaRef, SourceLocation ForLoc,
183+
const Stmt *Init, const Stmt *Cond, const Stmt *Inc)
184+
: SemaRef(SemaRef), ForLoc(ForLoc), IsInstantiation(false),
185+
Info(CheckForInfo{{}, {Init, Cond, Inc}}) {}
186+
// Checking for an instantiation version of a traditional for.
187+
ForStmtBeginChecker(SemaOpenACC &SemaRef, SourceLocation ForLoc,
188+
const Stmt *OldInit, const Stmt *OldCond,
189+
const Stmt *OldInc, const Stmt *Init, const Stmt *Cond,
190+
const Stmt *Inc)
191+
: SemaRef(SemaRef), ForLoc(ForLoc), IsInstantiation(true),
192+
Info(CheckForInfo{{OldInit, OldCond, OldInc}, {Init, Cond, Inc}}) {}
156193

157-
const ValueDecl *checkInit();
158-
void checkCond();
159-
void checkInc(const ValueDecl *Init);
194+
void check();
160195
};
161196

162197
/// Helper function for checking the 'for' and 'range for' stmts.

0 commit comments

Comments
 (0)