1313#ifndef LLVM_CLANG_AST_STMTOPENACC_H
1414#define LLVM_CLANG_AST_STMTOPENACC_H
1515
16+ #include " clang/AST/OpenACCClause.h"
1617#include " clang/AST/Stmt.h"
1718#include " clang/Basic/OpenACCKinds.h"
1819#include " clang/Basic/SourceLocation.h"
20+ #include < memory>
1921
2022namespace clang {
2123// / This is the base class for an OpenACC statement-level construct, other
@@ -30,13 +32,23 @@ class OpenACCConstructStmt : public Stmt {
3032 // / the directive.
3133 SourceRange Range;
3234
33- // TODO OPENACC: Clauses should probably be collected in this class.
35+ // / The list of clauses. This is stored here as an ArrayRef, as this is the
36+ // / most convienient place to access the list, however the list itself should
37+ // / be stored in leaf nodes, likely in trailing-storage.
38+ MutableArrayRef<const OpenACCClause *> Clauses;
3439
3540protected:
3641 OpenACCConstructStmt (StmtClass SC, OpenACCDirectiveKind K,
3742 SourceLocation Start, SourceLocation End)
3843 : Stmt(SC), Kind(K), Range(Start, End) {}
3944
45+ // Used only for initialization, the leaf class can initialize this to
46+ // trailing storage.
47+ void setClauseList (MutableArrayRef<const OpenACCClause *> NewClauses) {
48+ assert (Clauses.empty () && " Cannot change clause list" );
49+ Clauses = NewClauses;
50+ }
51+
4052public:
4153 OpenACCDirectiveKind getDirectiveKind () const { return Kind; }
4254
@@ -47,6 +59,7 @@ class OpenACCConstructStmt : public Stmt {
4759
4860 SourceLocation getBeginLoc () const { return Range.getBegin (); }
4961 SourceLocation getEndLoc () const { return Range.getEnd (); }
62+ ArrayRef<const OpenACCClause *> clauses () const { return Clauses; }
5063
5164 child_range children () {
5265 return child_range (child_iterator (), child_iterator ());
@@ -101,24 +114,46 @@ class OpenACCAssociatedStmtConstruct : public OpenACCConstructStmt {
101114// / those three, as they are semantically identical, and have only minor
102115// / differences in the permitted list of clauses, which can be differentiated by
103116// / the 'Kind'.
104- class OpenACCComputeConstruct : public OpenACCAssociatedStmtConstruct {
117+ class OpenACCComputeConstruct final
118+ : public OpenACCAssociatedStmtConstruct,
119+ public llvm::TrailingObjects<OpenACCComputeConstruct,
120+ const OpenACCClause *> {
105121 friend class ASTStmtWriter ;
106122 friend class ASTStmtReader ;
107123 friend class ASTContext ;
108- OpenACCComputeConstruct ()
109- : OpenACCAssociatedStmtConstruct(
110- OpenACCComputeConstructClass, OpenACCDirectiveKind::Invalid,
111- SourceLocation{}, SourceLocation{}, /* AssociatedStmt=*/ nullptr ) {}
124+ OpenACCComputeConstruct (unsigned NumClauses)
125+ : OpenACCAssociatedStmtConstruct(OpenACCComputeConstructClass,
126+ OpenACCDirectiveKind::Invalid,
127+ SourceLocation{}, SourceLocation{},
128+ /* AssociatedStmt=*/ nullptr ) {
129+ // We cannot send the TrailingObjects storage to the base class (which holds
130+ // a reference to the data) until it is constructed, so we have to set it
131+ // separately here.
132+ std::uninitialized_value_construct (
133+ getTrailingObjects<const OpenACCClause *>(),
134+ getTrailingObjects<const OpenACCClause *>() + NumClauses);
135+ setClauseList (MutableArrayRef (getTrailingObjects<const OpenACCClause *>(),
136+ NumClauses));
137+ }
112138
113139 OpenACCComputeConstruct (OpenACCDirectiveKind K, SourceLocation Start,
114- SourceLocation End, Stmt *StructuredBlock)
140+ SourceLocation End,
141+ ArrayRef<const OpenACCClause *> Clauses,
142+ Stmt *StructuredBlock)
115143 : OpenACCAssociatedStmtConstruct(OpenACCComputeConstructClass, K, Start,
116144 End, StructuredBlock) {
117145 assert ((K == OpenACCDirectiveKind::Parallel ||
118146 K == OpenACCDirectiveKind::Serial ||
119147 K == OpenACCDirectiveKind::Kernels) &&
120148 " Only parallel, serial, and kernels constructs should be "
121149 " represented by this type" );
150+
151+ // Initialize the trailing storage.
152+ std::uninitialized_copy (Clauses.begin (), Clauses.end (),
153+ getTrailingObjects<const OpenACCClause *>());
154+
155+ setClauseList (MutableArrayRef (getTrailingObjects<const OpenACCClause *>(),
156+ Clauses.size ()));
122157 }
123158
124159 void setStructuredBlock (Stmt *S) { setAssociatedStmt (S); }
@@ -128,10 +163,12 @@ class OpenACCComputeConstruct : public OpenACCAssociatedStmtConstruct {
128163 return T->getStmtClass () == OpenACCComputeConstructClass;
129164 }
130165
131- static OpenACCComputeConstruct *CreateEmpty (const ASTContext &C, EmptyShell);
166+ static OpenACCComputeConstruct *CreateEmpty (const ASTContext &C,
167+ unsigned NumClauses);
132168 static OpenACCComputeConstruct *
133169 Create (const ASTContext &C, OpenACCDirectiveKind K, SourceLocation BeginLoc,
134- SourceLocation EndLoc, Stmt *StructuredBlock);
170+ SourceLocation EndLoc, ArrayRef<const OpenACCClause *> Clauses,
171+ Stmt *StructuredBlock);
135172
136173 Stmt *getStructuredBlock () { return getAssociatedStmt (); }
137174 const Stmt *getStructuredBlock () const {
0 commit comments