diff options
Diffstat (limited to 'include/clang/AST/StmtOpenMP.h')
-rw-r--r-- | include/clang/AST/StmtOpenMP.h | 647 |
1 files changed, 537 insertions, 110 deletions
diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h index 708b866..1ba859c 100644 --- a/include/clang/AST/StmtOpenMP.h +++ b/include/clang/AST/StmtOpenMP.h @@ -92,65 +92,78 @@ public: /// \brief Iterates over a filtered subrange of clauses applied to a /// directive. /// - /// This iterator visits only those declarations that meet some run-time - /// criteria. - template <class FilterPredicate> class filtered_clause_iterator { - protected: - ArrayRef<OMPClause *>::const_iterator Current; + /// This iterator visits only clauses of type SpecificClause. + template <typename SpecificClause> + class specific_clause_iterator + : public llvm::iterator_adaptor_base< + specific_clause_iterator<SpecificClause>, + ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag, + const SpecificClause *, ptrdiff_t, const SpecificClause *, + const SpecificClause *> { ArrayRef<OMPClause *>::const_iterator End; - FilterPredicate Pred; + void SkipToNextClause() { - while (Current != End && !Pred(*Current)) - ++Current; + while (this->I != End && !isa<SpecificClause>(*this->I)) + ++this->I; } public: - typedef const OMPClause *value_type; - filtered_clause_iterator() : Current(), End() {} - filtered_clause_iterator(ArrayRef<OMPClause *> Arr, FilterPredicate Pred) - : Current(Arr.begin()), End(Arr.end()), Pred(std::move(Pred)) { + explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses) + : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()), + End(Clauses.end()) { SkipToNextClause(); } - value_type operator*() const { return *Current; } - value_type operator->() const { return *Current; } - filtered_clause_iterator &operator++() { - ++Current; - SkipToNextClause(); - return *this; - } - filtered_clause_iterator operator++(int) { - filtered_clause_iterator tmp(*this); - ++(*this); - return tmp; + const SpecificClause *operator*() const { + return cast<SpecificClause>(*this->I); } + const SpecificClause *operator->() const { return **this; } - bool operator!() { return Current == End; } - explicit operator bool() { return Current != End; } - bool empty() const { return Current == End; } + specific_clause_iterator &operator++() { + ++this->I; + SkipToNextClause(); + return *this; + } }; - template <typename Fn> - filtered_clause_iterator<Fn> getFilteredClauses(Fn &&fn) const { - return filtered_clause_iterator<Fn>(clauses(), std::move(fn)); + template <typename SpecificClause> + static llvm::iterator_range<specific_clause_iterator<SpecificClause>> + getClausesOfKind(ArrayRef<OMPClause *> Clauses) { + return {specific_clause_iterator<SpecificClause>(Clauses), + specific_clause_iterator<SpecificClause>( + llvm::makeArrayRef(Clauses.end(), 0))}; } - struct ClauseKindFilter { - OpenMPClauseKind Kind; - bool operator()(const OMPClause *clause) const { - return clause->getClauseKind() == Kind; - } - }; - filtered_clause_iterator<ClauseKindFilter> - getClausesOfKind(OpenMPClauseKind Kind) const { - return getFilteredClauses(ClauseKindFilter{Kind}); + + template <typename SpecificClause> + llvm::iterator_range<specific_clause_iterator<SpecificClause>> + getClausesOfKind() const { + return getClausesOfKind<SpecificClause>(clauses()); } - /// \brief Gets a single clause of the specified kind \a K associated with the + /// Gets a single clause of the specified kind associated with the /// current directive iff there is only one clause of this kind (and assertion /// is fired if there is more than one clause is associated with the - /// directive). Returns nullptr if no clause of kind \a K is associated with + /// directive). Returns nullptr if no clause of this kind is associated with /// the directive. - const OMPClause *getSingleClause(OpenMPClauseKind K) const; + template <typename SpecificClause> + const SpecificClause *getSingleClause() const { + auto Clauses = getClausesOfKind<SpecificClause>(); + + if (Clauses.begin() != Clauses.end()) { + assert(std::next(Clauses.begin()) == Clauses.end() && + "There are at least 2 clauses of the specified kind"); + return *Clauses.begin(); + } + return nullptr; + } + + /// Returns true if the current directive has one or more clauses of a + /// specific kind. + template <typename SpecificClause> + bool hasClausesOfKind() const { + auto Clauses = getClausesOfKind<SpecificClause>(); + return Clauses.begin() != Clauses.end(); + } /// \brief Returns starting location of directive kind. SourceLocation getLocStart() const { return StartLoc; } @@ -195,7 +208,7 @@ public: child_range children() { if (!hasAssociatedStmt()) - return child_range(); + return child_range(child_iterator(), child_iterator()); Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end()); return child_range(ChildStorage, ChildStorage + NumChildren); } @@ -217,6 +230,10 @@ public: /// variables 'c' and 'd'. /// class OMPParallelDirective : public OMPExecutableDirective { + friend class ASTStmtReader; + /// \brief true if the construct has inner cancel directive. + bool HasCancel; + /// \brief Build directive with the given start and end location. /// /// \param StartLoc Starting location of the directive (directive keyword). @@ -225,7 +242,8 @@ class OMPParallelDirective : public OMPExecutableDirective { OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc, unsigned NumClauses) : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel, - StartLoc, EndLoc, NumClauses, 1) {} + StartLoc, EndLoc, NumClauses, 1), + HasCancel(false) {} /// \brief Build an empty directive. /// @@ -234,7 +252,11 @@ class OMPParallelDirective : public OMPExecutableDirective { explicit OMPParallelDirective(unsigned NumClauses) : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel, SourceLocation(), SourceLocation(), NumClauses, - 1) {} + 1), + HasCancel(false) {} + + /// \brief Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } public: /// \brief Creates directive with a list of \a Clauses. @@ -244,10 +266,11 @@ public: /// \param EndLoc Ending Location of the directive. /// \param Clauses List of clauses. /// \param AssociatedStmt Statement associated with the directive. + /// \param HasCancel true if this directive has inner cancel directive. /// static OMPParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, - ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel); /// \brief Creates an empty directive with the place for \a N clauses. /// @@ -257,6 +280,9 @@ public: static OMPParallelDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); + /// \brief Return true if current directive has inner cancel directive. + bool hasCancel() const { return HasCancel; } + static bool classof(const Stmt *T) { return T->getStmtClass() == OMPParallelDirectiveClass; } @@ -311,11 +337,18 @@ class OMPLoopDirective : public OMPExecutableDirective { return MutableArrayRef<Expr *>(Storage, CollapsedNum); } + /// \brief Get the private counters storage. + MutableArrayRef<Expr *> getPrivateCounters() { + Expr **Storage = reinterpret_cast<Expr **>(&*std::next( + child_begin(), getArraysOffset(getDirectiveKind()) + CollapsedNum)); + return MutableArrayRef<Expr *>(Storage, CollapsedNum); + } + /// \brief Get the updates storage. MutableArrayRef<Expr *> getInits() { Expr **Storage = reinterpret_cast<Expr **>( &*std::next(child_begin(), - getArraysOffset(getDirectiveKind()) + CollapsedNum)); + getArraysOffset(getDirectiveKind()) + 2 * CollapsedNum)); return MutableArrayRef<Expr *>(Storage, CollapsedNum); } @@ -323,7 +356,7 @@ class OMPLoopDirective : public OMPExecutableDirective { MutableArrayRef<Expr *> getUpdates() { Expr **Storage = reinterpret_cast<Expr **>( &*std::next(child_begin(), - getArraysOffset(getDirectiveKind()) + 2 * CollapsedNum)); + getArraysOffset(getDirectiveKind()) + 3 * CollapsedNum)); return MutableArrayRef<Expr *>(Storage, CollapsedNum); } @@ -331,7 +364,7 @@ class OMPLoopDirective : public OMPExecutableDirective { MutableArrayRef<Expr *> getFinals() { Expr **Storage = reinterpret_cast<Expr **>( &*std::next(child_begin(), - getArraysOffset(getDirectiveKind()) + 3 * CollapsedNum)); + getArraysOffset(getDirectiveKind()) + 4 * CollapsedNum)); return MutableArrayRef<Expr *>(Storage, CollapsedNum); } @@ -358,15 +391,19 @@ protected: /// \brief Offset to the start of children expression arrays. static unsigned getArraysOffset(OpenMPDirectiveKind Kind) { - return isOpenMPWorksharingDirective(Kind) ? WorksharingEnd - : DefaultEnd; + return (isOpenMPWorksharingDirective(Kind) || + isOpenMPTaskLoopDirective(Kind) || + isOpenMPDistributeDirective(Kind)) + ? WorksharingEnd + : DefaultEnd; } /// \brief Children number. static unsigned numLoopChildren(unsigned CollapsedNum, OpenMPDirectiveKind Kind) { - return getArraysOffset(Kind) + - 4 * CollapsedNum; // Counters, Inits, Updates and Finals + return getArraysOffset(Kind) + 5 * CollapsedNum; // Counters, + // PrivateCounters, Inits, + // Updates and Finals } void setIterationVariable(Expr *IV) { @@ -387,41 +424,56 @@ protected: void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; } void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; } void setIsLastIterVariable(Expr *IL) { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); *std::next(child_begin(), IsLastIterVariableOffset) = IL; } void setLowerBoundVariable(Expr *LB) { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); *std::next(child_begin(), LowerBoundVariableOffset) = LB; } void setUpperBoundVariable(Expr *UB) { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); *std::next(child_begin(), UpperBoundVariableOffset) = UB; } void setStrideVariable(Expr *ST) { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); *std::next(child_begin(), StrideVariableOffset) = ST; } void setEnsureUpperBound(Expr *EUB) { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); *std::next(child_begin(), EnsureUpperBoundOffset) = EUB; } void setNextLowerBound(Expr *NLB) { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); *std::next(child_begin(), NextLowerBoundOffset) = NLB; } void setNextUpperBound(Expr *NUB) { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); *std::next(child_begin(), NextUpperBoundOffset) = NUB; } void setCounters(ArrayRef<Expr *> A); + void setPrivateCounters(ArrayRef<Expr *> A); void setInits(ArrayRef<Expr *> A); void setUpdates(ArrayRef<Expr *> A); void setFinals(ArrayRef<Expr *> A); @@ -462,6 +514,8 @@ public: Expr *NUB; /// \brief Counters Loop counters. SmallVector<Expr *, 4> Counters; + /// \brief PrivateCounters Loop counters. + SmallVector<Expr *, 4> PrivateCounters; /// \brief Expressions for loop counters inits for CodeGen. SmallVector<Expr *, 4> Inits; /// \brief Expressions for loop counters update for CodeGen. @@ -495,11 +549,13 @@ public: NLB = nullptr; NUB = nullptr; Counters.resize(Size); + PrivateCounters.resize(Size); Inits.resize(Size); Updates.resize(Size); Finals.resize(Size); for (unsigned i = 0; i < Size; ++i) { Counters[i] = nullptr; + PrivateCounters[i] = nullptr; Inits[i] = nullptr; Updates[i] = nullptr; Finals[i] = nullptr; @@ -539,43 +595,50 @@ public: reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset))); } Expr *getIsLastIterVariable() const { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast<Expr *>(reinterpret_cast<const Expr *>( *std::next(child_begin(), IsLastIterVariableOffset))); } Expr *getLowerBoundVariable() const { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast<Expr *>(reinterpret_cast<const Expr *>( *std::next(child_begin(), LowerBoundVariableOffset))); } Expr *getUpperBoundVariable() const { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast<Expr *>(reinterpret_cast<const Expr *>( *std::next(child_begin(), UpperBoundVariableOffset))); } Expr *getStrideVariable() const { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast<Expr *>(reinterpret_cast<const Expr *>( *std::next(child_begin(), StrideVariableOffset))); } Expr *getEnsureUpperBound() const { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast<Expr *>(reinterpret_cast<const Expr *>( *std::next(child_begin(), EnsureUpperBoundOffset))); } Expr *getNextLowerBound() const { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast<Expr *>(reinterpret_cast<const Expr *>( *std::next(child_begin(), NextLowerBoundOffset))); } Expr *getNextUpperBound() const { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast<Expr *>(reinterpret_cast<const Expr *>( *std::next(child_begin(), NextUpperBoundOffset))); @@ -597,6 +660,12 @@ public: return const_cast<OMPLoopDirective *>(this)->getCounters(); } + ArrayRef<Expr *> private_counters() { return getPrivateCounters(); } + + ArrayRef<Expr *> private_counters() const { + return const_cast<OMPLoopDirective *>(this)->getPrivateCounters(); + } + ArrayRef<Expr *> inits() { return getInits(); } ArrayRef<Expr *> inits() const { @@ -620,7 +689,10 @@ public: T->getStmtClass() == OMPForDirectiveClass || T->getStmtClass() == OMPForSimdDirectiveClass || T->getStmtClass() == OMPParallelForDirectiveClass || - T->getStmtClass() == OMPParallelForSimdDirectiveClass; + T->getStmtClass() == OMPParallelForSimdDirectiveClass || + T->getStmtClass() == OMPTaskLoopDirectiveClass || + T->getStmtClass() == OMPTaskLoopSimdDirectiveClass || + T->getStmtClass() == OMPDistributeDirectiveClass; } }; @@ -700,6 +772,10 @@ public: /// class OMPForDirective : public OMPLoopDirective { friend class ASTStmtReader; + + /// \brief true if current directive has inner cancel directive. + bool HasCancel; + /// \brief Build directive with the given start and end location. /// /// \param StartLoc Starting location of the directive kind. @@ -710,7 +786,8 @@ class OMPForDirective : public OMPLoopDirective { OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, unsigned NumClauses) : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc, - CollapsedNum, NumClauses) {} + CollapsedNum, NumClauses), + HasCancel(false) {} /// \brief Build an empty directive. /// @@ -719,7 +796,11 @@ class OMPForDirective : public OMPLoopDirective { /// explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses) : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, SourceLocation(), - SourceLocation(), CollapsedNum, NumClauses) {} + SourceLocation(), CollapsedNum, NumClauses), + HasCancel(false) {} + + /// \brief Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } public: /// \brief Creates directive with a list of \a Clauses. @@ -731,12 +812,13 @@ public: /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. + /// \param HasCancel true if current directive has inner cancel directive. /// static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, - Stmt *AssociatedStmt, - const HelperExprs &Exprs); + Stmt *AssociatedStmt, const HelperExprs &Exprs, + bool HasCancel); /// \brief Creates an empty directive with the place /// for \a NumClauses clauses. @@ -748,6 +830,9 @@ public: static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, EmptyShell); + /// \brief Return true if current directive has inner cancel directive. + bool hasCancel() const { return HasCancel; } + static bool classof(const Stmt *T) { return T->getStmtClass() == OMPForDirectiveClass; } @@ -829,6 +914,10 @@ public: /// class OMPSectionsDirective : public OMPExecutableDirective { friend class ASTStmtReader; + + /// \brief true if current directive has inner cancel directive. + bool HasCancel; + /// \brief Build directive with the given start and end location. /// /// \param StartLoc Starting location of the directive kind. @@ -838,7 +927,8 @@ class OMPSectionsDirective : public OMPExecutableDirective { OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc, unsigned NumClauses) : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections, - StartLoc, EndLoc, NumClauses, 1) {} + StartLoc, EndLoc, NumClauses, 1), + HasCancel(false) {} /// \brief Build an empty directive. /// @@ -847,7 +937,11 @@ class OMPSectionsDirective : public OMPExecutableDirective { explicit OMPSectionsDirective(unsigned NumClauses) : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections, SourceLocation(), SourceLocation(), NumClauses, - 1) {} + 1), + HasCancel(false) {} + + /// \brief Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } public: /// \brief Creates directive with a list of \a Clauses. @@ -857,10 +951,11 @@ public: /// \param EndLoc Ending Location of the directive. /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. + /// \param HasCancel true if current directive has inner directive. /// static OMPSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, - ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel); /// \brief Creates an empty directive with the place for \a NumClauses /// clauses. @@ -871,6 +966,9 @@ public: static OMPSectionsDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); + /// \brief Return true if current directive has inner cancel directive. + bool hasCancel() const { return HasCancel; } + static bool classof(const Stmt *T) { return T->getStmtClass() == OMPSectionsDirectiveClass; } @@ -884,6 +982,10 @@ public: /// class OMPSectionDirective : public OMPExecutableDirective { friend class ASTStmtReader; + + /// \brief true if current directive has inner cancel directive. + bool HasCancel; + /// \brief Build directive with the given start and end location. /// /// \param StartLoc Starting location of the directive kind. @@ -891,13 +993,15 @@ class OMPSectionDirective : public OMPExecutableDirective { /// OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc) : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section, - StartLoc, EndLoc, 0, 1) {} + StartLoc, EndLoc, 0, 1), + HasCancel(false) {} /// \brief Build an empty directive. /// explicit OMPSectionDirective() : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section, - SourceLocation(), SourceLocation(), 0, 1) {} + SourceLocation(), SourceLocation(), 0, 1), + HasCancel(false) {} public: /// \brief Creates directive. @@ -906,11 +1010,12 @@ public: /// \param StartLoc Starting location of the directive kind. /// \param EndLoc Ending Location of the directive. /// \param AssociatedStmt Statement, associated with the directive. + /// \param HasCancel true if current directive has inner directive. /// static OMPSectionDirective *Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, - Stmt *AssociatedStmt); + Stmt *AssociatedStmt, bool HasCancel); /// \brief Creates an empty directive. /// @@ -918,6 +1023,12 @@ public: /// static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell); + /// \brief Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } + + /// \brief Return true if current directive has inner cancel directive. + bool hasCancel() const { return HasCancel; } + static bool classof(const Stmt *T) { return T->getStmtClass() == OMPSectionDirectiveClass; } @@ -1042,18 +1153,22 @@ class OMPCriticalDirective : public OMPExecutableDirective { /// \param Name Name of the directive. /// \param StartLoc Starting location of the directive kind. /// \param EndLoc Ending location of the directive. + /// \param NumClauses Number of clauses. /// OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc, - SourceLocation EndLoc) + SourceLocation EndLoc, unsigned NumClauses) : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical, - StartLoc, EndLoc, 0, 1), + StartLoc, EndLoc, NumClauses, 1), DirName(Name) {} /// \brief Build an empty directive. /// - explicit OMPCriticalDirective() + /// \param NumClauses Number of clauses. + /// + explicit OMPCriticalDirective(unsigned NumClauses) : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical, - SourceLocation(), SourceLocation(), 0, 1), + SourceLocation(), SourceLocation(), NumClauses, + 1), DirName() {} /// \brief Set name of the directive. @@ -1069,17 +1184,21 @@ public: /// \param Name Name of the directive. /// \param StartLoc Starting location of the directive kind. /// \param EndLoc Ending Location of the directive. + /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// static OMPCriticalDirective * Create(const ASTContext &C, const DeclarationNameInfo &Name, - SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt); + SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); /// \brief Creates an empty directive. /// /// \param C AST context. + /// \param NumClauses Number of clauses. /// - static OMPCriticalDirective *CreateEmpty(const ASTContext &C, EmptyShell); + static OMPCriticalDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, EmptyShell); /// \brief Return name of the directive. /// @@ -1101,6 +1220,10 @@ public: /// class OMPParallelForDirective : public OMPLoopDirective { friend class ASTStmtReader; + + /// \brief true if current region has inner cancel directive. + bool HasCancel; + /// \brief Build directive with the given start and end location. /// /// \param StartLoc Starting location of the directive kind. @@ -1111,7 +1234,8 @@ class OMPParallelForDirective : public OMPLoopDirective { OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, unsigned NumClauses) : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for, - StartLoc, EndLoc, CollapsedNum, NumClauses) {} + StartLoc, EndLoc, CollapsedNum, NumClauses), + HasCancel(false) {} /// \brief Build an empty directive. /// @@ -1121,7 +1245,11 @@ class OMPParallelForDirective : public OMPLoopDirective { explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses) : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for, SourceLocation(), SourceLocation(), CollapsedNum, - NumClauses) {} + NumClauses), + HasCancel(false) {} + + /// \brief Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } public: /// \brief Creates directive with a list of \a Clauses. @@ -1133,11 +1261,12 @@ public: /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. + /// \param HasCancel true if current directive has inner cancel directive. /// static OMPParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, - Stmt *AssociatedStmt, const HelperExprs &Exprs); + Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); /// \brief Creates an empty directive with the place /// for \a NumClauses clauses. @@ -1151,6 +1280,9 @@ public: unsigned CollapsedNum, EmptyShell); + /// \brief Return true if current directive has inner cancel directive. + bool hasCancel() const { return HasCancel; } + static bool classof(const Stmt *T) { return T->getStmtClass() == OMPParallelForDirectiveClass; } @@ -1236,6 +1368,10 @@ public: /// class OMPParallelSectionsDirective : public OMPExecutableDirective { friend class ASTStmtReader; + + /// \brief true if current directive has inner cancel directive. + bool HasCancel; + /// \brief Build directive with the given start and end location. /// /// \param StartLoc Starting location of the directive kind. @@ -1246,7 +1382,8 @@ class OMPParallelSectionsDirective : public OMPExecutableDirective { unsigned NumClauses) : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass, OMPD_parallel_sections, StartLoc, EndLoc, - NumClauses, 1) {} + NumClauses, 1), + HasCancel(false) {} /// \brief Build an empty directive. /// @@ -1255,7 +1392,11 @@ class OMPParallelSectionsDirective : public OMPExecutableDirective { explicit OMPParallelSectionsDirective(unsigned NumClauses) : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass, OMPD_parallel_sections, SourceLocation(), - SourceLocation(), NumClauses, 1) {} + SourceLocation(), NumClauses, 1), + HasCancel(false) {} + + /// \brief Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } public: /// \brief Creates directive with a list of \a Clauses. @@ -1265,10 +1406,11 @@ public: /// \param EndLoc Ending Location of the directive. /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. + /// \param HasCancel true if current directive has inner cancel directive. /// static OMPParallelSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, - ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel); /// \brief Creates an empty directive with the place for \a NumClauses /// clauses. @@ -1279,6 +1421,9 @@ public: static OMPParallelSectionsDirective * CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); + /// \brief Return true if current directive has inner cancel directive. + bool hasCancel() const { return HasCancel; } + static bool classof(const Stmt *T) { return T->getStmtClass() == OMPParallelSectionsDirectiveClass; } @@ -1294,6 +1439,9 @@ public: /// class OMPTaskDirective : public OMPExecutableDirective { friend class ASTStmtReader; + /// \brief true if this directive has inner cancel directive. + bool HasCancel; + /// \brief Build directive with the given start and end location. /// /// \param StartLoc Starting location of the directive kind. @@ -1303,7 +1451,8 @@ class OMPTaskDirective : public OMPExecutableDirective { OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc, unsigned NumClauses) : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc, - EndLoc, NumClauses, 1) {} + EndLoc, NumClauses, 1), + HasCancel(false) {} /// \brief Build an empty directive. /// @@ -1312,7 +1461,11 @@ class OMPTaskDirective : public OMPExecutableDirective { explicit OMPTaskDirective(unsigned NumClauses) : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, SourceLocation(), SourceLocation(), NumClauses, - 1) {} + 1), + HasCancel(false) {} + + /// \brief Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } public: /// \brief Creates directive with a list of \a Clauses. @@ -1322,11 +1475,12 @@ public: /// \param EndLoc Ending Location of the directive. /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. + /// \param HasCancel true, if current directive has inner cancel directive. /// static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses, - Stmt *AssociatedStmt); + Stmt *AssociatedStmt, bool HasCancel); /// \brief Creates an empty directive with the place for \a NumClauses /// clauses. @@ -1337,6 +1491,9 @@ public: static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); + /// \brief Return true if current directive has inner cancel directive. + bool hasCancel() const { return HasCancel; } + static bool classof(const Stmt *T) { return T->getStmtClass() == OMPTaskDirectiveClass; } @@ -1592,16 +1749,21 @@ class OMPOrderedDirective : public OMPExecutableDirective { /// /// \param StartLoc Starting location of the directive kind. /// \param EndLoc Ending location of the directive. + /// \param NumClauses Number of clauses. /// - OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc) + OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered, - StartLoc, EndLoc, 0, 1) {} + StartLoc, EndLoc, NumClauses, 1) {} /// \brief Build an empty directive. /// - explicit OMPOrderedDirective() + /// \param NumClauses Number of clauses. + /// + explicit OMPOrderedDirective(unsigned NumClauses) : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered, - SourceLocation(), SourceLocation(), 0, 1) {} + SourceLocation(), SourceLocation(), NumClauses, + 1) {} public: /// \brief Creates directive. @@ -1609,18 +1771,20 @@ public: /// \param C AST context. /// \param StartLoc Starting location of the directive kind. /// \param EndLoc Ending Location of the directive. + /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// - static OMPOrderedDirective *Create(const ASTContext &C, - SourceLocation StartLoc, - SourceLocation EndLoc, - Stmt *AssociatedStmt); + static OMPOrderedDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); /// \brief Creates an empty directive. /// /// \param C AST context. + /// \param NumClauses Number of clauses. /// - static OMPOrderedDirective *CreateEmpty(const ASTContext &C, EmptyShell); + static OMPOrderedDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, EmptyShell); static bool classof(const Stmt *T) { return T->getStmtClass() == OMPOrderedDirectiveClass; @@ -1817,6 +1981,64 @@ public: } }; +/// \brief This represents '#pragma omp target data' directive. +/// +/// \code +/// #pragma omp target data device(0) if(a) map(b[:]) +/// \endcode +/// In this example directive '#pragma omp target data' has clauses 'device' +/// with the value '0', 'if' with condition 'a' and 'map' with array +/// section 'b[:]'. +/// +class OMPTargetDataDirective : public OMPExecutableDirective { + friend class ASTStmtReader; + /// \brief Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param NumClauses The number of clauses. + /// + OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) + : OMPExecutableDirective(this, OMPTargetDataDirectiveClass, + OMPD_target_data, StartLoc, EndLoc, NumClauses, + 1) {} + + /// \brief Build an empty directive. + /// + /// \param NumClauses Number of clauses. + /// + explicit OMPTargetDataDirective(unsigned NumClauses) + : OMPExecutableDirective(this, OMPTargetDataDirectiveClass, + OMPD_target_data, SourceLocation(), + SourceLocation(), NumClauses, 1) {} + +public: + /// \brief Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. + /// + static OMPTargetDataDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); + + /// \brief Creates an empty directive with the place for \a N clauses. + /// + /// \param C AST context. + /// \param N The number of clauses. + /// + static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N, + EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPTargetDataDirectiveClass; + } +}; + /// \brief This represents '#pragma omp teams' directive. /// /// \code @@ -1947,17 +2169,21 @@ class OMPCancelDirective : public OMPExecutableDirective { /// /// \param StartLoc Starting location of the directive kind. /// \param EndLoc Ending location of the directive. + /// \param NumClauses Number of clauses. /// - OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc) + OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel, - StartLoc, EndLoc, 0, 0), + StartLoc, EndLoc, NumClauses, 0), CancelRegion(OMPD_unknown) {} /// \brief Build an empty directive. /// - explicit OMPCancelDirective() + /// \param NumClauses Number of clauses. + explicit OMPCancelDirective(unsigned NumClauses) : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel, - SourceLocation(), SourceLocation(), 0, 0), + SourceLocation(), SourceLocation(), NumClauses, + 0), CancelRegion(OMPD_unknown) {} /// \brief Set cancel region for current cancellation point. @@ -1970,17 +2196,19 @@ public: /// \param C AST context. /// \param StartLoc Starting location of the directive kind. /// \param EndLoc Ending Location of the directive. + /// \param Clauses List of clauses. /// - static OMPCancelDirective *Create(const ASTContext &C, - SourceLocation StartLoc, - SourceLocation EndLoc, - OpenMPDirectiveKind CancelRegion); + static OMPCancelDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion); /// \brief Creates an empty directive. /// /// \param C AST context. + /// \param NumClauses Number of clauses. /// - static OMPCancelDirective *CreateEmpty(const ASTContext &C, EmptyShell); + static OMPCancelDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, EmptyShell); /// \brief Get cancellation region for the current cancellation point. OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } @@ -1990,6 +2218,205 @@ public: } }; +/// \brief This represents '#pragma omp taskloop' directive. +/// +/// \code +/// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num) +/// \endcode +/// In this example directive '#pragma omp taskloop' has clauses 'private' +/// with the variables 'a' and 'b', 'grainsize' with expression 'val' and +/// 'num_tasks' with expression 'num'. +/// +class OMPTaskLoopDirective : public OMPLoopDirective { + friend class ASTStmtReader; + /// \brief Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, unsigned NumClauses) + : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop, + StartLoc, EndLoc, CollapsedNum, NumClauses) {} + + /// \brief Build an empty directive. + /// + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + explicit OMPTaskLoopDirective(unsigned CollapsedNum, unsigned NumClauses) + : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop, + SourceLocation(), SourceLocation(), CollapsedNum, + NumClauses) {} + +public: + /// \brief Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param CollapsedNum Number of collapsed loops. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. + /// \param Exprs Helper expressions for CodeGen. + /// + static OMPTaskLoopDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, + Stmt *AssociatedStmt, const HelperExprs &Exprs); + + /// \brief Creates an empty directive with the place + /// for \a NumClauses clauses. + /// + /// \param C AST context. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPTaskLoopDirectiveClass; + } +}; + +/// \brief This represents '#pragma omp taskloop simd' directive. +/// +/// \code +/// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num) +/// \endcode +/// In this example directive '#pragma omp taskloop simd' has clauses 'private' +/// with the variables 'a' and 'b', 'grainsize' with expression 'val' and +/// 'num_tasks' with expression 'num'. +/// +class OMPTaskLoopSimdDirective : public OMPLoopDirective { + friend class ASTStmtReader; + /// \brief Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, unsigned NumClauses) + : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass, + OMPD_taskloop_simd, StartLoc, EndLoc, CollapsedNum, + NumClauses) {} + + /// \brief Build an empty directive. + /// + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum, unsigned NumClauses) + : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass, + OMPD_taskloop_simd, SourceLocation(), SourceLocation(), + CollapsedNum, NumClauses) {} + +public: + /// \brief Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param CollapsedNum Number of collapsed loops. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. + /// \param Exprs Helper expressions for CodeGen. + /// + static OMPTaskLoopSimdDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, + Stmt *AssociatedStmt, const HelperExprs &Exprs); + + /// \brief Creates an empty directive with the place + /// for \a NumClauses clauses. + /// + /// \param C AST context. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, + EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass; + } +}; + +/// \brief This represents '#pragma omp distribute' directive. +/// +/// \code +/// #pragma omp distribute private(a,b) +/// \endcode +/// In this example directive '#pragma omp distribute' has clauses 'private' +/// with the variables 'a' and 'b' +/// +class OMPDistributeDirective : public OMPLoopDirective { + friend class ASTStmtReader; + + /// \brief Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, unsigned NumClauses) + : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute, + StartLoc, EndLoc, CollapsedNum, NumClauses) + {} + + /// \brief Build an empty directive. + /// + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + explicit OMPDistributeDirective(unsigned CollapsedNum, unsigned NumClauses) + : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute, + SourceLocation(), SourceLocation(), CollapsedNum, + NumClauses) + {} + +public: + /// \brief Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param CollapsedNum Number of collapsed loops. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. + /// \param Exprs Helper expressions for CodeGen. + /// + static OMPDistributeDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, + Stmt *AssociatedStmt, const HelperExprs &Exprs); + + /// \brief Creates an empty directive with the place + /// for \a NumClauses clauses. + /// + /// \param C AST context. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + static OMPDistributeDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPDistributeDirectiveClass; + } +}; + } // end namespace clang #endif |