@@ -38,9 +38,20 @@ class SemaOpenACC : public SemaBase {
3838 // / haven't had their 'parent' compute construct set yet. Entires will only be
3939 // / made to this list in the case where we know the loop isn't an orphan.
4040 llvm::SmallVector<OpenACCLoopConstruct *> ParentlessLoopConstructs;
41- // / Whether we are inside of a compute construct, and should add loops to the
42- // / above collection.
43- bool InsideComputeConstruct = false ;
41+
42+ struct ComputeConstructInfo {
43+ // / Which type of compute construct we are inside of, which we can use to
44+ // / determine whether we should add loops to the above collection. We can
45+ // / also use it to diagnose loop construct clauses.
46+ OpenACCDirectiveKind Kind = OpenACCDirectiveKind::Invalid;
47+ // If we have an active compute construct, stores the list of clauses we've
48+ // prepared for it, so that we can diagnose limitations on child constructs.
49+ ArrayRef<OpenACCClause *> Clauses;
50+ } ActiveComputeConstructInfo;
51+
52+ bool isInComputeConstruct () const {
53+ return ActiveComputeConstructInfo.Kind != OpenACCDirectiveKind::Invalid;
54+ }
4455
4556 // / Certain clauses care about the same things that aren't specific to the
4657 // / individual clause, but can be shared by a few, so store them here. All
@@ -99,6 +110,15 @@ class SemaOpenACC : public SemaBase {
99110 } TileInfo;
100111
101112public:
113+ ComputeConstructInfo &getActiveComputeConstructInfo () {
114+ return ActiveComputeConstructInfo;
115+ }
116+
117+ // / If there is a current 'active' loop construct with a 'gang' clause on a
118+ // / 'kernel' construct, this will have the source location for it. This
119+ // / permits us to implement the restriction of no further 'gang' clauses.
120+ SourceLocation LoopGangClauseOnKernelLoc;
121+
102122 // Redeclaration of the version in OpenACCClause.h.
103123 using DeviceTypeArgument = std::pair<IdentifierInfo *, SourceLocation>;
104124
@@ -149,9 +169,14 @@ class SemaOpenACC : public SemaBase {
149169 Expr *LoopCount;
150170 };
151171
172+ struct GangDetails {
173+ SmallVector<OpenACCGangKind> GangKinds;
174+ SmallVector<Expr *> IntExprs;
175+ };
176+
152177 std::variant<std::monostate, DefaultDetails, ConditionDetails,
153178 IntExprDetails, VarListDetails, WaitDetails, DeviceTypeDetails,
154- ReductionDetails, CollapseDetails>
179+ ReductionDetails, CollapseDetails, GangDetails >
155180 Details = std::monostate{};
156181
157182 public:
@@ -245,9 +270,18 @@ class SemaOpenACC : public SemaBase {
245270 ClauseKind == OpenACCClauseKind::NumWorkers ||
246271 ClauseKind == OpenACCClauseKind::Async ||
247272 ClauseKind == OpenACCClauseKind::Tile ||
273+ ClauseKind == OpenACCClauseKind::Gang ||
248274 ClauseKind == OpenACCClauseKind::VectorLength) &&
249275 " Parsed clause kind does not have a int exprs" );
250276
277+ if (ClauseKind == OpenACCClauseKind::Gang) {
278+ // There might not be any gang int exprs, as this is an optional
279+ // argument.
280+ if (std::holds_alternative<std::monostate>(Details))
281+ return {};
282+ return std::get<GangDetails>(Details).IntExprs ;
283+ }
284+
251285 return std::get<IntExprDetails>(Details).IntExprs ;
252286 }
253287
@@ -259,6 +293,16 @@ class SemaOpenACC : public SemaBase {
259293 return std::get<ReductionDetails>(Details).Op ;
260294 }
261295
296+ ArrayRef<OpenACCGangKind> getGangKinds () const {
297+ assert (ClauseKind == OpenACCClauseKind::Gang &&
298+ " Parsed clause kind does not have gang kind" );
299+ // The args on gang are optional, so this might not actually hold
300+ // anything.
301+ if (std::holds_alternative<std::monostate>(Details))
302+ return {};
303+ return std::get<GangDetails>(Details).GangKinds ;
304+ }
305+
262306 ArrayRef<Expr *> getVarList () {
263307 assert ((ClauseKind == OpenACCClauseKind::Private ||
264308 ClauseKind == OpenACCClauseKind::NoCreate ||
@@ -371,6 +415,25 @@ class SemaOpenACC : public SemaBase {
371415 Details = IntExprDetails{std::move (IntExprs)};
372416 }
373417
418+ void setGangDetails (ArrayRef<OpenACCGangKind> GKs,
419+ ArrayRef<Expr *> IntExprs) {
420+ assert (ClauseKind == OpenACCClauseKind::Gang &&
421+ " Parsed Clause kind does not have gang details" );
422+ assert (GKs.size () == IntExprs.size () && " Mismatched kind/size?" );
423+
424+ Details = GangDetails{{GKs.begin (), GKs.end ()},
425+ {IntExprs.begin (), IntExprs.end ()}};
426+ }
427+
428+ void setGangDetails (llvm::SmallVector<OpenACCGangKind> &&GKs,
429+ llvm::SmallVector<Expr *> &&IntExprs) {
430+ assert (ClauseKind == OpenACCClauseKind::Gang &&
431+ " Parsed Clause kind does not have gang details" );
432+ assert (GKs.size () == IntExprs.size () && " Mismatched kind/size?" );
433+
434+ Details = GangDetails{std::move (GKs), std::move (IntExprs)};
435+ }
436+
374437 void setVarListDetails (ArrayRef<Expr *> VarList, bool IsReadOnly,
375438 bool IsZero) {
376439 assert ((ClauseKind == OpenACCClauseKind::Private ||
@@ -545,10 +608,12 @@ class SemaOpenACC : public SemaBase {
545608 SourceLocation RBLoc);
546609 // / Checks the loop depth value for a collapse clause.
547610 ExprResult CheckCollapseLoopCount (Expr *LoopCount);
548- // / Checks a single size expr for a tile clause. 'gang' could possibly call
549- // / this, but has slightly stricter rules as to valid values.
611+ // / Checks a single size expr for a tile clause.
550612 ExprResult CheckTileSizeExpr (Expr *SizeExpr);
551613
614+ // Check a single expression on a gang clause.
615+ ExprResult CheckGangExpr (OpenACCGangKind GK, Expr *E);
616+
552617 ExprResult BuildOpenACCAsteriskSizeExpr (SourceLocation AsteriskLoc);
553618 ExprResult ActOnOpenACCAsteriskSizeExpr (SourceLocation AsteriskLoc);
554619
@@ -595,8 +660,9 @@ class SemaOpenACC : public SemaBase {
595660 // / Loop needing its parent construct.
596661 class AssociatedStmtRAII {
597662 SemaOpenACC &SemaRef;
598- bool WasInsideComputeConstruct ;
663+ ComputeConstructInfo OldActiveComputeConstructInfo ;
599664 OpenACCDirectiveKind DirKind;
665+ SourceLocation OldLoopGangClauseOnKernelLoc;
600666 llvm::SmallVector<OpenACCLoopConstruct *> ParentlessLoopConstructs;
601667 LoopInConstructRAII LoopRAII;
602668
0 commit comments