@@ -327,18 +327,89 @@ class OpenACCIfClause : public OpenACCClauseWithCondition {
327327 SourceLocation EndLoc);
328328};
329329
330- // / A 'self' clause, which has an optional condition expression.
331- class OpenACCSelfClause : public OpenACCClauseWithCondition {
330+ // / A 'self' clause, which has an optional condition expression, or, in the
331+ // / event of an 'update' directive, contains a 'VarList'.
332+ class OpenACCSelfClause final
333+ : public OpenACCClauseWithParams,
334+ private llvm::TrailingObjects<OpenACCSelfClause, Expr *> {
335+ friend TrailingObjects;
336+ // Holds whether this HAS a condition expression. Lacks a value if this is NOT
337+ // a condition-expr self clause.
338+ std::optional<bool > HasConditionExpr;
339+ // Holds the number of stored expressions. In the case of a condition-expr
340+ // self clause, this is expected to be ONE (and there to be 1 trailing
341+ // object), whether or not that is null.
342+ unsigned NumExprs;
343+
332344 OpenACCSelfClause (SourceLocation BeginLoc, SourceLocation LParenLoc,
333345 Expr *ConditionExpr, SourceLocation EndLoc);
346+ OpenACCSelfClause (SourceLocation BeginLoc, SourceLocation LParenLoc,
347+ ArrayRef<Expr *> VarList, SourceLocation EndLoc);
348+
349+ // Intentionally internal, meant to be an implementation detail of everything
350+ // else. All non-internal uses should go through getConditionExpr/getVarList.
351+ llvm::ArrayRef<Expr *> getExprs () const {
352+ return {getTrailingObjects<Expr *>(), NumExprs};
353+ }
334354
335355public:
336356 static bool classof (const OpenACCClause *C) {
337357 return C->getClauseKind () == OpenACCClauseKind::Self;
338358 }
359+
360+ bool isConditionExprClause () const { return HasConditionExpr.has_value (); }
361+
362+ bool hasConditionExpr () const {
363+ assert (HasConditionExpr.has_value () &&
364+ " VarList Self Clause asked about condition expression" );
365+ return *HasConditionExpr;
366+ }
367+
368+ const Expr *getConditionExpr () const {
369+ assert (HasConditionExpr.has_value () &&
370+ " VarList Self Clause asked about condition expression" );
371+ assert (getExprs ().size () == 1 &&
372+ " ConditionExpr Self Clause with too many Exprs" );
373+ return getExprs ()[0 ];
374+ }
375+
376+ Expr *getConditionExpr () {
377+ assert (HasConditionExpr.has_value () &&
378+ " VarList Self Clause asked about condition expression" );
379+ assert (getExprs ().size () == 1 &&
380+ " ConditionExpr Self Clause with too many Exprs" );
381+ return getExprs ()[0 ];
382+ }
383+
384+ ArrayRef<Expr *> getVarList () {
385+ assert (!HasConditionExpr.has_value () &&
386+ " Condition Expr self clause asked about var list" );
387+ return getExprs ();
388+ }
389+ ArrayRef<Expr *> getVarList () const {
390+ assert (!HasConditionExpr.has_value () &&
391+ " Condition Expr self clause asked about var list" );
392+ return getExprs ();
393+ }
394+
395+ child_range children () {
396+ return child_range (
397+ reinterpret_cast <Stmt **>(getTrailingObjects<Expr *>()),
398+ reinterpret_cast <Stmt **>(getTrailingObjects<Expr *>() + NumExprs));
399+ }
400+
401+ const_child_range children () const {
402+ child_range Children = const_cast <OpenACCSelfClause *>(this )->children ();
403+ return const_child_range (Children.begin (), Children.end ());
404+ }
405+
339406 static OpenACCSelfClause *Create (const ASTContext &C, SourceLocation BeginLoc,
340407 SourceLocation LParenLoc,
341408 Expr *ConditionExpr, SourceLocation EndLoc);
409+ static OpenACCSelfClause *Create (const ASTContext &C, SourceLocation BeginLoc,
410+ SourceLocation LParenLoc,
411+ ArrayRef<Expr *> ConditionExpr,
412+ SourceLocation EndLoc);
342413};
343414
344415// / Represents a clause that has one or more expressions associated with it.
0 commit comments