static bool classof(const OMPClause *) { return true; }
};
+template <OpenMPClauseKind ClauseKind>
+struct OMPNoChildClause : public OMPClause {
+ /// Build '\p ClauseKind' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ OMPNoChildClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(ClauseKind, StartLoc, EndLoc) {}
+
+ /// Build an empty clause.
+ OMPNoChildClause()
+ : OMPClause(ClauseKind, SourceLocation(), SourceLocation()) {}
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == ClauseKind;
+ }
+};
+
+template <OpenMPClauseKind ClauseKind, class Base>
+class OMPOneStmtClause : public Base {
+
+ /// Location of '('.
+ SourceLocation LParenLoc;
+
+ /// Sub-expression.
+ Stmt *S = nullptr;
+
+protected:
+ void setStmt(Stmt *S) { this->S = S; }
+
+public:
+ OMPOneStmtClause(Stmt *S, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : Base(ClauseKind, StartLoc, EndLoc), LParenLoc(LParenLoc), S(S) {}
+
+ OMPOneStmtClause() : Base(ClauseKind, SourceLocation(), SourceLocation()) {}
+
+ /// Return the associated statement, potentially casted to \p T.
+ template <typename T> T *getStmtAs() const { return cast_or_null<T>(S); }
+
+ /// Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+ /// Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ using child_iterator = StmtIterator;
+ using const_child_iterator = ConstStmtIterator;
+ using child_range = llvm::iterator_range<child_iterator>;
+ using const_child_range = llvm::iterator_range<const_child_iterator>;
+
+ child_range children() { return child_range(&S, &S + 1); }
+
+ const_child_range children() const { return const_child_range(&S, &S + 1); }
+
+ // TODO: Consider making the getAddrOfExprAsWritten version the default.
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == ClauseKind;
+ }
+};
+
/// Class that handles pre-initialization statement for some clauses, like
/// 'shedule', 'firstprivate' etc.
class OMPClauseWithPreInit {
/// \endcode
/// In this example directive '#pragma omp allocate' has simple 'allocator'
/// clause with the allocator 'omp_default_mem_alloc'.
-class OMPAllocatorClause : public OMPClause {
+class OMPAllocatorClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_allocator, OMPClause> {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Expression with the allocator.
- Stmt *Allocator = nullptr;
-
/// Set allocator.
- void setAllocator(Expr *A) { Allocator = A; }
+ void setAllocator(Expr *A) { setStmt(A); }
public:
/// Build 'allocator' clause with the given allocator.
/// \param EndLoc Ending location of the clause.
OMPAllocatorClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_allocator, StartLoc, EndLoc),
- LParenLoc(LParenLoc), Allocator(A) {}
+ : OMPOneStmtClause(A, StartLoc, LParenLoc, EndLoc) {}
/// Build an empty clause.
- OMPAllocatorClause()
- : OMPClause(llvm::omp::OMPC_allocator, SourceLocation(),
- SourceLocation()) {}
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ OMPAllocatorClause() : OMPOneStmtClause() {}
/// Returns allocator.
- Expr *getAllocator() const { return cast_or_null<Expr>(Allocator); }
-
- child_range children() { return child_range(&Allocator, &Allocator + 1); }
-
- const_child_range children() const {
- return const_child_range(&Allocator, &Allocator + 1);
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_allocator;
- }
+ Expr *getAllocator() const { return getStmtAs<Expr>(); }
};
/// This represents the 'align' clause in the '#pragma omp allocate'
/// In this example directive '#pragma omp allocate' has simple 'allocator'
/// clause with the allocator 'omp_default_mem_alloc' and align clause with
/// value of 8.
-class OMPAlignClause final : public OMPClause {
+class OMPAlignClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_align, OMPClause> {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Alignment specified with align clause.
- Stmt *Alignment = nullptr;
-
/// Set alignment value.
- void setAlignment(Expr *A) { Alignment = A; }
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ void setAlignment(Expr *A) { setStmt(A); }
/// Build 'align' clause with the given alignment
///
/// \param EndLoc Ending location of the clause.
OMPAlignClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_align, StartLoc, EndLoc),
- LParenLoc(LParenLoc), Alignment(A) {}
+ : OMPOneStmtClause(A, StartLoc, LParenLoc, EndLoc) {}
/// Build an empty clause.
- OMPAlignClause()
- : OMPClause(llvm::omp::OMPC_align, SourceLocation(), SourceLocation()) {}
+ OMPAlignClause() : OMPOneStmtClause() {}
public:
/// Build 'align' clause with the given alignment
SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
/// Returns alignment
- Expr *getAlignment() const { return cast_or_null<Expr>(Alignment); }
-
- child_range children() { return child_range(&Alignment, &Alignment + 1); }
-
- const_child_range children() const {
- return const_child_range(&Alignment, &Alignment + 1);
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_align;
- }
+ Expr *getAlignment() const { return getStmtAs<Expr>(); }
};
/// This represents clause 'allocate' in the '#pragma omp ...' directives.
/// \endcode
/// In this example directive '#pragma omp task' has simple 'final'
/// clause with condition 'a > 5'.
-class OMPFinalClause : public OMPClause, public OMPClauseWithPreInit {
+class OMPFinalClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_final, OMPClause>,
+ public OMPClauseWithPreInit {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Condition of the 'if' clause.
- Stmt *Condition = nullptr;
-
/// Set condition.
- void setCondition(Expr *Cond) { Condition = Cond; }
+ void setCondition(Expr *Cond) { setStmt(Cond); }
public:
/// Build 'final' clause with condition \a Cond.
OMPFinalClause(Expr *Cond, Stmt *HelperCond,
OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_final, StartLoc, EndLoc),
- OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond) {
+ : OMPOneStmtClause(Cond, StartLoc, LParenLoc, EndLoc),
+ OMPClauseWithPreInit(this) {
setPreInitStmt(HelperCond, CaptureRegion);
}
/// Build an empty clause.
- OMPFinalClause()
- : OMPClause(llvm::omp::OMPC_final, SourceLocation(), SourceLocation()),
- OMPClauseWithPreInit(this) {}
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ OMPFinalClause() : OMPOneStmtClause(), OMPClauseWithPreInit(this) {}
/// Returns condition.
- Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
-
- child_range children() { return child_range(&Condition, &Condition + 1); }
-
- const_child_range children() const {
- return const_child_range(&Condition, &Condition + 1);
- }
+ Expr *getCondition() const { return getStmtAs<Expr>(); }
child_range used_children();
const_child_range used_children() const {
auto Children = const_cast<OMPFinalClause *>(this)->used_children();
return const_child_range(Children.begin(), Children.end());
}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_final;
- }
};
-
/// This represents 'num_threads' clause in the '#pragma omp ...'
/// directive.
///
/// \endcode
/// In this example directive '#pragma omp parallel' has simple 'num_threads'
/// clause with number of threads '6'.
-class OMPNumThreadsClause : public OMPClause, public OMPClauseWithPreInit {
+class OMPNumThreadsClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_num_threads, OMPClause>,
+ public OMPClauseWithPreInit {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Condition of the 'num_threads' clause.
- Stmt *NumThreads = nullptr;
-
/// Set condition.
- void setNumThreads(Expr *NThreads) { NumThreads = NThreads; }
+ void setNumThreads(Expr *NThreads) { setStmt(NThreads); }
public:
/// Build 'num_threads' clause with condition \a NumThreads.
OpenMPDirectiveKind CaptureRegion,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_num_threads, StartLoc, EndLoc),
- OMPClauseWithPreInit(this), LParenLoc(LParenLoc),
- NumThreads(NumThreads) {
+ : OMPOneStmtClause(NumThreads, StartLoc, LParenLoc, EndLoc),
+ OMPClauseWithPreInit(this) {
setPreInitStmt(HelperNumThreads, CaptureRegion);
}
/// Build an empty clause.
- OMPNumThreadsClause()
- : OMPClause(llvm::omp::OMPC_num_threads, SourceLocation(),
- SourceLocation()),
- OMPClauseWithPreInit(this) {}
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ OMPNumThreadsClause() : OMPOneStmtClause(), OMPClauseWithPreInit(this) {}
/// Returns number of threads.
- Expr *getNumThreads() const { return cast_or_null<Expr>(NumThreads); }
-
- child_range children() { return child_range(&NumThreads, &NumThreads + 1); }
-
- const_child_range children() const {
- return const_child_range(&NumThreads, &NumThreads + 1);
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_num_threads;
- }
+ Expr *getNumThreads() const { return getStmtAs<Expr>(); }
};
/// This represents 'safelen' clause in the '#pragma omp ...'
/// concurrently with SIMD instructions can have a greater distance
/// in the logical iteration space than its value. The parameter of
/// the safelen clause must be a constant positive integer expression.
-class OMPSafelenClause : public OMPClause {
+class OMPSafelenClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_safelen, OMPClause> {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Safe iteration space distance.
- Stmt *Safelen = nullptr;
-
/// Set safelen.
- void setSafelen(Expr *Len) { Safelen = Len; }
+ void setSafelen(Expr *Len) { setStmt(Len); }
public:
/// Build 'safelen' clause.
/// \param EndLoc Ending location of the clause.
OMPSafelenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_safelen, StartLoc, EndLoc),
- LParenLoc(LParenLoc), Safelen(Len) {}
+ : OMPOneStmtClause(Len, StartLoc, LParenLoc, EndLoc) {}
/// Build an empty clause.
- explicit OMPSafelenClause()
- : OMPClause(llvm::omp::OMPC_safelen, SourceLocation(), SourceLocation()) {
- }
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ explicit OMPSafelenClause() : OMPOneStmtClause() {}
/// Return safe iteration space distance.
- Expr *getSafelen() const { return cast_or_null<Expr>(Safelen); }
-
- child_range children() { return child_range(&Safelen, &Safelen + 1); }
-
- const_child_range children() const {
- return const_child_range(&Safelen, &Safelen + 1);
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_safelen;
- }
+ Expr *getSafelen() const { return getStmtAs<Expr>(); }
};
/// This represents 'simdlen' clause in the '#pragma omp ...'
/// If the 'simdlen' clause is used then it specifies the preferred number of
/// iterations to be executed concurrently. The parameter of the 'simdlen'
/// clause must be a constant positive integer expression.
-class OMPSimdlenClause : public OMPClause {
+class OMPSimdlenClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_simdlen, OMPClause> {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Safe iteration space distance.
- Stmt *Simdlen = nullptr;
-
/// Set simdlen.
- void setSimdlen(Expr *Len) { Simdlen = Len; }
+ void setSimdlen(Expr *Len) { setStmt(Len); }
public:
/// Build 'simdlen' clause.
/// \param EndLoc Ending location of the clause.
OMPSimdlenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_simdlen, StartLoc, EndLoc),
- LParenLoc(LParenLoc), Simdlen(Len) {}
+ : OMPOneStmtClause(Len, StartLoc, LParenLoc, EndLoc) {}
/// Build an empty clause.
- explicit OMPSimdlenClause()
- : OMPClause(llvm::omp::OMPC_simdlen, SourceLocation(), SourceLocation()) {
- }
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ explicit OMPSimdlenClause() : OMPOneStmtClause() {}
/// Return safe iteration space distance.
- Expr *getSimdlen() const { return cast_or_null<Expr>(Simdlen); }
-
- child_range children() { return child_range(&Simdlen, &Simdlen + 1); }
-
- const_child_range children() const {
- return const_child_range(&Simdlen, &Simdlen + 1);
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_simdlen;
- }
+ Expr *getSimdlen() const { return getStmtAs<Expr>(); }
};
/// This represents the 'sizes' clause in the '#pragma omp tile' directive.
/// #pragma omp unroll full
/// for (int i = 0; i < 64; ++i)
/// \endcode
-class OMPFullClause final : public OMPClause {
+class OMPFullClause final : public OMPNoChildClause<llvm::omp::OMPC_full> {
friend class OMPClauseReader;
/// Build an empty clause.
- explicit OMPFullClause() : OMPClause(llvm::omp::OMPC_full, {}, {}) {}
+ explicit OMPFullClause() : OMPNoChildClause() {}
public:
/// Build an AST node for a 'full' clause.
///
/// \param C Context of the AST.
static OMPFullClause *CreateEmpty(const ASTContext &C);
-
- child_range children() { return {child_iterator(), child_iterator()}; }
- const_child_range children() const {
- return {const_child_iterator(), const_child_iterator()};
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_full;
- }
};
/// Representation of the 'partial' clause of the '#pragma omp unroll'
/// The parameter must be a constant positive integer expression, it specifies
/// the number of nested loops that should be collapsed into a single iteration
/// space.
-class OMPCollapseClause : public OMPClause {
+class OMPCollapseClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_collapse, OMPClause> {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Number of for-loops.
- Stmt *NumForLoops = nullptr;
-
/// Set the number of associated for-loops.
- void setNumForLoops(Expr *Num) { NumForLoops = Num; }
+ void setNumForLoops(Expr *Num) { setStmt(Num); }
public:
/// Build 'collapse' clause.
/// \param EndLoc Ending location of the clause.
OMPCollapseClause(Expr *Num, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_collapse, StartLoc, EndLoc),
- LParenLoc(LParenLoc), NumForLoops(Num) {}
+ : OMPOneStmtClause(Num, StartLoc, LParenLoc, EndLoc) {}
/// Build an empty clause.
- explicit OMPCollapseClause()
- : OMPClause(llvm::omp::OMPC_collapse, SourceLocation(),
- SourceLocation()) {}
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ explicit OMPCollapseClause() : OMPOneStmtClause() {}
/// Return the number of associated for-loops.
- Expr *getNumForLoops() const { return cast_or_null<Expr>(NumForLoops); }
-
- child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); }
-
- const_child_range children() const {
- return const_child_range(&NumForLoops, &NumForLoops + 1);
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_collapse;
- }
+ Expr *getNumForLoops() const { return getStmtAs<Expr>(); }
};
/// This represents 'default' clause in the '#pragma omp ...' directive.
/// \endcode
/// In this example directive '#pragma omp requires' has 'unified_address'
/// clause.
-class OMPUnifiedAddressClause final : public OMPClause {
+class OMPUnifiedAddressClause final
+ : public OMPNoChildClause<llvm::omp::OMPC_unified_address> {
public:
friend class OMPClauseReader;
/// Build 'unified_address' clause.
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_unified_address, StartLoc, EndLoc) {}
+ : OMPNoChildClause(StartLoc, EndLoc) {}
/// Build an empty clause.
- OMPUnifiedAddressClause()
- : OMPClause(llvm::omp::OMPC_unified_address, SourceLocation(),
- SourceLocation()) {}
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_unified_address;
- }
+ OMPUnifiedAddressClause() : OMPNoChildClause() {}
};
/// This represents 'unified_shared_memory' clause in the '#pragma omp requires'
/// #pragma omp for nowait
/// \endcode
/// In this example directive '#pragma omp for' has 'nowait' clause.
-class OMPNowaitClause : public OMPClause {
+class OMPNowaitClause final : public OMPNoChildClause<llvm::omp::OMPC_nowait> {
public:
/// Build 'nowait' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
- OMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_nowait, StartLoc, EndLoc) {}
-
- /// Build an empty clause.
- OMPNowaitClause()
- : OMPClause(llvm::omp::OMPC_nowait, SourceLocation(), SourceLocation()) {}
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_nowait;
- }
+ OMPNowaitClause(SourceLocation StartLoc = SourceLocation(),
+ SourceLocation EndLoc = SourceLocation())
+ : OMPNoChildClause(StartLoc, EndLoc) {}
};
/// This represents 'untied' clause in the '#pragma omp ...' directive.
/// #pragma omp ordered threads
/// \endcode
/// In this example directive '#pragma omp ordered' has simple 'threads' clause.
-class OMPThreadsClause : public OMPClause {
+class OMPThreadsClause final
+ : public OMPNoChildClause<llvm::omp::OMPC_threads> {
public:
/// Build 'threads' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_threads, StartLoc, EndLoc) {}
+ : OMPNoChildClause(StartLoc, EndLoc) {}
/// Build an empty clause.
- OMPThreadsClause()
- : OMPClause(llvm::omp::OMPC_threads, SourceLocation(), SourceLocation()) {
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_threads;
- }
+ OMPThreadsClause() : OMPNoChildClause() {}
};
/// This represents 'simd' clause in the '#pragma omp ...' directive.
/// \endcode
/// In this example directive '#pragma omp dispatch' has simple 'novariants'
/// clause with condition 'a > 5'.
-class OMPNovariantsClause final : public OMPClause,
- public OMPClauseWithPreInit {
+class OMPNovariantsClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_novariants, OMPClause>,
+ public OMPClauseWithPreInit {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Condition of the 'if' clause.
- Stmt *Condition = nullptr;
-
/// Set condition.
- void setCondition(Expr *Cond) { Condition = Cond; }
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ void setCondition(Expr *Cond) { setStmt(Cond); }
public:
/// Build 'novariants' clause with condition \a Cond.
OpenMPDirectiveKind CaptureRegion,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_novariants, StartLoc, EndLoc),
- OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond) {
+ : OMPOneStmtClause(Cond, StartLoc, LParenLoc, EndLoc),
+ OMPClauseWithPreInit(this) {
setPreInitStmt(HelperCond, CaptureRegion);
}
/// Build an empty clause.
- OMPNovariantsClause()
- : OMPClause(llvm::omp::OMPC_novariants, SourceLocation(),
- SourceLocation()),
- OMPClauseWithPreInit(this) {}
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ OMPNovariantsClause() : OMPOneStmtClause(), OMPClauseWithPreInit(this) {}
/// Returns condition.
- Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
-
- child_range children() { return child_range(&Condition, &Condition + 1); }
-
- const_child_range children() const {
- return const_child_range(&Condition, &Condition + 1);
- }
+ Expr *getCondition() const { return getStmtAs<Expr>(); }
child_range used_children();
const_child_range used_children() const {
auto Children = const_cast<OMPNovariantsClause *>(this)->used_children();
return const_child_range(Children.begin(), Children.end());
}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_novariants;
- }
};
/// This represents 'nocontext' clause in the '#pragma omp ...' directive.
/// \endcode
/// In this example directive '#pragma omp dispatch' has simple 'nocontext'
/// clause with condition 'a > 5'.
-class OMPNocontextClause final : public OMPClause, public OMPClauseWithPreInit {
+class OMPNocontextClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_nocontext, OMPClause>,
+ public OMPClauseWithPreInit {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Condition of the 'if' clause.
- Stmt *Condition = nullptr;
-
/// Set condition.
- void setCondition(Expr *Cond) { Condition = Cond; }
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ void setCondition(Expr *Cond) { setStmt(Cond); }
public:
/// Build 'nocontext' clause with condition \a Cond.
OMPNocontextClause(Expr *Cond, Stmt *HelperCond,
OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_nocontext, StartLoc, EndLoc),
- OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond) {
+ : OMPOneStmtClause(Cond, StartLoc, LParenLoc, EndLoc),
+ OMPClauseWithPreInit(this) {
setPreInitStmt(HelperCond, CaptureRegion);
}
/// Build an empty clause.
- OMPNocontextClause()
- : OMPClause(llvm::omp::OMPC_nocontext, SourceLocation(),
- SourceLocation()),
- OMPClauseWithPreInit(this) {}
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ OMPNocontextClause() : OMPOneStmtClause(), OMPClauseWithPreInit(this) {}
/// Returns condition.
- Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
-
- child_range children() { return child_range(&Condition, &Condition + 1); }
-
- const_child_range children() const {
- return const_child_range(&Condition, &Condition + 1);
- }
+ Expr *getCondition() const { return getStmtAs<Expr>(); }
child_range used_children();
const_child_range used_children() const {
auto Children = const_cast<OMPNocontextClause *>(this)->used_children();
return const_child_range(Children.begin(), Children.end());
}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_nocontext;
- }
};
/// This represents 'detach' clause in the '#pragma omp task' directive.
/// \endcode
/// In this example directive '#pragma omp detach' has simple 'detach' clause
/// with the variable 'evt'.
-class OMPDetachClause final : public OMPClause {
+class OMPDetachClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_detach, OMPClause> {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Expression of the 'detach' clause.
- Stmt *Evt = nullptr;
-
/// Set condition.
- void setEventHandler(Expr *E) { Evt = E; }
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ void setEventHandler(Expr *E) { setStmt(E); }
public:
/// Build 'detach' clause with event-handler \a Evt.
/// \param EndLoc Ending location of the clause.
OMPDetachClause(Expr *Evt, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_detach, StartLoc, EndLoc),
- LParenLoc(LParenLoc), Evt(Evt) {}
+ : OMPOneStmtClause(Evt, StartLoc, LParenLoc, EndLoc) {}
/// Build an empty clause.
- OMPDetachClause()
- : OMPClause(llvm::omp::OMPC_detach, SourceLocation(), SourceLocation()) {}
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ OMPDetachClause() : OMPOneStmtClause() {}
/// Returns event-handler expression.
- Expr *getEventHandler() const { return cast_or_null<Expr>(Evt); }
-
- child_range children() { return child_range(&Evt, &Evt + 1); }
-
- const_child_range children() const {
- return const_child_range(&Evt, &Evt + 1);
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_detach;
- }
+ Expr *getEventHandler() const { return getStmtAs<Expr>(); }
};
/// This represents clause 'inclusive' in the '#pragma omp scan' directive.
/// \endcode
/// In this example directive '#pragma omp masked' has 'filter' clause with
/// thread id.
-class OMPFilterClause final : public OMPClause, public OMPClauseWithPreInit {
+class OMPFilterClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_filter, OMPClause>,
+ public OMPClauseWithPreInit {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Express of the 'filter' clause.
- Stmt *ThreadID = nullptr;
-
/// Sets the thread identifier.
- void setThreadID(Expr *TID) { ThreadID = TID; }
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ void setThreadID(Expr *TID) { setStmt(TID); }
public:
/// Build 'filter' clause with thread-id \a ThreadID.
OMPFilterClause(Expr *ThreadID, Stmt *HelperE,
OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_filter, StartLoc, EndLoc),
- OMPClauseWithPreInit(this), LParenLoc(LParenLoc), ThreadID(ThreadID) {
+ : OMPOneStmtClause(ThreadID, StartLoc, LParenLoc, EndLoc),
+ OMPClauseWithPreInit(this) {
setPreInitStmt(HelperE, CaptureRegion);
}
/// Build an empty clause.
- OMPFilterClause()
- : OMPClause(llvm::omp::OMPC_filter, SourceLocation(), SourceLocation()),
- OMPClauseWithPreInit(this) {}
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ OMPFilterClause() : OMPOneStmtClause(), OMPClauseWithPreInit(this) {}
/// Return thread identifier.
- Expr *getThreadID() { return cast<Expr>(ThreadID); }
+ Expr *getThreadID() const { return getStmtAs<Expr>(); }
/// Return thread identifier.
- Expr *getThreadID() const { return cast<Expr>(ThreadID); }
-
- child_range children() { return child_range(&ThreadID, &ThreadID + 1); }
-
- const_child_range children() const {
- return const_child_range(&ThreadID, &ThreadID + 1);
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_filter;
- }
+ Expr *getThreadID() { return getStmtAs<Expr>(); }
};
/// This represents 'bind' clause in the '#pragma omp ...' directives.
/// \code
/// #pragma omp loop bind(parallel)
/// \endcode
-class OMPBindClause final : public OMPClause {
+class OMPBindClause final : public OMPNoChildClause<llvm::omp::OMPC_bind> {
friend class OMPClauseReader;
/// Location of '('.
OMPBindClause(OpenMPBindClauseKind K, SourceLocation KLoc,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_bind, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Kind(K), KindLoc(KLoc) {}
+ : OMPNoChildClause(StartLoc, EndLoc), LParenLoc(LParenLoc), Kind(K),
+ KindLoc(KLoc) {}
/// Build an empty clause.
- OMPBindClause()
- : OMPClause(llvm::omp::OMPC_bind, SourceLocation(), SourceLocation()) {}
+ OMPBindClause() : OMPNoChildClause() {}
public:
/// Build 'bind' clause with kind \a K ('teams', 'parallel', or 'thread').
/// Returns location of clause kind.
SourceLocation getBindKindLoc() const { return KindLoc; }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_bind;
- }
};
/// This class implements a simple visitor for OMPClause