| //===- OpenMPClause.h - Classes for OpenMP clauses --------------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| /// \file |
| /// This file defines OpenMP AST classes for clauses. |
| /// There are clauses for executable directives, clauses for declarative |
| /// directives and clauses which can be used in both kinds of directives. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_CLANG_AST_OPENMPCLAUSE_H |
| #define LLVM_CLANG_AST_OPENMPCLAUSE_H |
| |
| #include "clang/AST/ASTFwd.h" |
| #include "clang/AST/Decl.h" |
| #include "clang/AST/DeclarationName.h" |
| #include "clang/AST/Expr.h" |
| #include "clang/AST/NestedNameSpecifier.h" |
| #include "clang/AST/Stmt.h" |
| #include "clang/AST/StmtIterator.h" |
| #include "clang/Basic/LLVM.h" |
| #include "clang/Basic/OpenMPKinds.h" |
| #include "clang/Basic/SourceLocation.h" |
| #include "llvm/ADT/ArrayRef.h" |
| #include "llvm/ADT/MapVector.h" |
| #include "llvm/ADT/PointerIntPair.h" |
| #include "llvm/ADT/SmallVector.h" |
| #include "llvm/ADT/iterator.h" |
| #include "llvm/ADT/iterator_range.h" |
| #include "llvm/Frontend/OpenMP/OMPAssume.h" |
| #include "llvm/Frontend/OpenMP/OMPConstants.h" |
| #include "llvm/Frontend/OpenMP/OMPContext.h" |
| #include "llvm/Support/Casting.h" |
| #include "llvm/Support/Compiler.h" |
| #include "llvm/Support/TrailingObjects.h" |
| #include <cassert> |
| #include <cstddef> |
| #include <iterator> |
| #include <utility> |
| |
| namespace clang { |
| |
| class ASTContext; |
| |
| //===----------------------------------------------------------------------===// |
| // AST classes for clauses. |
| //===----------------------------------------------------------------------===// |
| |
| /// This is a basic class for representing single OpenMP clause. |
| class OMPClause { |
| /// Starting location of the clause (the clause keyword). |
| SourceLocation StartLoc; |
| |
| /// Ending location of the clause. |
| SourceLocation EndLoc; |
| |
| /// Kind of the clause. |
| OpenMPClauseKind Kind; |
| |
| protected: |
| OMPClause(OpenMPClauseKind K, SourceLocation StartLoc, SourceLocation EndLoc) |
| : StartLoc(StartLoc), EndLoc(EndLoc), Kind(K) {} |
| |
| public: |
| /// Returns the starting location of the clause. |
| SourceLocation getBeginLoc() const { return StartLoc; } |
| |
| /// Returns the ending location of the clause. |
| SourceLocation getEndLoc() const { return EndLoc; } |
| |
| /// Sets the starting location of the clause. |
| void setLocStart(SourceLocation Loc) { StartLoc = Loc; } |
| |
| /// Sets the ending location of the clause. |
| void setLocEnd(SourceLocation Loc) { EndLoc = Loc; } |
| |
| /// Returns kind of OpenMP clause (private, shared, reduction, etc.). |
| OpenMPClauseKind getClauseKind() const { return Kind; } |
| |
| bool isImplicit() const { return StartLoc.isInvalid(); } |
| |
| 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(); |
| const_child_range children() const { |
| auto Children = const_cast<OMPClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| /// Get the iterator range for the expressions used in the clauses. Used |
| /// expressions include only the children that must be evaluated at the |
| /// runtime before entering the construct. |
| child_range used_children(); |
| const_child_range used_children() const { |
| auto Children = const_cast<OMPClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| static bool classof(const OMPClause *) { return true; } |
| }; |
| |
| /// Class that handles pre-initialization statement for some clauses, like |
| /// 'shedule', 'firstprivate' etc. |
| class OMPClauseWithPreInit { |
| friend class OMPClauseReader; |
| |
| /// Pre-initialization statement for the clause. |
| Stmt *PreInit = nullptr; |
| |
| /// Region that captures the associated stmt. |
| OpenMPDirectiveKind CaptureRegion = llvm::omp::OMPD_unknown; |
| |
| protected: |
| OMPClauseWithPreInit(const OMPClause *This) { |
| assert(get(This) && "get is not tuned for pre-init."); |
| } |
| |
| /// Set pre-initialization statement for the clause. |
| void |
| setPreInitStmt(Stmt *S, |
| OpenMPDirectiveKind ThisRegion = llvm::omp::OMPD_unknown) { |
| PreInit = S; |
| CaptureRegion = ThisRegion; |
| } |
| |
| public: |
| /// Get pre-initialization statement for the clause. |
| const Stmt *getPreInitStmt() const { return PreInit; } |
| |
| /// Get pre-initialization statement for the clause. |
| Stmt *getPreInitStmt() { return PreInit; } |
| |
| /// Get capture region for the stmt in the clause. |
| OpenMPDirectiveKind getCaptureRegion() const { return CaptureRegion; } |
| |
| static OMPClauseWithPreInit *get(OMPClause *C); |
| static const OMPClauseWithPreInit *get(const OMPClause *C); |
| }; |
| |
| /// Class that handles post-update expression for some clauses, like |
| /// 'lastprivate', 'reduction' etc. |
| class OMPClauseWithPostUpdate : public OMPClauseWithPreInit { |
| friend class OMPClauseReader; |
| |
| /// Post-update expression for the clause. |
| Expr *PostUpdate = nullptr; |
| |
| protected: |
| OMPClauseWithPostUpdate(const OMPClause *This) : OMPClauseWithPreInit(This) { |
| assert(get(This) && "get is not tuned for post-update."); |
| } |
| |
| /// Set pre-initialization statement for the clause. |
| void setPostUpdateExpr(Expr *S) { PostUpdate = S; } |
| |
| public: |
| /// Get post-update expression for the clause. |
| const Expr *getPostUpdateExpr() const { return PostUpdate; } |
| |
| /// Get post-update expression for the clause. |
| Expr *getPostUpdateExpr() { return PostUpdate; } |
| |
| static OMPClauseWithPostUpdate *get(OMPClause *C); |
| static const OMPClauseWithPostUpdate *get(const OMPClause *C); |
| }; |
| |
| /// This structure contains most locations needed for by an OMPVarListClause. |
| struct OMPVarListLocTy { |
| /// Starting location of the clause (the clause keyword). |
| SourceLocation StartLoc; |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| /// Ending location of the clause. |
| SourceLocation EndLoc; |
| OMPVarListLocTy() = default; |
| OMPVarListLocTy(SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc) |
| : StartLoc(StartLoc), LParenLoc(LParenLoc), EndLoc(EndLoc) {} |
| }; |
| |
| /// This represents clauses with the list of variables like 'private', |
| /// 'firstprivate', 'copyin', 'shared', or 'reduction' clauses in the |
| /// '#pragma omp ...' directives. |
| template <class T> class OMPVarListClause : public OMPClause { |
| friend class OMPClauseReader; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// Number of variables in the list. |
| unsigned NumVars; |
| |
| protected: |
| /// Build a clause with \a N variables |
| /// |
| /// \param K Kind of the clause. |
| /// \param StartLoc Starting location of the clause (the clause keyword). |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param N Number of the variables in the clause. |
| OMPVarListClause(OpenMPClauseKind K, SourceLocation StartLoc, |
| SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) |
| : OMPClause(K, StartLoc, EndLoc), LParenLoc(LParenLoc), NumVars(N) {} |
| |
| /// Fetches list of variables associated with this clause. |
| MutableArrayRef<Expr *> getVarRefs() { |
| return MutableArrayRef<Expr *>( |
| static_cast<T *>(this)->template getTrailingObjects<Expr *>(), NumVars); |
| } |
| |
| /// Sets the list of variables for this clause. |
| void setVarRefs(ArrayRef<Expr *> VL) { |
| assert(VL.size() == NumVars && |
| "Number of variables is not the same as the preallocated buffer"); |
| std::copy(VL.begin(), VL.end(), |
| static_cast<T *>(this)->template getTrailingObjects<Expr *>()); |
| } |
| |
| public: |
| using varlist_iterator = MutableArrayRef<Expr *>::iterator; |
| using varlist_const_iterator = ArrayRef<const Expr *>::iterator; |
| using varlist_range = llvm::iterator_range<varlist_iterator>; |
| using varlist_const_range = llvm::iterator_range<varlist_const_iterator>; |
| |
| unsigned varlist_size() const { return NumVars; } |
| bool varlist_empty() const { return NumVars == 0; } |
| |
| varlist_range varlists() { |
| return varlist_range(varlist_begin(), varlist_end()); |
| } |
| varlist_const_range varlists() const { |
| return varlist_const_range(varlist_begin(), varlist_end()); |
| } |
| |
| varlist_iterator varlist_begin() { return getVarRefs().begin(); } |
| varlist_iterator varlist_end() { return getVarRefs().end(); } |
| varlist_const_iterator varlist_begin() const { return getVarRefs().begin(); } |
| varlist_const_iterator varlist_end() const { return getVarRefs().end(); } |
| |
| /// Sets the location of '('. |
| void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } |
| |
| /// Returns the location of '('. |
| SourceLocation getLParenLoc() const { return LParenLoc; } |
| |
| /// Fetches list of all variables in the clause. |
| ArrayRef<const Expr *> getVarRefs() const { |
| return llvm::makeArrayRef( |
| static_cast<const T *>(this)->template getTrailingObjects<Expr *>(), |
| NumVars); |
| } |
| }; |
| |
| /// This represents 'allocator' clause in the '#pragma omp ...' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp allocate(a) allocator(omp_default_mem_alloc) |
| /// \endcode |
| /// In this example directive '#pragma omp allocate' has simple 'allocator' |
| /// clause with the allocator 'omp_default_mem_alloc'. |
| class OMPAllocatorClause : public OMPClause { |
| friend class OMPClauseReader; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// Expression with the allocator. |
| Stmt *Allocator = nullptr; |
| |
| /// Set allocator. |
| void setAllocator(Expr *A) { Allocator = A; } |
| |
| public: |
| /// Build 'allocator' clause with the given allocator. |
| /// |
| /// \param A Allocator. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \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) {} |
| |
| /// 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; } |
| |
| /// 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; |
| } |
| }; |
| |
| /// This represents the 'align' clause in the '#pragma omp allocate' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp allocate(a) allocator(omp_default_mem_alloc) align(8) |
| /// \endcode |
| /// 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 { |
| 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; } |
| |
| /// Build 'align' clause with the given alignment |
| /// |
| /// \param A Alignment value. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \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) {} |
| |
| /// Build an empty clause. |
| OMPAlignClause() |
| : OMPClause(llvm::omp::OMPC_align, SourceLocation(), SourceLocation()) {} |
| |
| public: |
| /// Build 'align' clause with the given alignment |
| /// |
| /// \param A Alignment value. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| static OMPAlignClause *Create(const ASTContext &C, Expr *A, |
| SourceLocation StartLoc, |
| 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; |
| } |
| }; |
| |
| /// This represents clause 'allocate' in the '#pragma omp ...' directives. |
| /// |
| /// \code |
| /// #pragma omp parallel private(a) allocate(omp_default_mem_alloc :a) |
| /// \endcode |
| /// In this example directive '#pragma omp parallel' has clause 'private' |
| /// and clause 'allocate' for the variable 'a'. |
| class OMPAllocateClause final |
| : public OMPVarListClause<OMPAllocateClause>, |
| private llvm::TrailingObjects<OMPAllocateClause, Expr *> { |
| friend class OMPClauseReader; |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Allocator specified in the clause, or 'nullptr' if the default one is |
| /// used. |
| Expr *Allocator = nullptr; |
| /// Position of the ':' delimiter in the clause; |
| SourceLocation ColonLoc; |
| |
| /// Build clause with number of variables \a N. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param Allocator Allocator expression. |
| /// \param ColonLoc Location of ':' delimiter. |
| /// \param EndLoc Ending location of the clause. |
| /// \param N Number of the variables in the clause. |
| OMPAllocateClause(SourceLocation StartLoc, SourceLocation LParenLoc, |
| Expr *Allocator, SourceLocation ColonLoc, |
| SourceLocation EndLoc, unsigned N) |
| : OMPVarListClause<OMPAllocateClause>(llvm::omp::OMPC_allocate, StartLoc, |
| LParenLoc, EndLoc, N), |
| Allocator(Allocator), ColonLoc(ColonLoc) {} |
| |
| /// Build an empty clause. |
| /// |
| /// \param N Number of variables. |
| explicit OMPAllocateClause(unsigned N) |
| : OMPVarListClause<OMPAllocateClause>(llvm::omp::OMPC_allocate, |
| SourceLocation(), SourceLocation(), |
| SourceLocation(), N) {} |
| |
| /// Sets location of ':' symbol in clause. |
| void setColonLoc(SourceLocation CL) { ColonLoc = CL; } |
| |
| void setAllocator(Expr *A) { Allocator = A; } |
| |
| public: |
| /// Creates clause with a list of variables \a VL. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param Allocator Allocator expression. |
| /// \param ColonLoc Location of ':' delimiter. |
| /// \param EndLoc Ending location of the clause. |
| /// \param VL List of references to the variables. |
| static OMPAllocateClause *Create(const ASTContext &C, SourceLocation StartLoc, |
| SourceLocation LParenLoc, Expr *Allocator, |
| SourceLocation ColonLoc, |
| SourceLocation EndLoc, ArrayRef<Expr *> VL); |
| |
| /// Returns the allocator expression or nullptr, if no allocator is specified. |
| Expr *getAllocator() const { return Allocator; } |
| |
| /// Returns the location of the ':' delimiter. |
| SourceLocation getColonLoc() const { return ColonLoc; } |
| |
| /// Creates an empty clause with the place for \a N variables. |
| /// |
| /// \param C AST context. |
| /// \param N The number of variables. |
| static OMPAllocateClause *CreateEmpty(const ASTContext &C, unsigned N); |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPAllocateClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| 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_allocate; |
| } |
| }; |
| |
| /// This represents 'if' clause in the '#pragma omp ...' directive. |
| /// |
| /// \code |
| /// #pragma omp parallel if(parallel:a > 5) |
| /// \endcode |
| /// In this example directive '#pragma omp parallel' has simple 'if' clause with |
| /// condition 'a > 5' and directive name modifier 'parallel'. |
| class OMPIfClause : public OMPClause, public OMPClauseWithPreInit { |
| friend class OMPClauseReader; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// Condition of the 'if' clause. |
| Stmt *Condition = nullptr; |
| |
| /// Location of ':' (if any). |
| SourceLocation ColonLoc; |
| |
| /// Directive name modifier for the clause. |
| OpenMPDirectiveKind NameModifier = llvm::omp::OMPD_unknown; |
| |
| /// Name modifier location. |
| SourceLocation NameModifierLoc; |
| |
| /// Set condition. |
| void setCondition(Expr *Cond) { Condition = Cond; } |
| |
| /// Set directive name modifier for the clause. |
| void setNameModifier(OpenMPDirectiveKind NM) { NameModifier = NM; } |
| |
| /// Set location of directive name modifier for the clause. |
| void setNameModifierLoc(SourceLocation Loc) { NameModifierLoc = Loc; } |
| |
| /// Set location of ':'. |
| void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } |
| |
| public: |
| /// Build 'if' clause with condition \a Cond. |
| /// |
| /// \param NameModifier [OpenMP 4.1] Directive name modifier of clause. |
| /// \param Cond Condition of the clause. |
| /// \param HelperCond Helper condition for the clause. |
| /// \param CaptureRegion Innermost OpenMP region where expressions in this |
| /// clause must be captured. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param NameModifierLoc Location of directive name modifier. |
| /// \param ColonLoc [OpenMP 4.1] Location of ':'. |
| /// \param EndLoc Ending location of the clause. |
| OMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Cond, Stmt *HelperCond, |
| OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, |
| SourceLocation LParenLoc, SourceLocation NameModifierLoc, |
| SourceLocation ColonLoc, SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_if, StartLoc, EndLoc), |
| OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond), |
| ColonLoc(ColonLoc), NameModifier(NameModifier), |
| NameModifierLoc(NameModifierLoc) { |
| setPreInitStmt(HelperCond, CaptureRegion); |
| } |
| |
| /// Build an empty clause. |
| OMPIfClause() |
| : OMPClause(llvm::omp::OMPC_if, SourceLocation(), SourceLocation()), |
| OMPClauseWithPreInit(this) {} |
| |
| /// Sets the location of '('. |
| void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } |
| |
| /// Returns the location of '('. |
| SourceLocation getLParenLoc() const { return LParenLoc; } |
| |
| /// Return the location of ':'. |
| SourceLocation getColonLoc() const { return ColonLoc; } |
| |
| /// Returns condition. |
| Expr *getCondition() const { return cast_or_null<Expr>(Condition); } |
| |
| /// Return directive name modifier associated with the clause. |
| OpenMPDirectiveKind getNameModifier() const { return NameModifier; } |
| |
| /// Return the location of directive name modifier. |
| SourceLocation getNameModifierLoc() const { return NameModifierLoc; } |
| |
| child_range children() { return child_range(&Condition, &Condition + 1); } |
| |
| const_child_range children() const { |
| return const_child_range(&Condition, &Condition + 1); |
| } |
| |
| child_range used_children(); |
| const_child_range used_children() const { |
| auto Children = const_cast<OMPIfClause *>(this)->used_children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| static bool classof(const OMPClause *T) { |
| return T->getClauseKind() == llvm::omp::OMPC_if; |
| } |
| }; |
| |
| /// This represents 'final' clause in the '#pragma omp ...' directive. |
| /// |
| /// \code |
| /// #pragma omp task final(a > 5) |
| /// \endcode |
| /// In this example directive '#pragma omp task' has simple 'final' |
| /// clause with condition 'a > 5'. |
| class OMPFinalClause : public 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; } |
| |
| public: |
| /// Build 'final' clause with condition \a Cond. |
| /// |
| /// \param Cond Condition of the clause. |
| /// \param HelperCond Helper condition for the construct. |
| /// \param CaptureRegion Innermost OpenMP region where expressions in this |
| /// clause must be captured. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| 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) { |
| 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; } |
| |
| /// 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); |
| } |
| |
| 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. |
| /// |
| /// \code |
| /// #pragma omp parallel num_threads(6) |
| /// \endcode |
| /// In this example directive '#pragma omp parallel' has simple 'num_threads' |
| /// clause with number of threads '6'. |
| class OMPNumThreadsClause : public 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; } |
| |
| public: |
| /// Build 'num_threads' clause with condition \a NumThreads. |
| /// |
| /// \param NumThreads Number of threads for the construct. |
| /// \param HelperNumThreads Helper Number of threads for the construct. |
| /// \param CaptureRegion Innermost OpenMP region where expressions in this |
| /// clause must be captured. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| OMPNumThreadsClause(Expr *NumThreads, Stmt *HelperNumThreads, |
| OpenMPDirectiveKind CaptureRegion, |
| SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_num_threads, StartLoc, EndLoc), |
| OMPClauseWithPreInit(this), LParenLoc(LParenLoc), |
| NumThreads(NumThreads) { |
| 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; } |
| |
| /// 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; |
| } |
| }; |
| |
| /// This represents 'safelen' clause in the '#pragma omp ...' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp simd safelen(4) |
| /// \endcode |
| /// In this example directive '#pragma omp simd' has clause 'safelen' |
| /// with single expression '4'. |
| /// If the safelen clause is used then no two iterations executed |
| /// 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 { |
| friend class OMPClauseReader; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// Safe iteration space distance. |
| Stmt *Safelen = nullptr; |
| |
| /// Set safelen. |
| void setSafelen(Expr *Len) { Safelen = Len; } |
| |
| public: |
| /// Build 'safelen' clause. |
| /// |
| /// \param Len Expression associated with this clause. |
| /// \param StartLoc Starting location of the 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) {} |
| |
| /// 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; } |
| |
| /// 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; |
| } |
| }; |
| |
| /// This represents 'simdlen' clause in the '#pragma omp ...' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp simd simdlen(4) |
| /// \endcode |
| /// In this example directive '#pragma omp simd' has clause 'simdlen' |
| /// with single expression '4'. |
| /// 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 { |
| friend class OMPClauseReader; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// Safe iteration space distance. |
| Stmt *Simdlen = nullptr; |
| |
| /// Set simdlen. |
| void setSimdlen(Expr *Len) { Simdlen = Len; } |
| |
| public: |
| /// Build 'simdlen' clause. |
| /// |
| /// \param Len Expression associated with this clause. |
| /// \param StartLoc Starting location of the 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) {} |
| |
| /// 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; } |
| |
| /// 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; |
| } |
| }; |
| |
| /// This represents the 'sizes' clause in the '#pragma omp tile' directive. |
| /// |
| /// \code |
| /// #pragma omp tile sizes(5,5) |
| /// for (int i = 0; i < 64; ++i) |
| /// for (int j = 0; j < 64; ++j) |
| /// \endcode |
| class OMPSizesClause final |
| : public OMPClause, |
| private llvm::TrailingObjects<OMPSizesClause, Expr *> { |
| friend class OMPClauseReader; |
| friend class llvm::TrailingObjects<OMPSizesClause, Expr *>; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// Number of tile sizes in the clause. |
| unsigned NumSizes; |
| |
| /// Build an empty clause. |
| explicit OMPSizesClause(int NumSizes) |
| : OMPClause(llvm::omp::OMPC_sizes, SourceLocation(), SourceLocation()), |
| NumSizes(NumSizes) {} |
| |
| public: |
| /// Build a 'sizes' AST node. |
| /// |
| /// \param C Context of the AST. |
| /// \param StartLoc Location of the 'sizes' identifier. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Location of ')'. |
| /// \param Sizes Content of the clause. |
| static OMPSizesClause *Create(const ASTContext &C, SourceLocation StartLoc, |
| SourceLocation LParenLoc, SourceLocation EndLoc, |
| ArrayRef<Expr *> Sizes); |
| |
| /// Build an empty 'sizes' AST node for deserialization. |
| /// |
| /// \param C Context of the AST. |
| /// \param NumSizes Number of items in the clause. |
| static OMPSizesClause *CreateEmpty(const ASTContext &C, unsigned NumSizes); |
| |
| /// Sets the location of '('. |
| void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } |
| |
| /// Returns the location of '('. |
| SourceLocation getLParenLoc() const { return LParenLoc; } |
| |
| /// Returns the number of list items. |
| unsigned getNumSizes() const { return NumSizes; } |
| |
| /// Returns the tile size expressions. |
| MutableArrayRef<Expr *> getSizesRefs() { |
| return MutableArrayRef<Expr *>(static_cast<OMPSizesClause *>(this) |
| ->template getTrailingObjects<Expr *>(), |
| NumSizes); |
| } |
| ArrayRef<Expr *> getSizesRefs() const { |
| return ArrayRef<Expr *>(static_cast<const OMPSizesClause *>(this) |
| ->template getTrailingObjects<Expr *>(), |
| NumSizes); |
| } |
| |
| /// Sets the tile size expressions. |
| void setSizesRefs(ArrayRef<Expr *> VL) { |
| assert(VL.size() == NumSizes); |
| std::copy(VL.begin(), VL.end(), |
| static_cast<OMPSizesClause *>(this) |
| ->template getTrailingObjects<Expr *>()); |
| } |
| |
| child_range children() { |
| MutableArrayRef<Expr *> Sizes = getSizesRefs(); |
| return child_range(reinterpret_cast<Stmt **>(Sizes.begin()), |
| reinterpret_cast<Stmt **>(Sizes.end())); |
| } |
| const_child_range children() const { |
| ArrayRef<Expr *> Sizes = getSizesRefs(); |
| return const_child_range(reinterpret_cast<Stmt *const *>(Sizes.begin()), |
| reinterpret_cast<Stmt *const *>(Sizes.end())); |
| } |
| |
| 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_sizes; |
| } |
| }; |
| |
| /// Representation of the 'full' clause of the '#pragma omp unroll' directive. |
| /// |
| /// \code |
| /// #pragma omp unroll full |
| /// for (int i = 0; i < 64; ++i) |
| /// \endcode |
| class OMPFullClause final : public OMPClause { |
| friend class OMPClauseReader; |
| |
| /// Build an empty clause. |
| explicit OMPFullClause() : OMPClause(llvm::omp::OMPC_full, {}, {}) {} |
| |
| public: |
| /// Build an AST node for a 'full' clause. |
| /// |
| /// \param C Context of the AST. |
| /// \param StartLoc Starting location of the clause. |
| /// \param EndLoc Ending location of the clause. |
| static OMPFullClause *Create(const ASTContext &C, SourceLocation StartLoc, |
| SourceLocation EndLoc); |
| |
| /// Build an empty 'full' AST node for deserialization. |
| /// |
| /// \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' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp unroll partial(4) |
| /// for (int i = start; i < end; ++i) |
| /// \endcode |
| class OMPPartialClause final : public OMPClause { |
| friend class OMPClauseReader; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// Optional argument to the clause (unroll factor). |
| Stmt *Factor; |
| |
| /// Build an empty clause. |
| explicit OMPPartialClause() : OMPClause(llvm::omp::OMPC_partial, {}, {}) {} |
| |
| /// Set the unroll factor. |
| void setFactor(Expr *E) { Factor = E; } |
| |
| /// Sets the location of '('. |
| void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } |
| |
| public: |
| /// Build an AST node for a 'partial' clause. |
| /// |
| /// \param C Context of the AST. |
| /// \param StartLoc Location of the 'partial' identifier. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Location of ')'. |
| /// \param Factor Clause argument. |
| static OMPPartialClause *Create(const ASTContext &C, SourceLocation StartLoc, |
| SourceLocation LParenLoc, |
| SourceLocation EndLoc, Expr *Factor); |
| |
| /// Build an empty 'partial' AST node for deserialization. |
| /// |
| /// \param C Context of the AST. |
| static OMPPartialClause *CreateEmpty(const ASTContext &C); |
| |
| /// Returns the location of '('. |
| SourceLocation getLParenLoc() const { return LParenLoc; } |
| |
| /// Returns the argument of the clause or nullptr if not set. |
| Expr *getFactor() const { return cast_or_null<Expr>(Factor); } |
| |
| child_range children() { return child_range(&Factor, &Factor + 1); } |
| const_child_range children() const { |
| return const_child_range(&Factor, &Factor + 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_partial; |
| } |
| }; |
| |
| /// This represents 'collapse' clause in the '#pragma omp ...' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp simd collapse(3) |
| /// \endcode |
| /// In this example directive '#pragma omp simd' has clause 'collapse' |
| /// with single expression '3'. |
| /// 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 { |
| 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; } |
| |
| public: |
| /// Build 'collapse' clause. |
| /// |
| /// \param Num Expression associated with this clause. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \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) {} |
| |
| /// 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; } |
| |
| /// 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; |
| } |
| }; |
| |
| /// This represents 'default' clause in the '#pragma omp ...' directive. |
| /// |
| /// \code |
| /// #pragma omp parallel default(shared) |
| /// \endcode |
| /// In this example directive '#pragma omp parallel' has simple 'default' |
| /// clause with kind 'shared'. |
| class OMPDefaultClause : public OMPClause { |
| friend class OMPClauseReader; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// A kind of the 'default' clause. |
| llvm::omp::DefaultKind Kind = llvm::omp::OMP_DEFAULT_unknown; |
| |
| /// Start location of the kind in source code. |
| SourceLocation KindKwLoc; |
| |
| /// Set kind of the clauses. |
| /// |
| /// \param K Argument of clause. |
| void setDefaultKind(llvm::omp::DefaultKind K) { Kind = K; } |
| |
| /// Set argument location. |
| /// |
| /// \param KLoc Argument location. |
| void setDefaultKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; } |
| |
| public: |
| /// Build 'default' clause with argument \a A ('none' or 'shared'). |
| /// |
| /// \param A Argument of the clause ('none' or 'shared'). |
| /// \param ALoc Starting location of the argument. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| OMPDefaultClause(llvm::omp::DefaultKind A, SourceLocation ALoc, |
| SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_default, StartLoc, EndLoc), |
| LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} |
| |
| /// Build an empty clause. |
| OMPDefaultClause() |
| : OMPClause(llvm::omp::OMPC_default, SourceLocation(), SourceLocation()) { |
| } |
| |
| /// Sets the location of '('. |
| void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } |
| |
| /// Returns the location of '('. |
| SourceLocation getLParenLoc() const { return LParenLoc; } |
| |
| /// Returns kind of the clause. |
| llvm::omp::DefaultKind getDefaultKind() const { return Kind; } |
| |
| /// Returns location of clause kind. |
| SourceLocation getDefaultKindKwLoc() const { return KindKwLoc; } |
| |
| 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_default; |
| } |
| }; |
| |
| /// This represents 'proc_bind' clause in the '#pragma omp ...' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp parallel proc_bind(master) |
| /// \endcode |
| /// In this example directive '#pragma omp parallel' has simple 'proc_bind' |
| /// clause with kind 'master'. |
| class OMPProcBindClause : public OMPClause { |
| friend class OMPClauseReader; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// A kind of the 'proc_bind' clause. |
| llvm::omp::ProcBindKind Kind = llvm::omp::OMP_PROC_BIND_unknown; |
| |
| /// Start location of the kind in source code. |
| SourceLocation KindKwLoc; |
| |
| /// Set kind of the clause. |
| /// |
| /// \param K Kind of clause. |
| void setProcBindKind(llvm::omp::ProcBindKind K) { Kind = K; } |
| |
| /// Set clause kind location. |
| /// |
| /// \param KLoc Kind location. |
| void setProcBindKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; } |
| |
| public: |
| /// Build 'proc_bind' clause with argument \a A ('master', 'close' or |
| /// 'spread'). |
| /// |
| /// \param A Argument of the clause ('master', 'close' or 'spread'). |
| /// \param ALoc Starting location of the argument. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| OMPProcBindClause(llvm::omp::ProcBindKind A, SourceLocation ALoc, |
| SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_proc_bind, StartLoc, EndLoc), |
| LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} |
| |
| /// Build an empty clause. |
| OMPProcBindClause() |
| : OMPClause(llvm::omp::OMPC_proc_bind, SourceLocation(), |
| SourceLocation()) {} |
| |
| /// Sets the location of '('. |
| void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } |
| |
| /// Returns the location of '('. |
| SourceLocation getLParenLoc() const { return LParenLoc; } |
| |
| /// Returns kind of the clause. |
| llvm::omp::ProcBindKind getProcBindKind() const { return Kind; } |
| |
| /// Returns location of clause kind. |
| SourceLocation getProcBindKindKwLoc() const { return KindKwLoc; } |
| |
| 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_proc_bind; |
| } |
| }; |
| |
| /// This represents 'unified_address' clause in the '#pragma omp requires' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp requires unified_address |
| /// \endcode |
| /// In this example directive '#pragma omp requires' has 'unified_address' |
| /// clause. |
| class OMPUnifiedAddressClause final : public OMPClause { |
| 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) {} |
| |
| /// 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; |
| } |
| }; |
| |
| /// This represents 'unified_shared_memory' clause in the '#pragma omp requires' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp requires unified_shared_memory |
| /// \endcode |
| /// In this example directive '#pragma omp requires' has 'unified_shared_memory' |
| /// clause. |
| class OMPUnifiedSharedMemoryClause final : public OMPClause { |
| public: |
| friend class OMPClauseReader; |
| /// Build 'unified_shared_memory' clause. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param EndLoc Ending location of the clause. |
| OMPUnifiedSharedMemoryClause(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_unified_shared_memory, StartLoc, EndLoc) {} |
| |
| /// Build an empty clause. |
| OMPUnifiedSharedMemoryClause() |
| : OMPClause(llvm::omp::OMPC_unified_shared_memory, 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_shared_memory; |
| } |
| }; |
| |
| /// This represents 'reverse_offload' clause in the '#pragma omp requires' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp requires reverse_offload |
| /// \endcode |
| /// In this example directive '#pragma omp requires' has 'reverse_offload' |
| /// clause. |
| class OMPReverseOffloadClause final : public OMPClause { |
| public: |
| friend class OMPClauseReader; |
| /// Build 'reverse_offload' clause. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param EndLoc Ending location of the clause. |
| OMPReverseOffloadClause(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_reverse_offload, StartLoc, EndLoc) {} |
| |
| /// Build an empty clause. |
| OMPReverseOffloadClause() |
| : OMPClause(llvm::omp::OMPC_reverse_offload, 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_reverse_offload; |
| } |
| }; |
| |
| /// This represents 'dynamic_allocators' clause in the '#pragma omp requires' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp requires dynamic_allocators |
| /// \endcode |
| /// In this example directive '#pragma omp requires' has 'dynamic_allocators' |
| /// clause. |
| class OMPDynamicAllocatorsClause final : public OMPClause { |
| public: |
| friend class OMPClauseReader; |
| /// Build 'dynamic_allocators' clause. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param EndLoc Ending location of the clause. |
| OMPDynamicAllocatorsClause(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_dynamic_allocators, StartLoc, EndLoc) {} |
| |
| /// Build an empty clause. |
| OMPDynamicAllocatorsClause() |
| : OMPClause(llvm::omp::OMPC_dynamic_allocators, 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_dynamic_allocators; |
| } |
| }; |
| |
| /// This represents 'atomic_default_mem_order' clause in the '#pragma omp |
| /// requires' directive. |
| /// |
| /// \code |
| /// #pragma omp requires atomic_default_mem_order(seq_cst) |
| /// \endcode |
| /// In this example directive '#pragma omp requires' has simple |
| /// atomic_default_mem_order' clause with kind 'seq_cst'. |
| class OMPAtomicDefaultMemOrderClause final : public OMPClause { |
| friend class OMPClauseReader; |
| |
| /// Location of '(' |
| SourceLocation LParenLoc; |
| |
| /// A kind of the 'atomic_default_mem_order' clause. |
| OpenMPAtomicDefaultMemOrderClauseKind Kind = |
| OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown; |
| |
| /// Start location of the kind in source code. |
| SourceLocation KindKwLoc; |
| |
| /// Set kind of the clause. |
| /// |
| /// \param K Kind of clause. |
| void setAtomicDefaultMemOrderKind(OpenMPAtomicDefaultMemOrderClauseKind K) { |
| Kind = K; |
| } |
| |
| /// Set clause kind location. |
| /// |
| /// \param KLoc Kind location. |
| void setAtomicDefaultMemOrderKindKwLoc(SourceLocation KLoc) { |
| KindKwLoc = KLoc; |
| } |
| |
| public: |
| /// Build 'atomic_default_mem_order' clause with argument \a A ('seq_cst', |
| /// 'acq_rel' or 'relaxed'). |
| /// |
| /// \param A Argument of the clause ('seq_cst', 'acq_rel' or 'relaxed'). |
| /// \param ALoc Starting location of the argument. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| OMPAtomicDefaultMemOrderClause(OpenMPAtomicDefaultMemOrderClauseKind A, |
| SourceLocation ALoc, SourceLocation StartLoc, |
| SourceLocation LParenLoc, |
| SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_atomic_default_mem_order, StartLoc, EndLoc), |
| LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} |
| |
| /// Build an empty clause. |
| OMPAtomicDefaultMemOrderClause() |
| : OMPClause(llvm::omp::OMPC_atomic_default_mem_order, SourceLocation(), |
| SourceLocation()) {} |
| |
| /// Sets the location of '('. |
| void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } |
| |
| /// Returns the locaiton of '('. |
| SourceLocation getLParenLoc() const { return LParenLoc; } |
| |
| /// Returns kind of the clause. |
| OpenMPAtomicDefaultMemOrderClauseKind getAtomicDefaultMemOrderKind() const { |
| return Kind; |
| } |
| |
| /// Returns location of clause kind. |
| SourceLocation getAtomicDefaultMemOrderKindKwLoc() const { return KindKwLoc; } |
| |
| 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_atomic_default_mem_order; |
| } |
| }; |
| |
| /// This represents 'schedule' clause in the '#pragma omp ...' directive. |
| /// |
| /// \code |
| /// #pragma omp for schedule(static, 3) |
| /// \endcode |
| /// In this example directive '#pragma omp for' has 'schedule' clause with |
| /// arguments 'static' and '3'. |
| class OMPScheduleClause : public OMPClause, public OMPClauseWithPreInit { |
| friend class OMPClauseReader; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// A kind of the 'schedule' clause. |
| OpenMPScheduleClauseKind Kind = OMPC_SCHEDULE_unknown; |
| |
| /// Modifiers for 'schedule' clause. |
| enum {FIRST, SECOND, NUM_MODIFIERS}; |
| OpenMPScheduleClauseModifier Modifiers[NUM_MODIFIERS]; |
| |
| /// Locations of modifiers. |
| SourceLocation ModifiersLoc[NUM_MODIFIERS]; |
| |
| /// Start location of the schedule ind in source code. |
| SourceLocation KindLoc; |
| |
| /// Location of ',' (if any). |
| SourceLocation CommaLoc; |
| |
| /// Chunk size. |
| Expr *ChunkSize = nullptr; |
| |
| /// Set schedule kind. |
| /// |
| /// \param K Schedule kind. |
| void setScheduleKind(OpenMPScheduleClauseKind K) { Kind = K; } |
| |
| /// Set the first schedule modifier. |
| /// |
| /// \param M Schedule modifier. |
| void setFirstScheduleModifier(OpenMPScheduleClauseModifier M) { |
| Modifiers[FIRST] = M; |
| } |
| |
| /// Set the second schedule modifier. |
| /// |
| /// \param M Schedule modifier. |
| void setSecondScheduleModifier(OpenMPScheduleClauseModifier M) { |
| Modifiers[SECOND] = M; |
| } |
| |
| /// Set location of the first schedule modifier. |
| void setFirstScheduleModifierLoc(SourceLocation Loc) { |
| ModifiersLoc[FIRST] = Loc; |
| } |
| |
| /// Set location of the second schedule modifier. |
| void setSecondScheduleModifierLoc(SourceLocation Loc) { |
| ModifiersLoc[SECOND] = Loc; |
| } |
| |
| /// Set schedule modifier location. |
| /// |
| /// \param M Schedule modifier location. |
| void setScheduleModifer(OpenMPScheduleClauseModifier M) { |
| if (Modifiers[FIRST] == OMPC_SCHEDULE_MODIFIER_unknown) |
| Modifiers[FIRST] = M; |
| else { |
| assert(Modifiers[SECOND] == OMPC_SCHEDULE_MODIFIER_unknown); |
| Modifiers[SECOND] = M; |
| } |
| } |
| |
| /// Sets the location of '('. |
| /// |
| /// \param Loc Location of '('. |
| void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } |
| |
| /// Set schedule kind start location. |
| /// |
| /// \param KLoc Schedule kind location. |
| void setScheduleKindLoc(SourceLocation KLoc) { KindLoc = KLoc; } |
| |
| /// Set location of ','. |
| /// |
| /// \param Loc Location of ','. |
| void setCommaLoc(SourceLocation Loc) { CommaLoc = Loc; } |
| |
| /// Set chunk size. |
| /// |
| /// \param E Chunk size. |
| void setChunkSize(Expr *E) { ChunkSize = E; } |
| |
| public: |
| /// Build 'schedule' clause with schedule kind \a Kind and chunk size |
| /// expression \a ChunkSize. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param KLoc Starting location of the argument. |
| /// \param CommaLoc Location of ','. |
| /// \param EndLoc Ending location of the clause. |
| /// \param Kind Schedule kind. |
| /// \param ChunkSize Chunk size. |
| /// \param HelperChunkSize Helper chunk size for combined directives. |
| /// \param M1 The first modifier applied to 'schedule' clause. |
| /// \param M1Loc Location of the first modifier |
| /// \param M2 The second modifier applied to 'schedule' clause. |
| /// \param M2Loc Location of the second modifier |
| OMPScheduleClause(SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation KLoc, SourceLocation CommaLoc, |
| SourceLocation EndLoc, OpenMPScheduleClauseKind Kind, |
| Expr *ChunkSize, Stmt *HelperChunkSize, |
| OpenMPScheduleClauseModifier M1, SourceLocation M1Loc, |
| OpenMPScheduleClauseModifier M2, SourceLocation M2Loc) |
| : OMPClause(llvm::omp::OMPC_schedule, StartLoc, EndLoc), |
| OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Kind(Kind), |
| KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) { |
| setPreInitStmt(HelperChunkSize); |
| Modifiers[FIRST] = M1; |
| Modifiers[SECOND] = M2; |
| ModifiersLoc[FIRST] = M1Loc; |
| ModifiersLoc[SECOND] = M2Loc; |
| } |
| |
| /// Build an empty clause. |
| explicit OMPScheduleClause() |
| : OMPClause(llvm::omp::OMPC_schedule, SourceLocation(), SourceLocation()), |
| OMPClauseWithPreInit(this) { |
| Modifiers[FIRST] = OMPC_SCHEDULE_MODIFIER_unknown; |
| Modifiers[SECOND] = OMPC_SCHEDULE_MODIFIER_unknown; |
| } |
| |
| /// Get kind of the clause. |
| OpenMPScheduleClauseKind getScheduleKind() const { return Kind; } |
| |
| /// Get the first modifier of the clause. |
| OpenMPScheduleClauseModifier getFirstScheduleModifier() const { |
| return Modifiers[FIRST]; |
| } |
| |
| /// Get the second modifier of the clause. |
| OpenMPScheduleClauseModifier getSecondScheduleModifier() const { |
| return Modifiers[SECOND]; |
| } |
| |
| /// Get location of '('. |
| SourceLocation getLParenLoc() { return LParenLoc; } |
| |
| /// Get kind location. |
| SourceLocation getScheduleKindLoc() { return KindLoc; } |
| |
| /// Get the first modifier location. |
| SourceLocation getFirstScheduleModifierLoc() const { |
| return ModifiersLoc[FIRST]; |
| } |
| |
| /// Get the second modifier location. |
| SourceLocation getSecondScheduleModifierLoc() const { |
| return ModifiersLoc[SECOND]; |
| } |
| |
| /// Get location of ','. |
| SourceLocation getCommaLoc() { return CommaLoc; } |
| |
| /// Get chunk size. |
| Expr *getChunkSize() { return ChunkSize; } |
| |
| /// Get chunk size. |
| const Expr *getChunkSize() const { return ChunkSize; } |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(&ChunkSize), |
| reinterpret_cast<Stmt **>(&ChunkSize) + 1); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPScheduleClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| 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_schedule; |
| } |
| }; |
| |
| /// This represents 'ordered' clause in the '#pragma omp ...' directive. |
| /// |
| /// \code |
| /// #pragma omp for ordered (2) |
| /// \endcode |
| /// In this example directive '#pragma omp for' has 'ordered' clause with |
| /// parameter 2. |
| class OMPOrderedClause final |
| : public OMPClause, |
| private llvm::TrailingObjects<OMPOrderedClause, Expr *> { |
| friend class OMPClauseReader; |
| friend TrailingObjects; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// Number of for-loops. |
| Stmt *NumForLoops = nullptr; |
| |
| /// Real number of loops. |
| unsigned NumberOfLoops = 0; |
| |
| /// Build 'ordered' clause. |
| /// |
| /// \param Num Expression, possibly associated with this clause. |
| /// \param NumLoops Number of loops, associated with this clause. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| OMPOrderedClause(Expr *Num, unsigned NumLoops, SourceLocation StartLoc, |
| SourceLocation LParenLoc, SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_ordered, StartLoc, EndLoc), |
| LParenLoc(LParenLoc), NumForLoops(Num), NumberOfLoops(NumLoops) {} |
| |
| /// Build an empty clause. |
| explicit OMPOrderedClause(unsigned NumLoops) |
| : OMPClause(llvm::omp::OMPC_ordered, SourceLocation(), SourceLocation()), |
| NumberOfLoops(NumLoops) {} |
| |
| /// Set the number of associated for-loops. |
| void setNumForLoops(Expr *Num) { NumForLoops = Num; } |
| |
| public: |
| /// Build 'ordered' clause. |
| /// |
| /// \param Num Expression, possibly associated with this clause. |
| /// \param NumLoops Number of loops, associated with this clause. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| static OMPOrderedClause *Create(const ASTContext &C, Expr *Num, |
| unsigned NumLoops, SourceLocation StartLoc, |
| SourceLocation LParenLoc, |
| SourceLocation EndLoc); |
| |
| /// Build an empty clause. |
| static OMPOrderedClause* CreateEmpty(const ASTContext &C, unsigned NumLoops); |
| |
| /// Sets the location of '('. |
| void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } |
| |
| /// Returns the location of '('. |
| SourceLocation getLParenLoc() const { return LParenLoc; } |
| |
| /// Return the number of associated for-loops. |
| Expr *getNumForLoops() const { return cast_or_null<Expr>(NumForLoops); } |
| |
| /// Set number of iterations for the specified loop. |
| void setLoopNumIterations(unsigned NumLoop, Expr *NumIterations); |
| /// Get number of iterations for all the loops. |
| ArrayRef<Expr *> getLoopNumIterations() const; |
| |
| /// Set loop counter for the specified loop. |
| void setLoopCounter(unsigned NumLoop, Expr *Counter); |
| /// Get loops counter for the specified loop. |
| Expr *getLoopCounter(unsigned NumLoop); |
| const Expr *getLoopCounter(unsigned NumLoop) const; |
| |
| 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_ordered; |
| } |
| }; |
| |
| /// This represents 'nowait' clause in the '#pragma omp ...' directive. |
| /// |
| /// \code |
| /// #pragma omp for nowait |
| /// \endcode |
| /// In this example directive '#pragma omp for' has 'nowait' clause. |
| class OMPNowaitClause : public OMPClause { |
| 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; |
| } |
| }; |
| |
| /// This represents 'untied' clause in the '#pragma omp ...' directive. |
| /// |
| /// \code |
| /// #pragma omp task untied |
| /// \endcode |
| /// In this example directive '#pragma omp task' has 'untied' clause. |
| class OMPUntiedClause : public OMPClause { |
| public: |
| /// Build 'untied' clause. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param EndLoc Ending location of the clause. |
| OMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_untied, StartLoc, EndLoc) {} |
| |
| /// Build an empty clause. |
| OMPUntiedClause() |
| : OMPClause(llvm::omp::OMPC_untied, 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_untied; |
| } |
| }; |
| |
| /// This represents 'mergeable' clause in the '#pragma omp ...' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp task mergeable |
| /// \endcode |
| /// In this example directive '#pragma omp task' has 'mergeable' clause. |
| class OMPMergeableClause : public OMPClause { |
| public: |
| /// Build 'mergeable' clause. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param EndLoc Ending location of the clause. |
| OMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_mergeable, StartLoc, EndLoc) {} |
| |
| /// Build an empty clause. |
| OMPMergeableClause() |
| : OMPClause(llvm::omp::OMPC_mergeable, 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_mergeable; |
| } |
| }; |
| |
| /// This represents 'read' clause in the '#pragma omp atomic' directive. |
| /// |
| /// \code |
| /// #pragma omp atomic read |
| /// \endcode |
| /// In this example directive '#pragma omp atomic' has 'read' clause. |
| class OMPReadClause : public OMPClause { |
| public: |
| /// Build 'read' clause. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param EndLoc Ending location of the clause. |
| OMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_read, StartLoc, EndLoc) {} |
| |
| /// Build an empty clause. |
| OMPReadClause() |
| : OMPClause(llvm::omp::OMPC_read, 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_read; |
| } |
| }; |
| |
| /// This represents 'write' clause in the '#pragma omp atomic' directive. |
| /// |
| /// \code |
| /// #pragma omp atomic write |
| /// \endcode |
| /// In this example directive '#pragma omp atomic' has 'write' clause. |
| class OMPWriteClause : public OMPClause { |
| public: |
| /// Build 'write' clause. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param EndLoc Ending location of the clause. |
| OMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_write, StartLoc, EndLoc) {} |
| |
| /// Build an empty clause. |
| OMPWriteClause() |
| : OMPClause(llvm::omp::OMPC_write, 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_write; |
| } |
| }; |
| |
| /// This represents 'update' clause in the '#pragma omp atomic' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp atomic update |
| /// \endcode |
| /// In this example directive '#pragma omp atomic' has 'update' clause. |
| /// Also, this class represents 'update' clause in '#pragma omp depobj' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp depobj(a) update(in) |
| /// \endcode |
| /// In this example directive '#pragma omp depobj' has 'update' clause with 'in' |
| /// dependence kind. |
| class OMPUpdateClause final |
| : public OMPClause, |
| private llvm::TrailingObjects<OMPUpdateClause, SourceLocation, |
| OpenMPDependClauseKind> { |
| friend class OMPClauseReader; |
| friend TrailingObjects; |
| |
| /// true if extended version of the clause for 'depobj' directive. |
| bool IsExtended = false; |
| |
| /// Define the sizes of each trailing object array except the last one. This |
| /// is required for TrailingObjects to work properly. |
| size_t numTrailingObjects(OverloadToken<SourceLocation>) const { |
| // 2 locations: for '(' and argument location. |
| return IsExtended ? 2 : 0; |
| } |
| |
| /// Sets the location of '(' in clause for 'depobj' directive. |
| void setLParenLoc(SourceLocation Loc) { |
| assert(IsExtended && "Expected extended clause."); |
| *getTrailingObjects<SourceLocation>() = Loc; |
| } |
| |
| /// Sets the location of '(' in clause for 'depobj' directive. |
| void setArgumentLoc(SourceLocation Loc) { |
| assert(IsExtended && "Expected extended clause."); |
| *std::next(getTrailingObjects<SourceLocation>(), 1) = Loc; |
| } |
| |
| /// Sets the dependence kind for the clause for 'depobj' directive. |
| void setDependencyKind(OpenMPDependClauseKind DK) { |
| assert(IsExtended && "Expected extended clause."); |
| *getTrailingObjects<OpenMPDependClauseKind>() = DK; |
| } |
| |
| /// Build 'update' clause. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param EndLoc Ending location of the clause. |
| OMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc, |
| bool IsExtended) |
| : OMPClause(llvm::omp::OMPC_update, StartLoc, EndLoc), |
| IsExtended(IsExtended) {} |
| |
| /// Build an empty clause. |
| OMPUpdateClause(bool IsExtended) |
| : OMPClause(llvm::omp::OMPC_update, SourceLocation(), SourceLocation()), |
| IsExtended(IsExtended) {} |
| |
| public: |
| /// Creates clause for 'atomic' directive. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the clause. |
| /// \param EndLoc Ending location of the clause. |
| static OMPUpdateClause *Create(const ASTContext &C, SourceLocation StartLoc, |
| SourceLocation EndLoc); |
| |
| /// Creates clause for 'depobj' directive. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param ArgumentLoc Location of the argument. |
| /// \param DK Dependence kind. |
| /// \param EndLoc Ending location of the clause. |
| static OMPUpdateClause *Create(const ASTContext &C, SourceLocation StartLoc, |
| SourceLocation LParenLoc, |
| SourceLocation ArgumentLoc, |
| OpenMPDependClauseKind DK, |
| SourceLocation EndLoc); |
| |
| /// Creates an empty clause with the place for \a N variables. |
| /// |
| /// \param C AST context. |
| /// \param IsExtended true if extended clause for 'depobj' directive must be |
| /// created. |
| static OMPUpdateClause *CreateEmpty(const ASTContext &C, bool IsExtended); |
| |
| /// Checks if the clause is the extended clauses for 'depobj' directive. |
| bool isExtended() const { return IsExtended; } |
| |
| 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()); |
| } |
| |
| /// Gets the location of '(' in clause for 'depobj' directive. |
| SourceLocation getLParenLoc() const { |
| assert(IsExtended && "Expected extended clause."); |
| return *getTrailingObjects<SourceLocation>(); |
| } |
| |
| /// Gets the location of argument in clause for 'depobj' directive. |
| SourceLocation getArgumentLoc() const { |
| assert(IsExtended && "Expected extended clause."); |
| return *std::next(getTrailingObjects<SourceLocation>(), 1); |
| } |
| |
| /// Gets the dependence kind in clause for 'depobj' directive. |
| OpenMPDependClauseKind getDependencyKind() const { |
| assert(IsExtended && "Expected extended clause."); |
| return *getTrailingObjects<OpenMPDependClauseKind>(); |
| } |
| |
| static bool classof(const OMPClause *T) { |
| return T->getClauseKind() == llvm::omp::OMPC_update; |
| } |
| }; |
| |
| /// This represents 'capture' clause in the '#pragma omp atomic' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp atomic capture |
| /// \endcode |
| /// In this example directive '#pragma omp atomic' has 'capture' clause. |
| class OMPCaptureClause : public OMPClause { |
| public: |
| /// Build 'capture' clause. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param EndLoc Ending location of the clause. |
| OMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_capture, StartLoc, EndLoc) {} |
| |
| /// Build an empty clause. |
| OMPCaptureClause() |
| : OMPClause(llvm::omp::OMPC_capture, 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_capture; |
| } |
| }; |
| |
| /// This represents 'compare' clause in the '#pragma omp atomic' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp atomic compare |
| /// \endcode |
| /// In this example directive '#pragma omp atomic' has 'compare' clause. |
| class OMPCompareClause final : public OMPClause { |
| public: |
| /// Build 'compare' clause. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param EndLoc Ending location of the clause. |
| OMPCompareClause(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_compare, StartLoc, EndLoc) {} |
| |
| /// Build an empty clause. |
| OMPCompareClause() |
| : OMPClause(llvm::omp::OMPC_compare, 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_compare; |
| } |
| }; |
| |
| /// This represents 'seq_cst' clause in the '#pragma omp atomic' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp atomic seq_cst |
| /// \endcode |
| /// In this example directive '#pragma omp atomic' has 'seq_cst' clause. |
| class OMPSeqCstClause : public OMPClause { |
| public: |
| /// Build 'seq_cst' clause. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param EndLoc Ending location of the clause. |
| OMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_seq_cst, StartLoc, EndLoc) {} |
| |
| /// Build an empty clause. |
| OMPSeqCstClause() |
| : OMPClause(llvm::omp::OMPC_seq_cst, 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_seq_cst; |
| } |
| }; |
| |
| /// This represents 'acq_rel' clause in the '#pragma omp atomic|flush' |
| /// directives. |
| /// |
| /// \code |
| /// #pragma omp flush acq_rel |
| /// \endcode |
| /// In this example directive '#pragma omp flush' has 'acq_rel' clause. |
| class OMPAcqRelClause final : public OMPClause { |
| public: |
| /// Build 'ack_rel' clause. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param EndLoc Ending location of the clause. |
| OMPAcqRelClause(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_acq_rel, StartLoc, EndLoc) {} |
| |
| /// Build an empty clause. |
| OMPAcqRelClause() |
| : OMPClause(llvm::omp::OMPC_acq_rel, 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_acq_rel; |
| } |
| }; |
| |
| /// This represents 'acquire' clause in the '#pragma omp atomic|flush' |
| /// directives. |
| /// |
| /// \code |
| /// #pragma omp flush acquire |
| /// \endcode |
| /// In this example directive '#pragma omp flush' has 'acquire' clause. |
| class OMPAcquireClause final : public OMPClause { |
| public: |
| /// Build 'acquire' clause. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param EndLoc Ending location of the clause. |
| OMPAcquireClause(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_acquire, StartLoc, EndLoc) {} |
| |
| /// Build an empty clause. |
| OMPAcquireClause() |
| : OMPClause(llvm::omp::OMPC_acquire, 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_acquire; |
| } |
| }; |
| |
| /// This represents 'release' clause in the '#pragma omp atomic|flush' |
| /// directives. |
| /// |
| /// \code |
| /// #pragma omp flush release |
| /// \endcode |
| /// In this example directive '#pragma omp flush' has 'release' clause. |
| class OMPReleaseClause final : public OMPClause { |
| public: |
| /// Build 'release' clause. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param EndLoc Ending location of the clause. |
| OMPReleaseClause(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_release, StartLoc, EndLoc) {} |
| |
| /// Build an empty clause. |
| OMPReleaseClause() |
| : OMPClause(llvm::omp::OMPC_release, 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_release; |
| } |
| }; |
| |
| /// This represents 'relaxed' clause in the '#pragma omp atomic' |
| /// directives. |
| /// |
| /// \code |
| /// #pragma omp atomic relaxed |
| /// \endcode |
| /// In this example directive '#pragma omp atomic' has 'relaxed' clause. |
| class OMPRelaxedClause final : public OMPClause { |
| public: |
| /// Build 'relaxed' clause. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param EndLoc Ending location of the clause. |
| OMPRelaxedClause(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_relaxed, StartLoc, EndLoc) {} |
| |
| /// Build an empty clause. |
| OMPRelaxedClause() |
| : OMPClause(llvm::omp::OMPC_relaxed, 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_relaxed; |
| } |
| }; |
| |
| /// This represents clause 'private' in the '#pragma omp ...' directives. |
| /// |
| /// \code |
| /// #pragma omp parallel private(a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp parallel' has clause 'private' |
| /// with the variables 'a' and 'b'. |
| class OMPPrivateClause final |
| : public OMPVarListClause<OMPPrivateClause>, |
| private llvm::TrailingObjects<OMPPrivateClause, Expr *> { |
| friend class OMPClauseReader; |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Build clause with number of variables \a N. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param N Number of the variables in the clause. |
| OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc, unsigned N) |
| : OMPVarListClause<OMPPrivateClause>(llvm::omp::OMPC_private, StartLoc, |
| LParenLoc, EndLoc, N) {} |
| |
| /// Build an empty clause. |
| /// |
| /// \param N Number of variables. |
| explicit OMPPrivateClause(unsigned N) |
| : OMPVarListClause<OMPPrivateClause>(llvm::omp::OMPC_private, |
| SourceLocation(), SourceLocation(), |
| SourceLocation(), N) {} |
| |
| /// Sets the list of references to private copies with initializers for |
| /// new private variables. |
| /// \param VL List of references. |
| void setPrivateCopies(ArrayRef<Expr *> VL); |
| |
| /// Gets the list of references to private copies with initializers for |
| /// new private variables. |
| MutableArrayRef<Expr *> getPrivateCopies() { |
| return MutableArrayRef<Expr *>(varlist_end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getPrivateCopies() const { |
| return llvm::makeArrayRef(varlist_end(), varlist_size()); |
| } |
| |
| public: |
| /// Creates clause with a list of variables \a VL. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param VL List of references to the variables. |
| /// \param PrivateVL List of references to private copies with initializers. |
| static OMPPrivateClause *Create(const ASTContext &C, SourceLocation StartLoc, |
| SourceLocation LParenLoc, |
| SourceLocation EndLoc, ArrayRef<Expr *> VL, |
| ArrayRef<Expr *> PrivateVL); |
| |
| /// Creates an empty clause with the place for \a N variables. |
| /// |
| /// \param C AST context. |
| /// \param N The number of variables. |
| static OMPPrivateClause *CreateEmpty(const ASTContext &C, unsigned N); |
| |
| using private_copies_iterator = MutableArrayRef<Expr *>::iterator; |
| using private_copies_const_iterator = ArrayRef<const Expr *>::iterator; |
| using private_copies_range = llvm::iterator_range<private_copies_iterator>; |
| using private_copies_const_range = |
| llvm::iterator_range<private_copies_const_iterator>; |
| |
| private_copies_range private_copies() { |
| return private_copies_range(getPrivateCopies().begin(), |
| getPrivateCopies().end()); |
| } |
| |
| private_copies_const_range private_copies() const { |
| return private_copies_const_range(getPrivateCopies().begin(), |
| getPrivateCopies().end()); |
| } |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPPrivateClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| 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_private; |
| } |
| }; |
| |
| /// This represents clause 'firstprivate' in the '#pragma omp ...' |
| /// directives. |
| /// |
| /// \code |
| /// #pragma omp parallel firstprivate(a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp parallel' has clause 'firstprivate' |
| /// with the variables 'a' and 'b'. |
| class OMPFirstprivateClause final |
| : public OMPVarListClause<OMPFirstprivateClause>, |
| public OMPClauseWithPreInit, |
| private llvm::TrailingObjects<OMPFirstprivateClause, Expr *> { |
| friend class OMPClauseReader; |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Build clause with number of variables \a N. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param N Number of the variables in the clause. |
| OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc, unsigned N) |
| : OMPVarListClause<OMPFirstprivateClause>(llvm::omp::OMPC_firstprivate, |
| StartLoc, LParenLoc, EndLoc, N), |
| OMPClauseWithPreInit(this) {} |
| |
| /// Build an empty clause. |
| /// |
| /// \param N Number of variables. |
| explicit OMPFirstprivateClause(unsigned N) |
| : OMPVarListClause<OMPFirstprivateClause>( |
| llvm::omp::OMPC_firstprivate, SourceLocation(), SourceLocation(), |
| SourceLocation(), N), |
| OMPClauseWithPreInit(this) {} |
| |
| /// Sets the list of references to private copies with initializers for |
| /// new private variables. |
| /// \param VL List of references. |
| void setPrivateCopies(ArrayRef<Expr *> VL); |
| |
| /// Gets the list of references to private copies with initializers for |
| /// new private variables. |
| MutableArrayRef<Expr *> getPrivateCopies() { |
| return MutableArrayRef<Expr *>(varlist_end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getPrivateCopies() const { |
| return llvm::makeArrayRef(varlist_end(), varlist_size()); |
| } |
| |
| /// Sets the list of references to initializer variables for new |
| /// private variables. |
| /// \param VL List of references. |
| void setInits(ArrayRef<Expr *> VL); |
| |
| /// Gets the list of references to initializer variables for new |
| /// private variables. |
| MutableArrayRef<Expr *> getInits() { |
| return MutableArrayRef<Expr *>(getPrivateCopies().end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getInits() const { |
| return llvm::makeArrayRef(getPrivateCopies().end(), varlist_size()); |
| } |
| |
| public: |
| /// Creates clause with a list of variables \a VL. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param VL List of references to the original variables. |
| /// \param PrivateVL List of references to private copies with initializers. |
| /// \param InitVL List of references to auto generated variables used for |
| /// initialization of a single array element. Used if firstprivate variable is |
| /// of array type. |
| /// \param PreInit Statement that must be executed before entering the OpenMP |
| /// region with this clause. |
| static OMPFirstprivateClause * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL, |
| ArrayRef<Expr *> InitVL, Stmt *PreInit); |
| |
| /// Creates an empty clause with the place for \a N variables. |
| /// |
| /// \param C AST context. |
| /// \param N The number of variables. |
| static OMPFirstprivateClause *CreateEmpty(const ASTContext &C, unsigned N); |
| |
| using private_copies_iterator = MutableArrayRef<Expr *>::iterator; |
| using private_copies_const_iterator = ArrayRef<const Expr *>::iterator; |
| using private_copies_range = llvm::iterator_range<private_copies_iterator>; |
| using private_copies_const_range = |
| llvm::iterator_range<private_copies_const_iterator>; |
| |
| private_copies_range private_copies() { |
| return private_copies_range(getPrivateCopies().begin(), |
| getPrivateCopies().end()); |
| } |
| private_copies_const_range private_copies() const { |
| return private_copies_const_range(getPrivateCopies().begin(), |
| getPrivateCopies().end()); |
| } |
| |
| using inits_iterator = MutableArrayRef<Expr *>::iterator; |
| using inits_const_iterator = ArrayRef<const Expr *>::iterator; |
| using inits_range = llvm::iterator_range<inits_iterator>; |
| using inits_const_range = llvm::iterator_range<inits_const_iterator>; |
| |
| inits_range inits() { |
| return inits_range(getInits().begin(), getInits().end()); |
| } |
| inits_const_range inits() const { |
| return inits_const_range(getInits().begin(), getInits().end()); |
| } |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPFirstprivateClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| child_range used_children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| const_child_range used_children() const { |
| auto Children = const_cast<OMPFirstprivateClause *>(this)->used_children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| static bool classof(const OMPClause *T) { |
| return T->getClauseKind() == llvm::omp::OMPC_firstprivate; |
| } |
| }; |
| |
| /// This represents clause 'lastprivate' in the '#pragma omp ...' |
| /// directives. |
| /// |
| /// \code |
| /// #pragma omp simd lastprivate(a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp simd' has clause 'lastprivate' |
| /// with the variables 'a' and 'b'. |
| class OMPLastprivateClause final |
| : public OMPVarListClause<OMPLastprivateClause>, |
| public OMPClauseWithPostUpdate, |
| private llvm::TrailingObjects<OMPLastprivateClause, Expr *> { |
| // There are 4 additional tail-allocated arrays at the end of the class: |
| // 1. Contains list of pseudo variables with the default initialization for |
| // each non-firstprivate variables. Used in codegen for initialization of |
| // lastprivate copies. |
| // 2. List of helper expressions for proper generation of assignment operation |
| // required for lastprivate clause. This list represents private variables |
| // (for arrays, single array element). |
| // 3. List of helper expressions for proper generation of assignment operation |
| // required for lastprivate clause. This list represents original variables |
| // (for arrays, single array element). |
| // 4. List of helper expressions that represents assignment operation: |
| // \code |
| // DstExprs = SrcExprs; |
| // \endcode |
| // Required for proper codegen of final assignment performed by the |
| // lastprivate clause. |
| friend class OMPClauseReader; |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Optional lastprivate kind, e.g. 'conditional', if specified by user. |
| OpenMPLastprivateModifier LPKind; |
| /// Optional location of the lasptrivate kind, if specified by user. |
| SourceLocation LPKindLoc; |
| /// Optional colon location, if specified by user. |
| SourceLocation ColonLoc; |
| |
| /// Build clause with number of variables \a N. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param N Number of the variables in the clause. |
| OMPLastprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc, OpenMPLastprivateModifier LPKind, |
| SourceLocation LPKindLoc, SourceLocation ColonLoc, |
| unsigned N) |
| : OMPVarListClause<OMPLastprivateClause>(llvm::omp::OMPC_lastprivate, |
| StartLoc, LParenLoc, EndLoc, N), |
| OMPClauseWithPostUpdate(this), LPKind(LPKind), LPKindLoc(LPKindLoc), |
| ColonLoc(ColonLoc) {} |
| |
| /// Build an empty clause. |
| /// |
| /// \param N Number of variables. |
| explicit OMPLastprivateClause(unsigned N) |
| : OMPVarListClause<OMPLastprivateClause>( |
| llvm::omp::OMPC_lastprivate, SourceLocation(), SourceLocation(), |
| SourceLocation(), N), |
| OMPClauseWithPostUpdate(this) {} |
| |
| /// Get the list of helper expressions for initialization of private |
| /// copies for lastprivate variables. |
| MutableArrayRef<Expr *> getPrivateCopies() { |
| return MutableArrayRef<Expr *>(varlist_end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getPrivateCopies() const { |
| return llvm::makeArrayRef(varlist_end(), varlist_size()); |
| } |
| |
| /// Set list of helper expressions, required for proper codegen of the |
| /// clause. These expressions represent private variables (for arrays, single |
| /// array element) in the final assignment statement performed by the |
| /// lastprivate clause. |
| void setSourceExprs(ArrayRef<Expr *> SrcExprs); |
| |
| /// Get the list of helper source expressions. |
| MutableArrayRef<Expr *> getSourceExprs() { |
| return MutableArrayRef<Expr *>(getPrivateCopies().end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getSourceExprs() const { |
| return llvm::makeArrayRef(getPrivateCopies().end(), varlist_size()); |
| } |
| |
| /// Set list of helper expressions, required for proper codegen of the |
| /// clause. These expressions represent original variables (for arrays, single |
| /// array element) in the final assignment statement performed by the |
| /// lastprivate clause. |
| void setDestinationExprs(ArrayRef<Expr *> DstExprs); |
| |
| /// Get the list of helper destination expressions. |
| MutableArrayRef<Expr *> getDestinationExprs() { |
| return MutableArrayRef<Expr *>(getSourceExprs().end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getDestinationExprs() const { |
| return llvm::makeArrayRef(getSourceExprs().end(), varlist_size()); |
| } |
| |
| /// Set list of helper assignment expressions, required for proper |
| /// codegen of the clause. These expressions are assignment expressions that |
| /// assign private copy of the variable to original variable. |
| void setAssignmentOps(ArrayRef<Expr *> AssignmentOps); |
| |
| /// Get the list of helper assignment expressions. |
| MutableArrayRef<Expr *> getAssignmentOps() { |
| return MutableArrayRef<Expr *>(getDestinationExprs().end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getAssignmentOps() const { |
| return llvm::makeArrayRef(getDestinationExprs().end(), varlist_size()); |
| } |
| |
| /// Sets lastprivate kind. |
| void setKind(OpenMPLastprivateModifier Kind) { LPKind = Kind; } |
| /// Sets location of the lastprivate kind. |
| void setKindLoc(SourceLocation Loc) { LPKindLoc = Loc; } |
| /// Sets colon symbol location. |
| void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } |
| |
| public: |
| /// Creates clause with a list of variables \a VL. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param VL List of references to the variables. |
| /// \param SrcExprs List of helper expressions for proper generation of |
| /// assignment operation required for lastprivate clause. This list represents |
| /// private variables (for arrays, single array element). |
| /// \param DstExprs List of helper expressions for proper generation of |
| /// assignment operation required for lastprivate clause. This list represents |
| /// original variables (for arrays, single array element). |
| /// \param AssignmentOps List of helper expressions that represents assignment |
| /// operation: |
| /// \code |
| /// DstExprs = SrcExprs; |
| /// \endcode |
| /// Required for proper codegen of final assignment performed by the |
| /// lastprivate clause. |
| /// \param LPKind Lastprivate kind, e.g. 'conditional'. |
| /// \param LPKindLoc Location of the lastprivate kind. |
| /// \param ColonLoc Location of the ':' symbol if lastprivate kind is used. |
| /// \param PreInit Statement that must be executed before entering the OpenMP |
| /// region with this clause. |
| /// \param PostUpdate Expression that must be executed after exit from the |
| /// OpenMP region with this clause. |
| static OMPLastprivateClause * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs, |
| ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps, |
| OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, |
| SourceLocation ColonLoc, Stmt *PreInit, Expr *PostUpdate); |
| |
| /// Creates an empty clause with the place for \a N variables. |
| /// |
| /// \param C AST context. |
| /// \param N The number of variables. |
| static OMPLastprivateClause *CreateEmpty(const ASTContext &C, unsigned N); |
| |
| /// Lastprivate kind. |
| OpenMPLastprivateModifier getKind() const { return LPKind; } |
| /// Returns the location of the lastprivate kind. |
| SourceLocation getKindLoc() const { return LPKindLoc; } |
| /// Returns the location of the ':' symbol, if any. |
| SourceLocation getColonLoc() const { return ColonLoc; } |
| |
| using helper_expr_iterator = MutableArrayRef<Expr *>::iterator; |
| using helper_expr_const_iterator = ArrayRef<const Expr *>::iterator; |
| using helper_expr_range = llvm::iterator_range<helper_expr_iterator>; |
| using helper_expr_const_range = |
| llvm::iterator_range<helper_expr_const_iterator>; |
| |
| /// Set list of helper expressions, required for generation of private |
| /// copies of original lastprivate variables. |
| void setPrivateCopies(ArrayRef<Expr *> PrivateCopies); |
| |
| helper_expr_const_range private_copies() const { |
| return helper_expr_const_range(getPrivateCopies().begin(), |
| getPrivateCopies().end()); |
| } |
| |
| helper_expr_range private_copies() { |
| return helper_expr_range(getPrivateCopies().begin(), |
| getPrivateCopies().end()); |
| } |
| |
| helper_expr_const_range source_exprs() const { |
| return helper_expr_const_range(getSourceExprs().begin(), |
| getSourceExprs().end()); |
| } |
| |
| helper_expr_range source_exprs() { |
| return helper_expr_range(getSourceExprs().begin(), getSourceExprs().end()); |
| } |
| |
| helper_expr_const_range destination_exprs() const { |
| return helper_expr_const_range(getDestinationExprs().begin(), |
| getDestinationExprs().end()); |
| } |
| |
| helper_expr_range destination_exprs() { |
| return helper_expr_range(getDestinationExprs().begin(), |
| getDestinationExprs().end()); |
| } |
| |
| helper_expr_const_range assignment_ops() const { |
| return helper_expr_const_range(getAssignmentOps().begin(), |
| getAssignmentOps().end()); |
| } |
| |
| helper_expr_range assignment_ops() { |
| return helper_expr_range(getAssignmentOps().begin(), |
| getAssignmentOps().end()); |
| } |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPLastprivateClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| 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_lastprivate; |
| } |
| }; |
| |
| /// This represents clause 'shared' in the '#pragma omp ...' directives. |
| /// |
| /// \code |
| /// #pragma omp parallel shared(a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp parallel' has clause 'shared' |
| /// with the variables 'a' and 'b'. |
| class OMPSharedClause final |
| : public OMPVarListClause<OMPSharedClause>, |
| private llvm::TrailingObjects<OMPSharedClause, Expr *> { |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Build clause with number of variables \a N. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param N Number of the variables in the clause. |
| OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc, unsigned N) |
| : OMPVarListClause<OMPSharedClause>(llvm::omp::OMPC_shared, StartLoc, |
| LParenLoc, EndLoc, N) {} |
| |
| /// Build an empty clause. |
| /// |
| /// \param N Number of variables. |
| explicit OMPSharedClause(unsigned N) |
| : OMPVarListClause<OMPSharedClause>(llvm::omp::OMPC_shared, |
| SourceLocation(), SourceLocation(), |
| SourceLocation(), N) {} |
| |
| public: |
| /// Creates clause with a list of variables \a VL. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param VL List of references to the variables. |
| static OMPSharedClause *Create(const ASTContext &C, SourceLocation StartLoc, |
| SourceLocation LParenLoc, |
| SourceLocation EndLoc, ArrayRef<Expr *> VL); |
| |
| /// Creates an empty clause with \a N variables. |
| /// |
| /// \param C AST context. |
| /// \param N The number of variables. |
| static OMPSharedClause *CreateEmpty(const ASTContext &C, unsigned N); |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPSharedClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| 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_shared; |
| } |
| }; |
| |
| /// This represents clause 'reduction' in the '#pragma omp ...' |
| /// directives. |
| /// |
| /// \code |
| /// #pragma omp parallel reduction(+:a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp parallel' has clause 'reduction' |
| /// with operator '+' and the variables 'a' and 'b'. |
| class OMPReductionClause final |
| : public OMPVarListClause<OMPReductionClause>, |
| public OMPClauseWithPostUpdate, |
| private llvm::TrailingObjects<OMPReductionClause, Expr *> { |
| friend class OMPClauseReader; |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Reduction modifier. |
| OpenMPReductionClauseModifier Modifier = OMPC_REDUCTION_unknown; |
| |
| /// Reduction modifier location. |
| SourceLocation ModifierLoc; |
| |
| /// Location of ':'. |
| SourceLocation ColonLoc; |
| |
| /// Nested name specifier for C++. |
| NestedNameSpecifierLoc QualifierLoc; |
| |
| /// Name of custom operator. |
| DeclarationNameInfo NameInfo; |
| |
| /// Build clause with number of variables \a N. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param ModifierLoc Modifier location. |
| /// \param ColonLoc Location of ':'. |
| /// \param EndLoc Ending location of the clause. |
| /// \param N Number of the variables in the clause. |
| /// \param QualifierLoc The nested-name qualifier with location information |
| /// \param NameInfo The full name info for reduction identifier. |
| OMPReductionClause(SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation ModifierLoc, SourceLocation ColonLoc, |
| SourceLocation EndLoc, |
| OpenMPReductionClauseModifier Modifier, unsigned N, |
| NestedNameSpecifierLoc QualifierLoc, |
| const DeclarationNameInfo &NameInfo) |
| : OMPVarListClause<OMPReductionClause>(llvm::omp::OMPC_reduction, |
| StartLoc, LParenLoc, EndLoc, N), |
| OMPClauseWithPostUpdate(this), Modifier(Modifier), |
| ModifierLoc(ModifierLoc), ColonLoc(ColonLoc), |
| QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} |
| |
| /// Build an empty clause. |
| /// |
| /// \param N Number of variables. |
| explicit OMPReductionClause(unsigned N) |
| : OMPVarListClause<OMPReductionClause>(llvm::omp::OMPC_reduction, |
| SourceLocation(), SourceLocation(), |
| SourceLocation(), N), |
| OMPClauseWithPostUpdate(this) {} |
| |
| /// Sets reduction modifier. |
| void setModifier(OpenMPReductionClauseModifier M) { Modifier = M; } |
| |
| /// Sets location of the modifier. |
| void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; } |
| |
| /// Sets location of ':' symbol in clause. |
| void setColonLoc(SourceLocation CL) { ColonLoc = CL; } |
| |
| /// Sets the name info for specified reduction identifier. |
| void setNameInfo(DeclarationNameInfo DNI) { NameInfo = DNI; } |
| |
| /// Sets the nested name specifier. |
| void setQualifierLoc(NestedNameSpecifierLoc NSL) { QualifierLoc = NSL; } |
| |
| /// Set list of helper expressions, required for proper codegen of the |
| /// clause. These expressions represent private copy of the reduction |
| /// variable. |
| void setPrivates(ArrayRef<Expr *> Privates); |
| |
| /// Get the list of helper privates. |
| MutableArrayRef<Expr *> getPrivates() { |
| return MutableArrayRef<Expr *>(varlist_end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getPrivates() const { |
| return llvm::makeArrayRef(varlist_end(), varlist_size()); |
| } |
| |
| /// Set list of helper expressions, required for proper codegen of the |
| /// clause. These expressions represent LHS expression in the final |
| /// reduction expression performed by the reduction clause. |
| void setLHSExprs(ArrayRef<Expr *> LHSExprs); |
| |
| /// Get the list of helper LHS expressions. |
| MutableArrayRef<Expr *> getLHSExprs() { |
| return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getLHSExprs() const { |
| return llvm::makeArrayRef(getPrivates().end(), varlist_size()); |
| } |
| |
| /// Set list of helper expressions, required for proper codegen of the |
| /// clause. These expressions represent RHS expression in the final |
| /// reduction expression performed by the reduction clause. |
| /// Also, variables in these expressions are used for proper initialization of |
| /// reduction copies. |
| void setRHSExprs(ArrayRef<Expr *> RHSExprs); |
| |
| /// Get the list of helper destination expressions. |
| MutableArrayRef<Expr *> getRHSExprs() { |
| return MutableArrayRef<Expr *>(getLHSExprs().end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getRHSExprs() const { |
| return llvm::makeArrayRef(getLHSExprs().end(), varlist_size()); |
| } |
| |
| /// Set list of helper reduction expressions, required for proper |
| /// codegen of the clause. These expressions are binary expressions or |
| /// operator/custom reduction call that calculates new value from source |
| /// helper expressions to destination helper expressions. |
| void setReductionOps(ArrayRef<Expr *> ReductionOps); |
| |
| /// Get the list of helper reduction expressions. |
| MutableArrayRef<Expr *> getReductionOps() { |
| return MutableArrayRef<Expr *>(getRHSExprs().end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getReductionOps() const { |
| return llvm::makeArrayRef(getRHSExprs().end(), varlist_size()); |
| } |
| |
| /// Set list of helper copy operations for inscan reductions. |
| /// The form is: Temps[i] = LHS[i]; |
| void setInscanCopyOps(ArrayRef<Expr *> Ops); |
| |
| /// Get the list of helper inscan copy operations. |
| MutableArrayRef<Expr *> getInscanCopyOps() { |
| return MutableArrayRef<Expr *>(getReductionOps().end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getInscanCopyOps() const { |
| return llvm::makeArrayRef(getReductionOps().end(), varlist_size()); |
| } |
| |
| /// Set list of helper temp vars for inscan copy array operations. |
| void setInscanCopyArrayTemps(ArrayRef<Expr *> CopyArrayTemps); |
| |
| /// Get the list of helper inscan copy temps. |
| MutableArrayRef<Expr *> getInscanCopyArrayTemps() { |
| return MutableArrayRef<Expr *>(getInscanCopyOps().end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getInscanCopyArrayTemps() const { |
| return llvm::makeArrayRef(getInscanCopyOps().end(), varlist_size()); |
| } |
| |
| /// Set list of helper temp elements vars for inscan copy array operations. |
| void setInscanCopyArrayElems(ArrayRef<Expr *> CopyArrayElems); |
| |
| /// Get the list of helper inscan copy temps. |
| MutableArrayRef<Expr *> getInscanCopyArrayElems() { |
| return MutableArrayRef<Expr *>(getInscanCopyArrayTemps().end(), |
| varlist_size()); |
| } |
| ArrayRef<const Expr *> getInscanCopyArrayElems() const { |
| return llvm::makeArrayRef(getInscanCopyArrayTemps().end(), varlist_size()); |
| } |
| |
| public: |
| /// Creates clause with a list of variables \a VL. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param ModifierLoc Modifier location. |
| /// \param ColonLoc Location of ':'. |
| /// \param EndLoc Ending location of the clause. |
| /// \param VL The variables in the clause. |
| /// \param QualifierLoc The nested-name qualifier with location information |
| /// \param NameInfo The full name info for reduction identifier. |
| /// \param Privates List of helper expressions for proper generation of |
| /// private copies. |
| /// \param LHSExprs List of helper expressions for proper generation of |
| /// assignment operation required for copyprivate clause. This list represents |
| /// LHSs of the reduction expressions. |
| /// \param RHSExprs List of helper expressions for proper generation of |
| /// assignment operation required for copyprivate clause. This list represents |
| /// RHSs of the reduction expressions. |
| /// Also, variables in these expressions are used for proper initialization of |
| /// reduction copies. |
| /// \param ReductionOps List of helper expressions that represents reduction |
| /// expressions: |
| /// \code |
| /// LHSExprs binop RHSExprs; |
| /// operator binop(LHSExpr, RHSExpr); |
| /// <CutomReduction>(LHSExpr, RHSExpr); |
| /// \endcode |
| /// Required for proper codegen of final reduction operation performed by the |
| /// reduction clause. |
| /// \param CopyOps List of copy operations for inscan reductions: |
| /// \code |
| /// TempExprs = LHSExprs; |
| /// \endcode |
| /// \param CopyArrayTemps Temp arrays for prefix sums. |
| /// \param CopyArrayElems Temp arrays for prefix sums. |
| /// \param PreInit Statement that must be executed before entering the OpenMP |
| /// region with this clause. |
| /// \param PostUpdate Expression that must be executed after exit from the |
| /// OpenMP region with this clause. |
| static OMPReductionClause * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation ModifierLoc, SourceLocation ColonLoc, |
| SourceLocation EndLoc, OpenMPReductionClauseModifier Modifier, |
| ArrayRef<Expr *> VL, NestedNameSpecifierLoc QualifierLoc, |
| const DeclarationNameInfo &NameInfo, ArrayRef<Expr *> Privates, |
| ArrayRef<Expr *> LHSExprs, ArrayRef<Expr *> RHSExprs, |
| ArrayRef<Expr *> ReductionOps, ArrayRef<Expr *> CopyOps, |
| ArrayRef<Expr *> CopyArrayTemps, ArrayRef<Expr *> CopyArrayElems, |
| Stmt *PreInit, Expr *PostUpdate); |
| |
| /// Creates an empty clause with the place for \a N variables. |
| /// |
| /// \param C AST context. |
| /// \param N The number of variables. |
| /// \param Modifier Reduction modifier. |
| static OMPReductionClause * |
| CreateEmpty(const ASTContext &C, unsigned N, |
| OpenMPReductionClauseModifier Modifier); |
| |
| /// Returns modifier. |
| OpenMPReductionClauseModifier getModifier() const { return Modifier; } |
| |
| /// Returns modifier location. |
| SourceLocation getModifierLoc() const { return ModifierLoc; } |
| |
| /// Gets location of ':' symbol in clause. |
| SourceLocation getColonLoc() const { return ColonLoc; } |
| |
| /// Gets the name info for specified reduction identifier. |
| const DeclarationNameInfo &getNameInfo() const { return NameInfo; } |
| |
| /// Gets the nested name specifier. |
| NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } |
| |
| using helper_expr_iterator = MutableArrayRef<Expr *>::iterator; |
| using helper_expr_const_iterator = ArrayRef<const Expr *>::iterator; |
| using helper_expr_range = llvm::iterator_range<helper_expr_iterator>; |
| using helper_expr_const_range = |
| llvm::iterator_range<helper_expr_const_iterator>; |
| |
| helper_expr_const_range privates() const { |
| return helper_expr_const_range(getPrivates().begin(), getPrivates().end()); |
| } |
| |
| helper_expr_range privates() { |
| return helper_expr_range(getPrivates().begin(), getPrivates().end()); |
| } |
| |
| helper_expr_const_range lhs_exprs() const { |
| return helper_expr_const_range(getLHSExprs().begin(), getLHSExprs().end()); |
| } |
| |
| helper_expr_range lhs_exprs() { |
| return helper_expr_range(getLHSExprs().begin(), getLHSExprs().end()); |
| } |
| |
| helper_expr_const_range rhs_exprs() const { |
| return helper_expr_const_range(getRHSExprs().begin(), getRHSExprs().end()); |
| } |
| |
| helper_expr_range rhs_exprs() { |
| return helper_expr_range(getRHSExprs().begin(), getRHSExprs().end()); |
| } |
| |
| helper_expr_const_range reduction_ops() const { |
| return helper_expr_const_range(getReductionOps().begin(), |
| getReductionOps().end()); |
| } |
| |
| helper_expr_range reduction_ops() { |
| return helper_expr_range(getReductionOps().begin(), |
| getReductionOps().end()); |
| } |
| |
| helper_expr_const_range copy_ops() const { |
| return helper_expr_const_range(getInscanCopyOps().begin(), |
| getInscanCopyOps().end()); |
| } |
| |
| helper_expr_range copy_ops() { |
| return helper_expr_range(getInscanCopyOps().begin(), |
| getInscanCopyOps().end()); |
| } |
| |
| helper_expr_const_range copy_array_temps() const { |
| return helper_expr_const_range(getInscanCopyArrayTemps().begin(), |
| getInscanCopyArrayTemps().end()); |
| } |
| |
| helper_expr_range copy_array_temps() { |
| return helper_expr_range(getInscanCopyArrayTemps().begin(), |
| getInscanCopyArrayTemps().end()); |
| } |
| |
| helper_expr_const_range copy_array_elems() const { |
| return helper_expr_const_range(getInscanCopyArrayElems().begin(), |
| getInscanCopyArrayElems().end()); |
| } |
| |
| helper_expr_range copy_array_elems() { |
| return helper_expr_range(getInscanCopyArrayElems().begin(), |
| getInscanCopyArrayElems().end()); |
| } |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPReductionClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| child_range used_children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| const_child_range used_children() const { |
| auto Children = const_cast<OMPReductionClause *>(this)->used_children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| static bool classof(const OMPClause *T) { |
| return T->getClauseKind() == llvm::omp::OMPC_reduction; |
| } |
| }; |
| |
| /// This represents clause 'task_reduction' in the '#pragma omp taskgroup' |
| /// directives. |
| /// |
| /// \code |
| /// #pragma omp taskgroup task_reduction(+:a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp taskgroup' has clause |
| /// 'task_reduction' with operator '+' and the variables 'a' and 'b'. |
| class OMPTaskReductionClause final |
| : public OMPVarListClause<OMPTaskReductionClause>, |
| public OMPClauseWithPostUpdate, |
| private llvm::TrailingObjects<OMPTaskReductionClause, Expr *> { |
| friend class OMPClauseReader; |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Location of ':'. |
| SourceLocation ColonLoc; |
| |
| /// Nested name specifier for C++. |
| NestedNameSpecifierLoc QualifierLoc; |
| |
| /// Name of custom operator. |
| DeclarationNameInfo NameInfo; |
| |
| /// Build clause with number of variables \a N. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param ColonLoc Location of ':'. |
| /// \param N Number of the variables in the clause. |
| /// \param QualifierLoc The nested-name qualifier with location information |
| /// \param NameInfo The full name info for reduction identifier. |
| OMPTaskReductionClause(SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation ColonLoc, SourceLocation EndLoc, |
| unsigned N, NestedNameSpecifierLoc QualifierLoc, |
| const DeclarationNameInfo &NameInfo) |
| : OMPVarListClause<OMPTaskReductionClause>( |
| llvm::omp::OMPC_task_reduction, StartLoc, LParenLoc, EndLoc, N), |
| OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc), |
| QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} |
| |
| /// Build an empty clause. |
| /// |
| /// \param N Number of variables. |
| explicit OMPTaskReductionClause(unsigned N) |
| : OMPVarListClause<OMPTaskReductionClause>( |
| llvm::omp::OMPC_task_reduction, SourceLocation(), SourceLocation(), |
| SourceLocation(), N), |
| OMPClauseWithPostUpdate(this) {} |
| |
| /// Sets location of ':' symbol in clause. |
| void setColonLoc(SourceLocation CL) { ColonLoc = CL; } |
| |
| /// Sets the name info for specified reduction identifier. |
| void setNameInfo(DeclarationNameInfo DNI) { NameInfo = DNI; } |
| |
| /// Sets the nested name specifier. |
| void setQualifierLoc(NestedNameSpecifierLoc NSL) { QualifierLoc = NSL; } |
| |
| /// Set list of helper expressions, required for proper codegen of the clause. |
| /// These expressions represent private copy of the reduction variable. |
| void setPrivates(ArrayRef<Expr *> Privates); |
| |
| /// Get the list of helper privates. |
| MutableArrayRef<Expr *> getPrivates() { |
| return MutableArrayRef<Expr *>(varlist_end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getPrivates() const { |
| return llvm::makeArrayRef(varlist_end(), varlist_size()); |
| } |
| |
| /// Set list of helper expressions, required for proper codegen of the clause. |
| /// These expressions represent LHS expression in the final reduction |
| /// expression performed by the reduction clause. |
| void setLHSExprs(ArrayRef<Expr *> LHSExprs); |
| |
| /// Get the list of helper LHS expressions. |
| MutableArrayRef<Expr *> getLHSExprs() { |
| return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getLHSExprs() const { |
| return llvm::makeArrayRef(getPrivates().end(), varlist_size()); |
| } |
| |
| /// Set list of helper expressions, required for proper codegen of the clause. |
| /// These expressions represent RHS expression in the final reduction |
| /// expression performed by the reduction clause. Also, variables in these |
| /// expressions are used for proper initialization of reduction copies. |
| void setRHSExprs(ArrayRef<Expr *> RHSExprs); |
| |
| /// Get the list of helper destination expressions. |
| MutableArrayRef<Expr *> getRHSExprs() { |
| return MutableArrayRef<Expr *>(getLHSExprs().end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getRHSExprs() const { |
| return llvm::makeArrayRef(getLHSExprs().end(), varlist_size()); |
| } |
| |
| /// Set list of helper reduction expressions, required for proper |
| /// codegen of the clause. These expressions are binary expressions or |
| /// operator/custom reduction call that calculates new value from source |
| /// helper expressions to destination helper expressions. |
| void setReductionOps(ArrayRef<Expr *> ReductionOps); |
| |
| /// Get the list of helper reduction expressions. |
| MutableArrayRef<Expr *> getReductionOps() { |
| return MutableArrayRef<Expr *>(getRHSExprs().end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getReductionOps() const { |
| return llvm::makeArrayRef(getRHSExprs().end(), varlist_size()); |
| } |
| |
| public: |
| /// Creates clause with a list of variables \a VL. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param ColonLoc Location of ':'. |
| /// \param EndLoc Ending location of the clause. |
| /// \param VL The variables in the clause. |
| /// \param QualifierLoc The nested-name qualifier with location information |
| /// \param NameInfo The full name info for reduction identifier. |
| /// \param Privates List of helper expressions for proper generation of |
| /// private copies. |
| /// \param LHSExprs List of helper expressions for proper generation of |
| /// assignment operation required for copyprivate clause. This list represents |
| /// LHSs of the reduction expressions. |
| /// \param RHSExprs List of helper expressions for proper generation of |
| /// assignment operation required for copyprivate clause. This list represents |
| /// RHSs of the reduction expressions. |
| /// Also, variables in these expressions are used for proper initialization of |
| /// reduction copies. |
| /// \param ReductionOps List of helper expressions that represents reduction |
| /// expressions: |
| /// \code |
| /// LHSExprs binop RHSExprs; |
| /// operator binop(LHSExpr, RHSExpr); |
| /// <CutomReduction>(LHSExpr, RHSExpr); |
| /// \endcode |
| /// Required for proper codegen of final reduction operation performed by the |
| /// reduction clause. |
| /// \param PreInit Statement that must be executed before entering the OpenMP |
| /// region with this clause. |
| /// \param PostUpdate Expression that must be executed after exit from the |
| /// OpenMP region with this clause. |
| static OMPTaskReductionClause * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL, |
| NestedNameSpecifierLoc QualifierLoc, |
| const DeclarationNameInfo &NameInfo, ArrayRef<Expr *> Privates, |
| ArrayRef<Expr *> LHSExprs, ArrayRef<Expr *> RHSExprs, |
| ArrayRef<Expr *> ReductionOps, Stmt *PreInit, Expr *PostUpdate); |
| |
| /// Creates an empty clause with the place for \a N variables. |
| /// |
| /// \param C AST context. |
| /// \param N The number of variables. |
| static OMPTaskReductionClause *CreateEmpty(const ASTContext &C, unsigned N); |
| |
| /// Gets location of ':' symbol in clause. |
| SourceLocation getColonLoc() const { return ColonLoc; } |
| |
| /// Gets the name info for specified reduction identifier. |
| const DeclarationNameInfo &getNameInfo() const { return NameInfo; } |
| |
| /// Gets the nested name specifier. |
| NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } |
| |
| using helper_expr_iterator = MutableArrayRef<Expr *>::iterator; |
| using helper_expr_const_iterator = ArrayRef<const Expr *>::iterator; |
| using helper_expr_range = llvm::iterator_range<helper_expr_iterator>; |
| using helper_expr_const_range = |
| llvm::iterator_range<helper_expr_const_iterator>; |
| |
| helper_expr_const_range privates() const { |
| return helper_expr_const_range(getPrivates().begin(), getPrivates().end()); |
| } |
| |
| helper_expr_range privates() { |
| return helper_expr_range(getPrivates().begin(), getPrivates().end()); |
| } |
| |
| helper_expr_const_range lhs_exprs() const { |
| return helper_expr_const_range(getLHSExprs().begin(), getLHSExprs().end()); |
| } |
| |
| helper_expr_range lhs_exprs() { |
| return helper_expr_range(getLHSExprs().begin(), getLHSExprs().end()); |
| } |
| |
| helper_expr_const_range rhs_exprs() const { |
| return helper_expr_const_range(getRHSExprs().begin(), getRHSExprs().end()); |
| } |
| |
| helper_expr_range rhs_exprs() { |
| return helper_expr_range(getRHSExprs().begin(), getRHSExprs().end()); |
| } |
| |
| helper_expr_const_range reduction_ops() const { |
| return helper_expr_const_range(getReductionOps().begin(), |
| getReductionOps().end()); |
| } |
| |
| helper_expr_range reduction_ops() { |
| return helper_expr_range(getReductionOps().begin(), |
| getReductionOps().end()); |
| } |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPTaskReductionClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| 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_task_reduction; |
| } |
| }; |
| |
| /// This represents clause 'in_reduction' in the '#pragma omp task' directives. |
| /// |
| /// \code |
| /// #pragma omp task in_reduction(+:a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp task' has clause 'in_reduction' with |
| /// operator '+' and the variables 'a' and 'b'. |
| class OMPInReductionClause final |
| : public OMPVarListClause<OMPInReductionClause>, |
| public OMPClauseWithPostUpdate, |
| private llvm::TrailingObjects<OMPInReductionClause, Expr *> { |
| friend class OMPClauseReader; |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Location of ':'. |
| SourceLocation ColonLoc; |
| |
| /// Nested name specifier for C++. |
| NestedNameSpecifierLoc QualifierLoc; |
| |
| /// Name of custom operator. |
| DeclarationNameInfo NameInfo; |
| |
| /// Build clause with number of variables \a N. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param ColonLoc Location of ':'. |
| /// \param N Number of the variables in the clause. |
| /// \param QualifierLoc The nested-name qualifier with location information |
| /// \param NameInfo The full name info for reduction identifier. |
| OMPInReductionClause(SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation ColonLoc, SourceLocation EndLoc, |
| unsigned N, NestedNameSpecifierLoc QualifierLoc, |
| const DeclarationNameInfo &NameInfo) |
| : OMPVarListClause<OMPInReductionClause>(llvm::omp::OMPC_in_reduction, |
| StartLoc, LParenLoc, EndLoc, N), |
| OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc), |
| QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} |
| |
| /// Build an empty clause. |
| /// |
| /// \param N Number of variables. |
| explicit OMPInReductionClause(unsigned N) |
| : OMPVarListClause<OMPInReductionClause>( |
| llvm::omp::OMPC_in_reduction, SourceLocation(), SourceLocation(), |
| SourceLocation(), N), |
| OMPClauseWithPostUpdate(this) {} |
| |
| /// Sets location of ':' symbol in clause. |
| void setColonLoc(SourceLocation CL) { ColonLoc = CL; } |
| |
| /// Sets the name info for specified reduction identifier. |
| void setNameInfo(DeclarationNameInfo DNI) { NameInfo = DNI; } |
| |
| /// Sets the nested name specifier. |
| void setQualifierLoc(NestedNameSpecifierLoc NSL) { QualifierLoc = NSL; } |
| |
| /// Set list of helper expressions, required for proper codegen of the clause. |
| /// These expressions represent private copy of the reduction variable. |
| void setPrivates(ArrayRef<Expr *> Privates); |
| |
| /// Get the list of helper privates. |
| MutableArrayRef<Expr *> getPrivates() { |
| return MutableArrayRef<Expr *>(varlist_end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getPrivates() const { |
| return llvm::makeArrayRef(varlist_end(), varlist_size()); |
| } |
| |
| /// Set list of helper expressions, required for proper codegen of the clause. |
| /// These expressions represent LHS expression in the final reduction |
| /// expression performed by the reduction clause. |
| void setLHSExprs(ArrayRef<Expr *> LHSExprs); |
| |
| /// Get the list of helper LHS expressions. |
| MutableArrayRef<Expr *> getLHSExprs() { |
| return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getLHSExprs() const { |
| return llvm::makeArrayRef(getPrivates().end(), varlist_size()); |
| } |
| |
| /// Set list of helper expressions, required for proper codegen of the clause. |
| /// These expressions represent RHS expression in the final reduction |
| /// expression performed by the reduction clause. Also, variables in these |
| /// expressions are used for proper initialization of reduction copies. |
| void setRHSExprs(ArrayRef<Expr *> RHSExprs); |
| |
| /// Get the list of helper destination expressions. |
| MutableArrayRef<Expr *> getRHSExprs() { |
| return MutableArrayRef<Expr *>(getLHSExprs().end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getRHSExprs() const { |
| return llvm::makeArrayRef(getLHSExprs().end(), varlist_size()); |
| } |
| |
| /// Set list of helper reduction expressions, required for proper |
| /// codegen of the clause. These expressions are binary expressions or |
| /// operator/custom reduction call that calculates new value from source |
| /// helper expressions to destination helper expressions. |
| void setReductionOps(ArrayRef<Expr *> ReductionOps); |
| |
| /// Get the list of helper reduction expressions. |
| MutableArrayRef<Expr *> getReductionOps() { |
| return MutableArrayRef<Expr *>(getRHSExprs().end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getReductionOps() const { |
| return llvm::makeArrayRef(getRHSExprs().end(), varlist_size()); |
| } |
| |
| /// Set list of helper reduction taskgroup descriptors. |
| void setTaskgroupDescriptors(ArrayRef<Expr *> ReductionOps); |
| |
| /// Get the list of helper reduction taskgroup descriptors. |
| MutableArrayRef<Expr *> getTaskgroupDescriptors() { |
| return MutableArrayRef<Expr *>(getReductionOps().end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getTaskgroupDescriptors() const { |
| return llvm::makeArrayRef(getReductionOps().end(), varlist_size()); |
| } |
| |
| public: |
| /// Creates clause with a list of variables \a VL. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param ColonLoc Location of ':'. |
| /// \param EndLoc Ending location of the clause. |
| /// \param VL The variables in the clause. |
| /// \param QualifierLoc The nested-name qualifier with location information |
| /// \param NameInfo The full name info for reduction identifier. |
| /// \param Privates List of helper expressions for proper generation of |
| /// private copies. |
| /// \param LHSExprs List of helper expressions for proper generation of |
| /// assignment operation required for copyprivate clause. This list represents |
| /// LHSs of the reduction expressions. |
| /// \param RHSExprs List of helper expressions for proper generation of |
| /// assignment operation required for copyprivate clause. This list represents |
| /// RHSs of the reduction expressions. |
| /// Also, variables in these expressions are used for proper initialization of |
| /// reduction copies. |
| /// \param ReductionOps List of helper expressions that represents reduction |
| /// expressions: |
| /// \code |
| /// LHSExprs binop RHSExprs; |
| /// operator binop(LHSExpr, RHSExpr); |
| /// <CutomReduction>(LHSExpr, RHSExpr); |
| /// \endcode |
| /// Required for proper codegen of final reduction operation performed by the |
| /// reduction clause. |
| /// \param TaskgroupDescriptors List of helper taskgroup descriptors for |
| /// corresponding items in parent taskgroup task_reduction clause. |
| /// \param PreInit Statement that must be executed before entering the OpenMP |
| /// region with this clause. |
| /// \param PostUpdate Expression that must be executed after exit from the |
| /// OpenMP region with this clause. |
| static OMPInReductionClause * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL, |
| NestedNameSpecifierLoc QualifierLoc, |
| const DeclarationNameInfo &NameInfo, ArrayRef<Expr *> Privates, |
| ArrayRef<Expr *> LHSExprs, ArrayRef<Expr *> RHSExprs, |
| ArrayRef<Expr *> ReductionOps, ArrayRef<Expr *> TaskgroupDescriptors, |
| Stmt *PreInit, Expr *PostUpdate); |
| |
| /// Creates an empty clause with the place for \a N variables. |
| /// |
| /// \param C AST context. |
| /// \param N The number of variables. |
| static OMPInReductionClause *CreateEmpty(const ASTContext &C, unsigned N); |
| |
| /// Gets location of ':' symbol in clause. |
| SourceLocation getColonLoc() const { return ColonLoc; } |
| |
| /// Gets the name info for specified reduction identifier. |
| const DeclarationNameInfo &getNameInfo() const { return NameInfo; } |
| |
| /// Gets the nested name specifier. |
| NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } |
| |
| using helper_expr_iterator = MutableArrayRef<Expr *>::iterator; |
| using helper_expr_const_iterator = ArrayRef<const Expr *>::iterator; |
| using helper_expr_range = llvm::iterator_range<helper_expr_iterator>; |
| using helper_expr_const_range = |
| llvm::iterator_range<helper_expr_const_iterator>; |
| |
| helper_expr_const_range privates() const { |
| return helper_expr_const_range(getPrivates().begin(), getPrivates().end()); |
| } |
| |
| helper_expr_range privates() { |
| return helper_expr_range(getPrivates().begin(), getPrivates().end()); |
| } |
| |
| helper_expr_const_range lhs_exprs() const { |
| return helper_expr_const_range(getLHSExprs().begin(), getLHSExprs().end()); |
| } |
| |
| helper_expr_range lhs_exprs() { |
| return helper_expr_range(getLHSExprs().begin(), getLHSExprs().end()); |
| } |
| |
| helper_expr_const_range rhs_exprs() const { |
| return helper_expr_const_range(getRHSExprs().begin(), getRHSExprs().end()); |
| } |
| |
| helper_expr_range rhs_exprs() { |
| return helper_expr_range(getRHSExprs().begin(), getRHSExprs().end()); |
| } |
| |
| helper_expr_const_range reduction_ops() const { |
| return helper_expr_const_range(getReductionOps().begin(), |
| getReductionOps().end()); |
| } |
| |
| helper_expr_range reduction_ops() { |
| return helper_expr_range(getReductionOps().begin(), |
| getReductionOps().end()); |
| } |
| |
| helper_expr_const_range taskgroup_descriptors() const { |
| return helper_expr_const_range(getTaskgroupDescriptors().begin(), |
| getTaskgroupDescriptors().end()); |
| } |
| |
| helper_expr_range taskgroup_descriptors() { |
| return helper_expr_range(getTaskgroupDescriptors().begin(), |
| getTaskgroupDescriptors().end()); |
| } |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPInReductionClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| 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_in_reduction; |
| } |
| }; |
| |
| /// This represents clause 'linear' in the '#pragma omp ...' |
| /// directives. |
| /// |
| /// \code |
| /// #pragma omp simd linear(a,b : 2) |
| /// \endcode |
| /// In this example directive '#pragma omp simd' has clause 'linear' |
| /// with variables 'a', 'b' and linear step '2'. |
| class OMPLinearClause final |
| : public OMPVarListClause<OMPLinearClause>, |
| public OMPClauseWithPostUpdate, |
| private llvm::TrailingObjects<OMPLinearClause, Expr *> { |
| friend class OMPClauseReader; |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Modifier of 'linear' clause. |
| OpenMPLinearClauseKind Modifier = OMPC_LINEAR_val; |
| |
| /// Location of linear modifier if any. |
| SourceLocation ModifierLoc; |
| |
| /// Location of ':'. |
| SourceLocation ColonLoc; |
| |
| /// Sets the linear step for clause. |
| void setStep(Expr *Step) { *(getFinals().end()) = Step; } |
| |
| /// Sets the expression to calculate linear step for clause. |
| void setCalcStep(Expr *CalcStep) { *(getFinals().end() + 1) = CalcStep; } |
| |
| /// Build 'linear' clause with given number of variables \a NumVars. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param ColonLoc Location of ':'. |
| /// \param EndLoc Ending location of the clause. |
| /// \param NumVars Number of variables. |
| OMPLinearClause(SourceLocation StartLoc, SourceLocation LParenLoc, |
| OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, |
| SourceLocation ColonLoc, SourceLocation EndLoc, |
| unsigned NumVars) |
| : OMPVarListClause<OMPLinearClause>(llvm::omp::OMPC_linear, StartLoc, |
| LParenLoc, EndLoc, NumVars), |
| OMPClauseWithPostUpdate(this), Modifier(Modifier), |
| ModifierLoc(ModifierLoc), ColonLoc(ColonLoc) {} |
| |
| /// Build an empty clause. |
| /// |
| /// \param NumVars Number of variables. |
| explicit OMPLinearClause(unsigned NumVars) |
| : OMPVarListClause<OMPLinearClause>(llvm::omp::OMPC_linear, |
| SourceLocation(), SourceLocation(), |
| SourceLocation(), NumVars), |
| OMPClauseWithPostUpdate(this) {} |
| |
| /// Gets the list of initial values for linear variables. |
| /// |
| /// There are NumVars expressions with initial values allocated after the |
| /// varlist, they are followed by NumVars update expressions (used to update |
| /// the linear variable's value on current iteration) and they are followed by |
| /// NumVars final expressions (used to calculate the linear variable's |
| /// value after the loop body). After these lists, there are 2 helper |
| /// expressions - linear step and a helper to calculate it before the |
| /// loop body (used when the linear step is not constant): |
| /// |
| /// { Vars[] /* in OMPVarListClause */; Privates[]; Inits[]; Updates[]; |
| /// Finals[]; Step; CalcStep; } |
| MutableArrayRef<Expr *> getPrivates() { |
| return MutableArrayRef<Expr *>(varlist_end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getPrivates() const { |
| return llvm::makeArrayRef(varlist_end(), varlist_size()); |
| } |
| |
| MutableArrayRef<Expr *> getInits() { |
| return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getInits() const { |
| return llvm::makeArrayRef(getPrivates().end(), varlist_size()); |
| } |
| |
| /// Sets the list of update expressions for linear variables. |
| MutableArrayRef<Expr *> getUpdates() { |
| return MutableArrayRef<Expr *>(getInits().end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getUpdates() const { |
| return llvm::makeArrayRef(getInits().end(), varlist_size()); |
| } |
| |
| /// Sets the list of final update expressions for linear variables. |
| MutableArrayRef<Expr *> getFinals() { |
| return MutableArrayRef<Expr *>(getUpdates().end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getFinals() const { |
| return llvm::makeArrayRef(getUpdates().end(), varlist_size()); |
| } |
| |
| /// Gets the list of used expressions for linear variables. |
| MutableArrayRef<Expr *> getUsedExprs() { |
| return MutableArrayRef<Expr *>(getFinals().end() + 2, varlist_size() + 1); |
| } |
| ArrayRef<const Expr *> getUsedExprs() const { |
| return llvm::makeArrayRef(getFinals().end() + 2, varlist_size() + 1); |
| } |
| |
| /// Sets the list of the copies of original linear variables. |
| /// \param PL List of expressions. |
| void setPrivates(ArrayRef<Expr *> PL); |
| |
| /// Sets the list of the initial values for linear variables. |
| /// \param IL List of expressions. |
| void setInits(ArrayRef<Expr *> IL); |
| |
| public: |
| /// Creates clause with a list of variables \a VL and a linear step |
| /// \a Step. |
| /// |
| /// \param C AST Context. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param Modifier Modifier of 'linear' clause. |
| /// \param ModifierLoc Modifier location. |
| /// \param ColonLoc Location of ':'. |
| /// \param EndLoc Ending location of the clause. |
| /// \param VL List of references to the variables. |
| /// \param PL List of private copies of original variables. |
| /// \param IL List of initial values for the variables. |
| /// \param Step Linear step. |
| /// \param CalcStep Calculation of the linear step. |
| /// \param PreInit Statement that must be executed before entering the OpenMP |
| /// region with this clause. |
| /// \param PostUpdate Expression that must be executed after exit from the |
| /// OpenMP region with this clause. |
| static OMPLinearClause * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, |
| OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, |
| SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL, |
| ArrayRef<Expr *> PL, ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep, |
| Stmt *PreInit, Expr *PostUpdate); |
| |
| /// Creates an empty clause with the place for \a NumVars variables. |
| /// |
| /// \param C AST context. |
| /// \param NumVars Number of variables. |
| static OMPLinearClause *CreateEmpty(const ASTContext &C, unsigned NumVars); |
| |
| /// Set modifier. |
| void setModifier(OpenMPLinearClauseKind Kind) { Modifier = Kind; } |
| |
| /// Return modifier. |
| OpenMPLinearClauseKind getModifier() const { return Modifier; } |
| |
| /// Set modifier location. |
| void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; } |
| |
| /// Return modifier location. |
| SourceLocation getModifierLoc() const { return ModifierLoc; } |
| |
| /// Sets the location of ':'. |
| void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } |
| |
| /// Returns the location of ':'. |
| SourceLocation getColonLoc() const { return ColonLoc; } |
| |
| /// Returns linear step. |
| Expr *getStep() { return *(getFinals().end()); } |
| |
| /// Returns linear step. |
| const Expr *getStep() const { return *(getFinals().end()); } |
| |
| /// Returns expression to calculate linear step. |
| Expr *getCalcStep() { return *(getFinals().end() + 1); } |
| |
| /// Returns expression to calculate linear step. |
| const Expr *getCalcStep() const { return *(getFinals().end() + 1); } |
| |
| /// Sets the list of update expressions for linear variables. |
| /// \param UL List of expressions. |
| void setUpdates(ArrayRef<Expr *> UL); |
| |
| /// Sets the list of final update expressions for linear variables. |
| /// \param FL List of expressions. |
| void setFinals(ArrayRef<Expr *> FL); |
| |
| /// Sets the list of used expressions for the linear clause. |
| void setUsedExprs(ArrayRef<Expr *> UE); |
| |
| using privates_iterator = MutableArrayRef<Expr *>::iterator; |
| using privates_const_iterator = ArrayRef<const Expr *>::iterator; |
| using privates_range = llvm::iterator_range<privates_iterator>; |
| using privates_const_range = llvm::iterator_range<privates_const_iterator>; |
| |
| privates_range privates() { |
| return privates_range(getPrivates().begin(), getPrivates().end()); |
| } |
| |
| privates_const_range privates() const { |
| return privates_const_range(getPrivates().begin(), getPrivates().end()); |
| } |
| |
| using inits_iterator = MutableArrayRef<Expr *>::iterator; |
| using inits_const_iterator = ArrayRef<const Expr *>::iterator; |
| using inits_range = llvm::iterator_range<inits_iterator>; |
| using inits_const_range = llvm::iterator_range<inits_const_iterator>; |
| |
| inits_range inits() { |
| return inits_range(getInits().begin(), getInits().end()); |
| } |
| |
| inits_const_range inits() const { |
| return inits_const_range(getInits().begin(), getInits().end()); |
| } |
| |
| using updates_iterator = MutableArrayRef<Expr *>::iterator; |
| using updates_const_iterator = ArrayRef<const Expr *>::iterator; |
| using updates_range = llvm::iterator_range<updates_iterator>; |
| using updates_const_range = llvm::iterator_range<updates_const_iterator>; |
| |
| updates_range updates() { |
| return updates_range(getUpdates().begin(), getUpdates().end()); |
| } |
| |
| updates_const_range updates() const { |
| return updates_const_range(getUpdates().begin(), getUpdates().end()); |
| } |
| |
| using finals_iterator = MutableArrayRef<Expr *>::iterator; |
| using finals_const_iterator = ArrayRef<const Expr *>::iterator; |
| using finals_range = llvm::iterator_range<finals_iterator>; |
| using finals_const_range = llvm::iterator_range<finals_const_iterator>; |
| |
| finals_range finals() { |
| return finals_range(getFinals().begin(), getFinals().end()); |
| } |
| |
| finals_const_range finals() const { |
| return finals_const_range(getFinals().begin(), getFinals().end()); |
| } |
| |
| using used_expressions_iterator = MutableArrayRef<Expr *>::iterator; |
| using used_expressions_const_iterator = ArrayRef<const Expr *>::iterator; |
| using used_expressions_range = |
| llvm::iterator_range<used_expressions_iterator>; |
| using used_expressions_const_range = |
| llvm::iterator_range<used_expressions_const_iterator>; |
| |
| used_expressions_range used_expressions() { |
| return finals_range(getUsedExprs().begin(), getUsedExprs().end()); |
| } |
| |
| used_expressions_const_range used_expressions() const { |
| return finals_const_range(getUsedExprs().begin(), getUsedExprs().end()); |
| } |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPLinearClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| child_range used_children(); |
| |
| const_child_range used_children() const { |
| auto Children = const_cast<OMPLinearClause *>(this)->used_children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| static bool classof(const OMPClause *T) { |
| return T->getClauseKind() == llvm::omp::OMPC_linear; |
| } |
| }; |
| |
| /// This represents clause 'aligned' in the '#pragma omp ...' |
| /// directives. |
| /// |
| /// \code |
| /// #pragma omp simd aligned(a,b : 8) |
| /// \endcode |
| /// In this example directive '#pragma omp simd' has clause 'aligned' |
| /// with variables 'a', 'b' and alignment '8'. |
| class OMPAlignedClause final |
| : public OMPVarListClause<OMPAlignedClause>, |
| private llvm::TrailingObjects<OMPAlignedClause, Expr *> { |
| friend class OMPClauseReader; |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Location of ':'. |
| SourceLocation ColonLoc; |
| |
| /// Sets the alignment for clause. |
| void setAlignment(Expr *A) { *varlist_end() = A; } |
| |
| /// Build 'aligned' clause with given number of variables \a NumVars. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param ColonLoc Location of ':'. |
| /// \param EndLoc Ending location of the clause. |
| /// \param NumVars Number of variables. |
| OMPAlignedClause(SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation ColonLoc, SourceLocation EndLoc, |
| unsigned NumVars) |
| : OMPVarListClause<OMPAlignedClause>(llvm::omp::OMPC_aligned, StartLoc, |
| LParenLoc, EndLoc, NumVars), |
| ColonLoc(ColonLoc) {} |
| |
| /// Build an empty clause. |
| /// |
| /// \param NumVars Number of variables. |
| explicit OMPAlignedClause(unsigned NumVars) |
| : OMPVarListClause<OMPAlignedClause>(llvm::omp::OMPC_aligned, |
| SourceLocation(), SourceLocation(), |
| SourceLocation(), NumVars) {} |
| |
| public: |
| /// Creates clause with a list of variables \a VL and alignment \a A. |
| /// |
| /// \param C AST Context. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param ColonLoc Location of ':'. |
| /// \param EndLoc Ending location of the clause. |
| /// \param VL List of references to the variables. |
| /// \param A Alignment. |
| static OMPAlignedClause *Create(const ASTContext &C, SourceLocation StartLoc, |
| SourceLocation LParenLoc, |
| SourceLocation ColonLoc, |
| SourceLocation EndLoc, ArrayRef<Expr *> VL, |
| Expr *A); |
| |
| /// Creates an empty clause with the place for \a NumVars variables. |
| /// |
| /// \param C AST context. |
| /// \param NumVars Number of variables. |
| static OMPAlignedClause *CreateEmpty(const ASTContext &C, unsigned NumVars); |
| |
| /// Sets the location of ':'. |
| void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } |
| |
| /// Returns the location of ':'. |
| SourceLocation getColonLoc() const { return ColonLoc; } |
| |
| /// Returns alignment. |
| Expr *getAlignment() { return *varlist_end(); } |
| |
| /// Returns alignment. |
| const Expr *getAlignment() const { return *varlist_end(); } |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPAlignedClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| 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_aligned; |
| } |
| }; |
| |
| /// This represents clause 'copyin' in the '#pragma omp ...' directives. |
| /// |
| /// \code |
| /// #pragma omp parallel copyin(a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp parallel' has clause 'copyin' |
| /// with the variables 'a' and 'b'. |
| class OMPCopyinClause final |
| : public OMPVarListClause<OMPCopyinClause>, |
| private llvm::TrailingObjects<OMPCopyinClause, Expr *> { |
| // Class has 3 additional tail allocated arrays: |
| // 1. List of helper expressions for proper generation of assignment operation |
| // required for copyin clause. This list represents sources. |
| // 2. List of helper expressions for proper generation of assignment operation |
| // required for copyin clause. This list represents destinations. |
| // 3. List of helper expressions that represents assignment operation: |
| // \code |
| // DstExprs = SrcExprs; |
| // \endcode |
| // Required for proper codegen of propagation of master's thread values of |
| // threadprivate variables to local instances of that variables in other |
| // implicit threads. |
| |
| friend class OMPClauseReader; |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Build clause with number of variables \a N. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param N Number of the variables in the clause. |
| OMPCopyinClause(SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc, unsigned N) |
| : OMPVarListClause<OMPCopyinClause>(llvm::omp::OMPC_copyin, StartLoc, |
| LParenLoc, EndLoc, N) {} |
| |
| /// Build an empty clause. |
| /// |
| /// \param N Number of variables. |
| explicit OMPCopyinClause(unsigned N) |
| : OMPVarListClause<OMPCopyinClause>(llvm::omp::OMPC_copyin, |
| SourceLocation(), SourceLocation(), |
| SourceLocation(), N) {} |
| |
| /// Set list of helper expressions, required for proper codegen of the |
| /// clause. These expressions represent source expression in the final |
| /// assignment statement performed by the copyin clause. |
| void setSourceExprs(ArrayRef<Expr *> SrcExprs); |
| |
| /// Get the list of helper source expressions. |
| MutableArrayRef<Expr *> getSourceExprs() { |
| return MutableArrayRef<Expr *>(varlist_end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getSourceExprs() const { |
| return llvm::makeArrayRef(varlist_end(), varlist_size()); |
| } |
| |
| /// Set list of helper expressions, required for proper codegen of the |
| /// clause. These expressions represent destination expression in the final |
| /// assignment statement performed by the copyin clause. |
| void setDestinationExprs(ArrayRef<Expr *> DstExprs); |
| |
| /// Get the list of helper destination expressions. |
| MutableArrayRef<Expr *> getDestinationExprs() { |
| return MutableArrayRef<Expr *>(getSourceExprs().end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getDestinationExprs() const { |
| return llvm::makeArrayRef(getSourceExprs().end(), varlist_size()); |
| } |
| |
| /// Set list of helper assignment expressions, required for proper |
| /// codegen of the clause. These expressions are assignment expressions that |
| /// assign source helper expressions to destination helper expressions |
| /// correspondingly. |
| void setAssignmentOps(ArrayRef<Expr *> AssignmentOps); |
| |
| /// Get the list of helper assignment expressions. |
| MutableArrayRef<Expr *> getAssignmentOps() { |
| return MutableArrayRef<Expr *>(getDestinationExprs().end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getAssignmentOps() const { |
| return llvm::makeArrayRef(getDestinationExprs().end(), varlist_size()); |
| } |
| |
| public: |
| /// Creates clause with a list of variables \a VL. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param VL List of references to the variables. |
| /// \param SrcExprs List of helper expressions for proper generation of |
| /// assignment operation required for copyin clause. This list represents |
| /// sources. |
| /// \param DstExprs List of helper expressions for proper generation of |
| /// assignment operation required for copyin clause. This list represents |
| /// destinations. |
| /// \param AssignmentOps List of helper expressions that represents assignment |
| /// operation: |
| /// \code |
| /// DstExprs = SrcExprs; |
| /// \endcode |
| /// Required for proper codegen of propagation of master's thread values of |
| /// threadprivate variables to local instances of that variables in other |
| /// implicit threads. |
| static OMPCopyinClause * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs, |
| ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps); |
| |
| /// Creates an empty clause with \a N variables. |
| /// |
| /// \param C AST context. |
| /// \param N The number of variables. |
| static OMPCopyinClause *CreateEmpty(const ASTContext &C, unsigned N); |
| |
| using helper_expr_iterator = MutableArrayRef<Expr *>::iterator; |
| using helper_expr_const_iterator = ArrayRef<const Expr *>::iterator; |
| using helper_expr_range = llvm::iterator_range<helper_expr_iterator>; |
| using helper_expr_const_range = |
| llvm::iterator_range<helper_expr_const_iterator>; |
| |
| helper_expr_const_range source_exprs() const { |
| return helper_expr_const_range(getSourceExprs().begin(), |
| getSourceExprs().end()); |
| } |
| |
| helper_expr_range source_exprs() { |
| return helper_expr_range(getSourceExprs().begin(), getSourceExprs().end()); |
| } |
| |
| helper_expr_const_range destination_exprs() const { |
| return helper_expr_const_range(getDestinationExprs().begin(), |
| getDestinationExprs().end()); |
| } |
| |
| helper_expr_range destination_exprs() { |
| return helper_expr_range(getDestinationExprs().begin(), |
| getDestinationExprs().end()); |
| } |
| |
| helper_expr_const_range assignment_ops() const { |
| return helper_expr_const_range(getAssignmentOps().begin(), |
| getAssignmentOps().end()); |
| } |
| |
| helper_expr_range assignment_ops() { |
| return helper_expr_range(getAssignmentOps().begin(), |
| getAssignmentOps().end()); |
| } |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPCopyinClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| 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_copyin; |
| } |
| }; |
| |
| /// This represents clause 'copyprivate' in the '#pragma omp ...' |
| /// directives. |
| /// |
| /// \code |
| /// #pragma omp single copyprivate(a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp single' has clause 'copyprivate' |
| /// with the variables 'a' and 'b'. |
| class OMPCopyprivateClause final |
| : public OMPVarListClause<OMPCopyprivateClause>, |
| private llvm::TrailingObjects<OMPCopyprivateClause, Expr *> { |
| friend class OMPClauseReader; |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Build clause with number of variables \a N. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param N Number of the variables in the clause. |
| OMPCopyprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc, unsigned N) |
| : OMPVarListClause<OMPCopyprivateClause>(llvm::omp::OMPC_copyprivate, |
| StartLoc, LParenLoc, EndLoc, N) { |
| } |
| |
| /// Build an empty clause. |
| /// |
| /// \param N Number of variables. |
| explicit OMPCopyprivateClause(unsigned N) |
| : OMPVarListClause<OMPCopyprivateClause>( |
| llvm::omp::OMPC_copyprivate, SourceLocation(), SourceLocation(), |
| SourceLocation(), N) {} |
| |
| /// Set list of helper expressions, required for proper codegen of the |
| /// clause. These expressions represent source expression in the final |
| /// assignment statement performed by the copyprivate clause. |
| void setSourceExprs(ArrayRef<Expr *> SrcExprs); |
| |
| /// Get the list of helper source expressions. |
| MutableArrayRef<Expr *> getSourceExprs() { |
| return MutableArrayRef<Expr *>(varlist_end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getSourceExprs() const { |
| return llvm::makeArrayRef(varlist_end(), varlist_size()); |
| } |
| |
| /// Set list of helper expressions, required for proper codegen of the |
| /// clause. These expressions represent destination expression in the final |
| /// assignment statement performed by the copyprivate clause. |
| void setDestinationExprs(ArrayRef<Expr *> DstExprs); |
| |
| /// Get the list of helper destination expressions. |
| MutableArrayRef<Expr *> getDestinationExprs() { |
| return MutableArrayRef<Expr *>(getSourceExprs().end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getDestinationExprs() const { |
| return llvm::makeArrayRef(getSourceExprs().end(), varlist_size()); |
| } |
| |
| /// Set list of helper assignment expressions, required for proper |
| /// codegen of the clause. These expressions are assignment expressions that |
| /// assign source helper expressions to destination helper expressions |
| /// correspondingly. |
| void setAssignmentOps(ArrayRef<Expr *> AssignmentOps); |
| |
| /// Get the list of helper assignment expressions. |
| MutableArrayRef<Expr *> getAssignmentOps() { |
| return MutableArrayRef<Expr *>(getDestinationExprs().end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getAssignmentOps() const { |
| return llvm::makeArrayRef(getDestinationExprs().end(), varlist_size()); |
| } |
| |
| public: |
| /// Creates clause with a list of variables \a VL. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param VL List of references to the variables. |
| /// \param SrcExprs List of helper expressions for proper generation of |
| /// assignment operation required for copyprivate clause. This list represents |
| /// sources. |
| /// \param DstExprs List of helper expressions for proper generation of |
| /// assignment operation required for copyprivate clause. This list represents |
| /// destinations. |
| /// \param AssignmentOps List of helper expressions that represents assignment |
| /// operation: |
| /// \code |
| /// DstExprs = SrcExprs; |
| /// \endcode |
| /// Required for proper codegen of final assignment performed by the |
| /// copyprivate clause. |
| static OMPCopyprivateClause * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs, |
| ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps); |
| |
| /// Creates an empty clause with \a N variables. |
| /// |
| /// \param C AST context. |
| /// \param N The number of variables. |
| static OMPCopyprivateClause *CreateEmpty(const ASTContext &C, unsigned N); |
| |
| using helper_expr_iterator = MutableArrayRef<Expr *>::iterator; |
| using helper_expr_const_iterator = ArrayRef<const Expr *>::iterator; |
| using helper_expr_range = llvm::iterator_range<helper_expr_iterator>; |
| using helper_expr_const_range = |
| llvm::iterator_range<helper_expr_const_iterator>; |
| |
| helper_expr_const_range source_exprs() const { |
| return helper_expr_const_range(getSourceExprs().begin(), |
| getSourceExprs().end()); |
| } |
| |
| helper_expr_range source_exprs() { |
| return helper_expr_range(getSourceExprs().begin(), getSourceExprs().end()); |
| } |
| |
| helper_expr_const_range destination_exprs() const { |
| return helper_expr_const_range(getDestinationExprs().begin(), |
| getDestinationExprs().end()); |
| } |
| |
| helper_expr_range destination_exprs() { |
| return helper_expr_range(getDestinationExprs().begin(), |
| getDestinationExprs().end()); |
| } |
| |
| helper_expr_const_range assignment_ops() const { |
| return helper_expr_const_range(getAssignmentOps().begin(), |
| getAssignmentOps().end()); |
| } |
| |
| helper_expr_range assignment_ops() { |
| return helper_expr_range(getAssignmentOps().begin(), |
| getAssignmentOps().end()); |
| } |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPCopyprivateClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| 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_copyprivate; |
| } |
| }; |
| |
| /// This represents implicit clause 'flush' for the '#pragma omp flush' |
| /// directive. |
| /// This clause does not exist by itself, it can be only as a part of 'omp |
| /// flush' directive. This clause is introduced to keep the original structure |
| /// of \a OMPExecutableDirective class and its derivatives and to use the |
| /// existing infrastructure of clauses with the list of variables. |
| /// |
| /// \code |
| /// #pragma omp flush(a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp flush' has implicit clause 'flush' |
| /// with the variables 'a' and 'b'. |
| class OMPFlushClause final |
| : public OMPVarListClause<OMPFlushClause>, |
| private llvm::TrailingObjects<OMPFlushClause, Expr *> { |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Build clause with number of variables \a N. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param N Number of the variables in the clause. |
| OMPFlushClause(SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc, unsigned N) |
| : OMPVarListClause<OMPFlushClause>(llvm::omp::OMPC_flush, StartLoc, |
| LParenLoc, EndLoc, N) {} |
| |
| /// Build an empty clause. |
| /// |
| /// \param N Number of variables. |
| explicit OMPFlushClause(unsigned N) |
| : OMPVarListClause<OMPFlushClause>(llvm::omp::OMPC_flush, |
| SourceLocation(), SourceLocation(), |
| SourceLocation(), N) {} |
| |
| public: |
| /// Creates clause with a list of variables \a VL. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param VL List of references to the variables. |
| static OMPFlushClause *Create(const ASTContext &C, SourceLocation StartLoc, |
| SourceLocation LParenLoc, SourceLocation EndLoc, |
| ArrayRef<Expr *> VL); |
| |
| /// Creates an empty clause with \a N variables. |
| /// |
| /// \param C AST context. |
| /// \param N The number of variables. |
| static OMPFlushClause *CreateEmpty(const ASTContext &C, unsigned N); |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPFlushClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| 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_flush; |
| } |
| }; |
| |
| /// This represents implicit clause 'depobj' for the '#pragma omp depobj' |
| /// directive. |
| /// This clause does not exist by itself, it can be only as a part of 'omp |
| /// depobj' directive. This clause is introduced to keep the original structure |
| /// of \a OMPExecutableDirective class and its derivatives and to use the |
| /// existing infrastructure of clauses with the list of variables. |
| /// |
| /// \code |
| /// #pragma omp depobj(a) destroy |
| /// \endcode |
| /// In this example directive '#pragma omp depobj' has implicit clause 'depobj' |
| /// with the depobj 'a'. |
| class OMPDepobjClause final : public OMPClause { |
| friend class OMPClauseReader; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// Chunk size. |
| Expr *Depobj = nullptr; |
| |
| /// Build clause with number of variables \a N. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| OMPDepobjClause(SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_depobj, StartLoc, EndLoc), |
| LParenLoc(LParenLoc) {} |
| |
| /// Build an empty clause. |
| /// |
| explicit OMPDepobjClause() |
| : OMPClause(llvm::omp::OMPC_depobj, SourceLocation(), SourceLocation()) {} |
| |
| void setDepobj(Expr *E) { Depobj = E; } |
| |
| /// Sets the location of '('. |
| void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } |
| |
| public: |
| /// Creates clause. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param Depobj depobj expression associated with the 'depobj' directive. |
| static OMPDepobjClause *Create(const ASTContext &C, SourceLocation StartLoc, |
| SourceLocation LParenLoc, |
| SourceLocation EndLoc, Expr *Depobj); |
| |
| /// Creates an empty clause. |
| /// |
| /// \param C AST context. |
| static OMPDepobjClause *CreateEmpty(const ASTContext &C); |
| |
| /// Returns depobj expression associated with the clause. |
| Expr *getDepobj() { return Depobj; } |
| const Expr *getDepobj() const { return Depobj; } |
| |
| /// Returns the location of '('. |
| SourceLocation getLParenLoc() const { return LParenLoc; } |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(&Depobj), |
| reinterpret_cast<Stmt **>(&Depobj) + 1); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPDepobjClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| 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_depobj; |
| } |
| }; |
| |
| /// This represents implicit clause 'depend' for the '#pragma omp task' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp task depend(in:a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp task' with clause 'depend' with the |
| /// variables 'a' and 'b' with dependency 'in'. |
| class OMPDependClause final |
| : public OMPVarListClause<OMPDependClause>, |
| private llvm::TrailingObjects<OMPDependClause, Expr *> { |
| friend class OMPClauseReader; |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Dependency type (one of in, out, inout). |
| OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown; |
| |
| /// Dependency type location. |
| SourceLocation DepLoc; |
| |
| /// Colon location. |
| SourceLocation ColonLoc; |
| |
| /// Number of loops, associated with the depend clause. |
| unsigned NumLoops = 0; |
| |
| /// Build clause with number of variables \a N. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param N Number of the variables in the clause. |
| /// \param NumLoops Number of loops that is associated with this depend |
| /// clause. |
| OMPDependClause(SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc, unsigned N, unsigned NumLoops) |
| : OMPVarListClause<OMPDependClause>(llvm::omp::OMPC_depend, StartLoc, |
| LParenLoc, EndLoc, N), |
| NumLoops(NumLoops) {} |
| |
| /// Build an empty clause. |
| /// |
| /// \param N Number of variables. |
| /// \param NumLoops Number of loops that is associated with this depend |
| /// clause. |
| explicit OMPDependClause(unsigned N, unsigned NumLoops) |
| : OMPVarListClause<OMPDependClause>(llvm::omp::OMPC_depend, |
| SourceLocation(), SourceLocation(), |
| SourceLocation(), N), |
| NumLoops(NumLoops) {} |
| |
| /// Set dependency kind. |
| void setDependencyKind(OpenMPDependClauseKind K) { DepKind = K; } |
| |
| /// Set dependency kind and its location. |
| void setDependencyLoc(SourceLocation Loc) { DepLoc = Loc; } |
| |
| /// Set colon location. |
| void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } |
| |
| /// Sets optional dependency modifier. |
| void setModifier(Expr *DepModifier); |
| |
| public: |
| /// Creates clause with a list of variables \a VL. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param DepKind Dependency type. |
| /// \param DepLoc Location of the dependency type. |
| /// \param ColonLoc Colon location. |
| /// \param VL List of references to the variables. |
| /// \param NumLoops Number of loops that is associated with this depend |
| /// clause. |
| static OMPDependClause *Create(const ASTContext &C, SourceLocation StartLoc, |
| SourceLocation LParenLoc, |
| SourceLocation EndLoc, Expr *DepModifier, |
| OpenMPDependClauseKind DepKind, |
| SourceLocation DepLoc, SourceLocation ColonLoc, |
| ArrayRef<Expr *> VL, unsigned NumLoops); |
| |
| /// Creates an empty clause with \a N variables. |
| /// |
| /// \param C AST context. |
| /// \param N The number of variables. |
| /// \param NumLoops Number of loops that is associated with this depend |
| /// clause. |
| static OMPDependClause *CreateEmpty(const ASTContext &C, unsigned N, |
| unsigned NumLoops); |
| |
| /// Get dependency type. |
| OpenMPDependClauseKind getDependencyKind() const { return DepKind; } |
| |
| /// Return optional depend modifier. |
| Expr *getModifier(); |
| const Expr *getModifier() const { |
| return const_cast<OMPDependClause *>(this)->getModifier(); |
| } |
| |
| /// Get dependency type location. |
| SourceLocation getDependencyLoc() const { return DepLoc; } |
| |
| /// Get colon location. |
| SourceLocation getColonLoc() const { return ColonLoc; } |
| |
| /// Get number of loops associated with the clause. |
| unsigned getNumLoops() const { return NumLoops; } |
| |
| /// Set the loop data for the depend clauses with 'sink|source' kind of |
| /// dependency. |
| void setLoopData(unsigned NumLoop, Expr *Cnt); |
| |
| /// Get the loop data. |
| Expr *getLoopData(unsigned NumLoop); |
| const Expr *getLoopData(unsigned NumLoop) const; |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPDependClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| 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_depend; |
| } |
| }; |
| |
| /// This represents 'device' clause in the '#pragma omp ...' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp target device(a) |
| /// \endcode |
| /// In this example directive '#pragma omp target' has clause 'device' |
| /// with single expression 'a'. |
| class OMPDeviceClause : public OMPClause, public OMPClauseWithPreInit { |
| friend class OMPClauseReader; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// Device clause modifier. |
| OpenMPDeviceClauseModifier Modifier = OMPC_DEVICE_unknown; |
| |
| /// Location of the modifier. |
| SourceLocation ModifierLoc; |
| |
| /// Device number. |
| Stmt *Device = nullptr; |
| |
| /// Set the device number. |
| /// |
| /// \param E Device number. |
| void setDevice(Expr *E) { Device = E; } |
| |
| /// Sets modifier. |
| void setModifier(OpenMPDeviceClauseModifier M) { Modifier = M; } |
| |
| /// Setst modifier location. |
| void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; } |
| |
| public: |
| /// Build 'device' clause. |
| /// |
| /// \param Modifier Clause modifier. |
| /// \param E Expression associated with this clause. |
| /// \param CaptureRegion Innermost OpenMP region where expressions in this |
| /// clause must be captured. |
| /// \param StartLoc Starting location of the clause. |
| /// \param ModifierLoc Modifier location. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| OMPDeviceClause(OpenMPDeviceClauseModifier Modifier, Expr *E, Stmt *HelperE, |
| OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, |
| SourceLocation LParenLoc, SourceLocation ModifierLoc, |
| SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_device, StartLoc, EndLoc), |
| OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Modifier(Modifier), |
| ModifierLoc(ModifierLoc), Device(E) { |
| setPreInitStmt(HelperE, CaptureRegion); |
| } |
| |
| /// Build an empty clause. |
| OMPDeviceClause() |
| : OMPClause(llvm::omp::OMPC_device, SourceLocation(), SourceLocation()), |
| OMPClauseWithPreInit(this) {} |
| |
| /// Sets the location of '('. |
| void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } |
| |
| /// Returns the location of '('. |
| SourceLocation getLParenLoc() const { return LParenLoc; } |
| |
| /// Return device number. |
| Expr *getDevice() { return cast<Expr>(Device); } |
| |
| /// Return device number. |
| Expr *getDevice() const { return cast<Expr>(Device); } |
| |
| /// Gets modifier. |
| OpenMPDeviceClauseModifier getModifier() const { return Modifier; } |
| |
| /// Gets modifier location. |
| SourceLocation getModifierLoc() const { return ModifierLoc; } |
| |
| child_range children() { return child_range(&Device, &Device + 1); } |
| |
| const_child_range children() const { |
| return const_child_range(&Device, &Device + 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_device; |
| } |
| }; |
| |
| /// This represents 'threads' clause in the '#pragma omp ...' directive. |
| /// |
| /// \code |
| /// #pragma omp ordered threads |
| /// \endcode |
| /// In this example directive '#pragma omp ordered' has simple 'threads' clause. |
| class OMPThreadsClause : public OMPClause { |
| 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) {} |
| |
| /// 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; |
| } |
| }; |
| |
| /// This represents 'simd' clause in the '#pragma omp ...' directive. |
| /// |
| /// \code |
| /// #pragma omp ordered simd |
| /// \endcode |
| /// In this example directive '#pragma omp ordered' has simple 'simd' clause. |
| class OMPSIMDClause : public OMPClause { |
| public: |
| /// Build 'simd' clause. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param EndLoc Ending location of the clause. |
| OMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_simd, StartLoc, EndLoc) {} |
| |
| /// Build an empty clause. |
| OMPSIMDClause() |
| : OMPClause(llvm::omp::OMPC_simd, 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_simd; |
| } |
| }; |
| |
| /// Struct that defines common infrastructure to handle mappable |
| /// expressions used in OpenMP clauses. |
| class OMPClauseMappableExprCommon { |
| public: |
| /// Class that represents a component of a mappable expression. E.g. |
| /// for an expression S.a, the first component is a declaration reference |
| /// expression associated with 'S' and the second is a member expression |
| /// associated with the field declaration 'a'. If the expression is an array |
| /// subscript it may not have any associated declaration. In that case the |
| /// associated declaration is set to nullptr. |
| class MappableComponent { |
| /// Pair of Expression and Non-contiguous pair associated with the |
| /// component. |
| llvm::PointerIntPair<Expr *, 1, bool> AssociatedExpressionNonContiguousPr; |
| |
| /// Declaration associated with the declaration. If the component does |
| /// not have a declaration (e.g. array subscripts or section), this is set |
| /// to nullptr. |
| ValueDecl *AssociatedDeclaration = nullptr; |
| |
| public: |
| explicit MappableComponent() = default; |
| explicit MappableComponent(Expr *AssociatedExpression, |
| ValueDecl *AssociatedDeclaration, |
| bool IsNonContiguous) |
| : AssociatedExpressionNonContiguousPr(AssociatedExpression, |
| IsNonContiguous), |
| AssociatedDeclaration( |
| AssociatedDeclaration |
| ? cast<ValueDecl>(AssociatedDeclaration->getCanonicalDecl()) |
| : nullptr) {} |
| |
| Expr *getAssociatedExpression() const { |
| return AssociatedExpressionNonContiguousPr.getPointer(); |
| } |
| |
| bool isNonContiguous() const { |
| return AssociatedExpressionNonContiguousPr.getInt(); |
| } |
| |
| ValueDecl *getAssociatedDeclaration() const { |
| return AssociatedDeclaration; |
| } |
| }; |
| |
| // List of components of an expression. This first one is the whole |
| // expression and the last one is the base expression. |
| using MappableExprComponentList = SmallVector<MappableComponent, 8>; |
| using MappableExprComponentListRef = ArrayRef<MappableComponent>; |
| |
| // List of all component lists associated to the same base declaration. |
| // E.g. if both 'S.a' and 'S.b' are a mappable expressions, each will have |
| // their component list but the same base declaration 'S'. |
| using MappableExprComponentLists = SmallVector<MappableExprComponentList, 8>; |
| using MappableExprComponentListsRef = ArrayRef<MappableExprComponentList>; |
| |
| protected: |
| // Return the total number of elements in a list of component lists. |
| static unsigned |
| getComponentsTotalNumber(MappableExprComponentListsRef ComponentLists); |
| |
| // Return the total number of elements in a list of declarations. All |
| // declarations are expected to be canonical. |
| static unsigned |
| getUniqueDeclarationsTotalNumber(ArrayRef<const ValueDecl *> Declarations); |
| }; |
| |
| /// This structure contains all sizes needed for by an |
| /// OMPMappableExprListClause. |
| struct OMPMappableExprListSizeTy { |
| /// Number of expressions listed. |
| unsigned NumVars; |
| /// Number of unique base declarations. |
| unsigned NumUniqueDeclarations; |
| /// Number of component lists. |
| unsigned NumComponentLists; |
| /// Total number of expression components. |
| unsigned NumComponents; |
| OMPMappableExprListSizeTy() = default; |
| OMPMappableExprListSizeTy(unsigned NumVars, unsigned NumUniqueDeclarations, |
| unsigned NumComponentLists, unsigned NumComponents) |
| : NumVars(NumVars), NumUniqueDeclarations(NumUniqueDeclarations), |
| NumComponentLists(NumComponentLists), NumComponents(NumComponents) {} |
| }; |
| |
| /// This represents clauses with a list of expressions that are mappable. |
| /// Examples of these clauses are 'map' in |
| /// '#pragma omp target [enter|exit] [data]...' directives, and 'to' and 'from |
| /// in '#pragma omp target update...' directives. |
| template <class T> |
| class OMPMappableExprListClause : public OMPVarListClause<T>, |
| public OMPClauseMappableExprCommon { |
| friend class OMPClauseReader; |
| |
| /// Number of unique declarations in this clause. |
| unsigned NumUniqueDeclarations; |
| |
| /// Number of component lists in this clause. |
| unsigned NumComponentLists; |
| |
| /// Total number of components in this clause. |
| unsigned NumComponents; |
| |
| /// Whether this clause is possible to have user-defined mappers associated. |
| /// It should be true for map, to, and from clauses, and false for |
| /// use_device_ptr and is_device_ptr. |
| const bool SupportsMapper; |
| |
| /// C++ nested name specifier for the associated user-defined mapper. |
| NestedNameSpecifierLoc MapperQualifierLoc; |
| |
| /// The associated user-defined mapper identifier information. |
| DeclarationNameInfo MapperIdInfo; |
| |
| protected: |
| /// Build a clause for \a NumUniqueDeclarations declarations, \a |
| /// NumComponentLists total component lists, and \a NumComponents total |
| /// components. |
| /// |
| /// \param K Kind of the clause. |
| /// \param Locs Locations needed to build a mappable clause. It includes 1) |
| /// StartLoc: starting location of the clause (the clause keyword); 2) |
| /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. |
| /// \param Sizes All required sizes to build a mappable clause. It includes 1) |
| /// NumVars: number of expressions listed in this clause; 2) |
| /// NumUniqueDeclarations: number of unique base declarations in this clause; |
| /// 3) NumComponentLists: number of component lists in this clause; and 4) |
| /// NumComponents: total number of expression components in the clause. |
| /// \param SupportsMapper Indicates whether this clause is possible to have |
| /// user-defined mappers associated. |
| /// \param MapperQualifierLocPtr C++ nested name specifier for the associated |
| /// user-defined mapper. |
| /// \param MapperIdInfoPtr The identifier of associated user-defined mapper. |
| OMPMappableExprListClause( |
| OpenMPClauseKind K, const OMPVarListLocTy &Locs, |
| const OMPMappableExprListSizeTy &Sizes, bool SupportsMapper = false, |
| NestedNameSpecifierLoc *MapperQualifierLocPtr = nullptr, |
| DeclarationNameInfo *MapperIdInfoPtr = nullptr) |
| : OMPVarListClause<T>(K, Locs.StartLoc, Locs.LParenLoc, Locs.EndLoc, |
| Sizes.NumVars), |
| NumUniqueDeclarations(Sizes.NumUniqueDeclarations), |
| NumComponentLists(Sizes.NumComponentLists), |
| NumComponents(Sizes.NumComponents), SupportsMapper(SupportsMapper) { |
| if (MapperQualifierLocPtr) |
| MapperQualifierLoc = *MapperQualifierLocPtr; |
| if (MapperIdInfoPtr) |
| MapperIdInfo = *MapperIdInfoPtr; |
| } |
| |
| /// Get the unique declarations that are in the trailing objects of the |
| /// class. |
| MutableArrayRef<ValueDecl *> getUniqueDeclsRef() { |
| return MutableArrayRef<ValueDecl *>( |
| static_cast<T *>(this)->template getTrailingObjects<ValueDecl *>(), |
| NumUniqueDeclarations); |
| } |
| |
| /// Get the unique declarations that are in the trailing objects of the |
| /// class. |
| ArrayRef<ValueDecl *> getUniqueDeclsRef() const { |
| return ArrayRef<ValueDecl *>( |
| static_cast<const T *>(this) |
| ->template getTrailingObjects<ValueDecl *>(), |
| NumUniqueDeclarations); |
| } |
| |
| /// Set the unique declarations that are in the trailing objects of the |
| /// class. |
| void setUniqueDecls(ArrayRef<ValueDecl *> UDs) { |
| assert(UDs.size() == NumUniqueDeclarations && |
| "Unexpected amount of unique declarations."); |
| std::copy(UDs.begin(), UDs.end(), getUniqueDeclsRef().begin()); |
| } |
| |
| /// Get the number of lists per declaration that are in the trailing |
| /// objects of the class. |
| MutableArrayRef<unsigned> getDeclNumListsRef() { |
| return MutableArrayRef<unsigned>( |
| static_cast<T *>(this)->template getTrailingObjects<unsigned>(), |
| NumUniqueDeclarations); |
| } |
| |
| /// Get the number of lists per declaration that are in the trailing |
| /// objects of the class. |
| ArrayRef<unsigned> getDeclNumListsRef() const { |
| return ArrayRef<unsigned>( |
| static_cast<const T *>(this)->template getTrailingObjects<unsigned>(), |
| NumUniqueDeclarations); |
| } |
| |
| /// Set the number of lists per declaration that are in the trailing |
| /// objects of the class. |
| void setDeclNumLists(ArrayRef<unsigned> DNLs) { |
| assert(DNLs.size() == NumUniqueDeclarations && |
| "Unexpected amount of list numbers."); |
| std::copy(DNLs.begin(), DNLs.end(), getDeclNumListsRef().begin()); |
| } |
| |
| /// Get the cumulative component lists sizes that are in the trailing |
| /// objects of the class. They are appended after the number of lists. |
| MutableArrayRef<unsigned> getComponentListSizesRef() { |
| return MutableArrayRef<unsigned>( |
| static_cast<T *>(this)->template getTrailingObjects<unsigned>() + |
| NumUniqueDeclarations, |
| NumComponentLists); |
| } |
| |
| /// Get the cumulative component lists sizes that are in the trailing |
| /// objects of the class. They are appended after the number of lists. |
| ArrayRef<unsigned> getComponentListSizesRef() const { |
| return ArrayRef<unsigned>( |
| static_cast<const T *>(this)->template getTrailingObjects<unsigned>() + |
| NumUniqueDeclarations, |
| NumComponentLists); |
| } |
| |
| /// Set the cumulative component lists sizes that are in the trailing |
| /// objects of the class. |
| void setComponentListSizes(ArrayRef<unsigned> CLSs) { |
| assert(CLSs.size() == NumComponentLists && |
| "Unexpected amount of component lists."); |
| std::copy(CLSs.begin(), CLSs.end(), getComponentListSizesRef().begin()); |
| } |
| |
| /// Get the components that are in the trailing objects of the class. |
| MutableArrayRef<MappableComponent> getComponentsRef() { |
| return MutableArrayRef<MappableComponent>( |
| static_cast<T *>(this) |
| ->template getTrailingObjects<MappableComponent>(), |
| NumComponents); |
| } |
| |
| /// Get the components that are in the trailing objects of the class. |
| ArrayRef<MappableComponent> getComponentsRef() const { |
| return ArrayRef<MappableComponent>( |
| static_cast<const T *>(this) |
| ->template getTrailingObjects<MappableComponent>(), |
| NumComponents); |
| } |
| |
| /// Set the components that are in the trailing objects of the class. |
| /// This requires the list sizes so that it can also fill the original |
| /// expressions, which are the first component of each list. |
| void setComponents(ArrayRef<MappableComponent> Components, |
| ArrayRef<unsigned> CLSs) { |
| assert(Components.size() == NumComponents && |
| "Unexpected amount of component lists."); |
| assert(CLSs.size() == NumComponentLists && |
| "Unexpected amount of list sizes."); |
| std::copy(Components.begin(), Components.end(), getComponentsRef().begin()); |
| } |
| |
| /// Fill the clause information from the list of declarations and |
| /// associated component lists. |
| void setClauseInfo(ArrayRef<ValueDecl *> Declarations, |
| MappableExprComponentListsRef ComponentLists) { |
| // Perform some checks to make sure the data sizes are consistent with the |
| // information available when the clause was created. |
| assert(getUniqueDeclarationsTotalNumber(Declarations) == |
| NumUniqueDeclarations && |
| "Unexpected number of mappable expression info entries!"); |
| assert(getComponentsTotalNumber(ComponentLists) == NumComponents && |
| "Unexpected total number of components!"); |
| assert(Declarations.size() == ComponentLists.size() && |
| "Declaration and component lists size is not consistent!"); |
| assert(Declarations.size() == NumComponentLists && |
| "Unexpected declaration and component lists size!"); |
| |
| // Organize the components by declaration and retrieve the original |
| // expression. Original expressions are always the first component of the |
| // mappable component list. |
| llvm::MapVector<ValueDecl *, SmallVector<MappableExprComponentListRef, 8>> |
| ComponentListMap; |
| { |
| auto CI = ComponentLists.begin(); |
| for (auto DI = Declarations.begin(), DE = Declarations.end(); DI != DE; |
| ++DI, ++CI) { |
| assert(!CI->empty() && "Invalid component list!"); |
| ComponentListMap[*DI].push_back(*CI); |
| } |
| } |
| |
| // Iterators of the target storage. |
| auto UniqueDeclarations = getUniqueDeclsRef(); |
| auto UDI = UniqueDeclarations.begin(); |
| |
| auto DeclNumLists = getDeclNumListsRef(); |
| auto DNLI = DeclNumLists.begin(); |
| |
| auto ComponentListSizes = getComponentListSizesRef(); |
| auto CLSI = ComponentListSizes.begin(); |
| |
| auto Components = getComponentsRef(); |
| auto CI = Components.begin(); |
| |
| // Variable to compute the accumulation of the number of components. |
| unsigned PrevSize = 0u; |
| |
| // Scan all the declarations and associated component lists. |
| for (auto &M : ComponentListMap) { |
| // The declaration. |
| auto *D = M.first; |
| // The component lists. |
| auto CL = M.second; |
| |
| // Initialize the entry. |
| *UDI = D; |
| ++UDI; |
| |
| *DNLI = CL.size(); |
| ++DNLI; |
| |
| // Obtain the cumulative sizes and concatenate all the components in the |
| // reserved storage. |
| for (auto C : CL) { |
| // Accumulate with the previous size. |
| PrevSize += C.size(); |
| |
| // Save the size. |
| *CLSI = PrevSize; |
| ++CLSI; |
| |
| // Append components after the current components iterator. |
| CI = std::copy(C.begin(), C.end(), CI); |
| } |
| } |
| } |
| |
| /// Set the nested name specifier of associated user-defined mapper. |
| void setMapperQualifierLoc(NestedNameSpecifierLoc NNSL) { |
| MapperQualifierLoc = NNSL; |
| } |
| |
| /// Set the name of associated user-defined mapper. |
| void setMapperIdInfo(DeclarationNameInfo MapperId) { |
| MapperIdInfo = MapperId; |
| } |
| |
| /// Get the user-defined mapper references that are in the trailing objects of |
| /// the class. |
| MutableArrayRef<Expr *> getUDMapperRefs() { |
| assert(SupportsMapper && |
| "Must be a clause that is possible to have user-defined mappers"); |
| return llvm::makeMutableArrayRef<Expr *>( |
| static_cast<T *>(this)->template getTrailingObjects<Expr *>() + |
| OMPVarListClause<T>::varlist_size(), |
| OMPVarListClause<T>::varlist_size()); |
| } |
| |
| /// Get the user-defined mappers references that are in the trailing objects |
| /// of the class. |
| ArrayRef<Expr *> getUDMapperRefs() const { |
| assert(SupportsMapper && |
| "Must be a clause that is possible to have user-defined mappers"); |
| return llvm::makeArrayRef<Expr *>( |
| static_cast<const T *>(this)->template getTrailingObjects<Expr *>() + |
| OMPVarListClause<T>::varlist_size(), |
| OMPVarListClause<T>::varlist_size()); |
| } |
| |
| /// Set the user-defined mappers that are in the trailing objects of the |
| /// class. |
| void setUDMapperRefs(ArrayRef<Expr *> DMDs) { |
| assert(DMDs.size() == OMPVarListClause<T>::varlist_size() && |
| "Unexpected number of user-defined mappers."); |
| assert(SupportsMapper && |
| "Must be a clause that is possible to have user-defined mappers"); |
| std::copy(DMDs.begin(), DMDs.end(), getUDMapperRefs().begin()); |
| } |
| |
| public: |
| /// Return the number of unique base declarations in this clause. |
| unsigned getUniqueDeclarationsNum() const { return NumUniqueDeclarations; } |
| |
| /// Return the number of lists derived from the clause expressions. |
| unsigned getTotalComponentListNum() const { return NumComponentLists; } |
| |
| /// Return the total number of components in all lists derived from the |
| /// clause. |
| unsigned getTotalComponentsNum() const { return NumComponents; } |
| |
| /// Gets the nested name specifier for associated user-defined mapper. |
| NestedNameSpecifierLoc getMapperQualifierLoc() const { |
| return MapperQualifierLoc; |
| } |
| |
| /// Gets the name info for associated user-defined mapper. |
| const DeclarationNameInfo &getMapperIdInfo() const { return MapperIdInfo; } |
| |
| /// Iterator that browse the components by lists. It also allows |
| /// browsing components of a single declaration. |
| class const_component_lists_iterator |
| : public llvm::iterator_adaptor_base< |
| const_component_lists_iterator, |
| MappableExprComponentListRef::const_iterator, |
| std::forward_iterator_tag, MappableComponent, ptrdiff_t, |
| MappableComponent, MappableComponent> { |
| // The declaration the iterator currently refers to. |
| ArrayRef<ValueDecl *>::iterator DeclCur; |
| |
| // The list number associated with the current declaration. |
| ArrayRef<unsigned>::iterator NumListsCur; |
| |
| // Whether this clause is possible to have user-defined mappers associated. |
| const bool SupportsMapper; |
| |
| // The user-defined mapper associated with the current declaration. |
| ArrayRef<Expr *>::iterator MapperCur; |
| |
| // Remaining lists for the current declaration. |
| unsigned RemainingLists = 0; |
| |
| // The cumulative size of the previous list, or zero if there is no previous |
| // list. |
| unsigned PrevListSize = 0; |
| |
| // The cumulative sizes of the current list - it will delimit the remaining |
| // range of interest. |
| ArrayRef<unsigned>::const_iterator ListSizeCur; |
| ArrayRef<unsigned>::const_iterator ListSizeEnd; |
| |
| // Iterator to the end of the components storage. |
| MappableExprComponentListRef::const_iterator End; |
| |
| public: |
| /// Construct an iterator that scans all lists. |
| explicit const_component_lists_iterator( |
| ArrayRef<ValueDecl *> UniqueDecls, ArrayRef<unsigned> DeclsListNum, |
| ArrayRef<unsigned> CumulativeListSizes, |
| MappableExprComponentListRef Components, bool SupportsMapper, |
| ArrayRef<Expr *> Mappers) |
| : const_component_lists_iterator::iterator_adaptor_base( |
| Components.begin()), |
| DeclCur(UniqueDecls.begin()), NumListsCur(DeclsListNum.begin()), |
| SupportsMapper(SupportsMapper), |
| ListSizeCur(CumulativeListSizes.begin()), |
| ListSizeEnd(CumulativeListSizes.end()), End(Components.end()) { |
| assert(UniqueDecls.size() == DeclsListNum.size() && |
| "Inconsistent number of declarations and list sizes!"); |
| if (!DeclsListNum.empty()) |
| RemainingLists = *NumListsCur; |
| if (SupportsMapper) |
| MapperCur = Mappers.begin(); |
| } |
| |
| /// Construct an iterator that scan lists for a given declaration \a |
| /// Declaration. |
| explicit const_component_lists_iterator( |
| const ValueDecl *Declaration, ArrayRef<ValueDecl *> UniqueDecls, |
| ArrayRef<unsigned> DeclsListNum, ArrayRef<unsigned> CumulativeListSizes, |
| MappableExprComponentListRef Components, bool SupportsMapper, |
| ArrayRef<Expr *> Mappers) |
| : const_component_lists_iterator(UniqueDecls, DeclsListNum, |
| CumulativeListSizes, Components, |
| SupportsMapper, Mappers) { |
| // Look for the desired declaration. While we are looking for it, we |
| // update the state so that we know the component where a given list |
| // starts. |
| for (; DeclCur != UniqueDecls.end(); ++DeclCur, ++NumListsCur) { |
| if (*DeclCur == Declaration) |
| break; |
| |
| assert(*NumListsCur > 0 && "No lists associated with declaration??"); |
| |
| // Skip the lists associated with the current declaration, but save the |
| // last list size that was skipped. |
| std::advance(ListSizeCur, *NumListsCur - 1); |
| PrevListSize = *ListSizeCur; |
| ++ListSizeCur; |
| |
| if (SupportsMapper) |
| ++MapperCur; |
| } |
| |
| // If we didn't find any declaration, advance the iterator to after the |
| // last component and set remaining lists to zero. |
| if (ListSizeCur == CumulativeListSizes.end()) { |
| this->I = End; |
| RemainingLists = 0u; |
| return; |
| } |
| |
| // Set the remaining lists with the total number of lists of the current |
| // declaration. |
| RemainingLists = *NumListsCur; |
| |
| // Adjust the list size end iterator to the end of the relevant range. |
| ListSizeEnd = ListSizeCur; |
| std::advance(ListSizeEnd, RemainingLists); |
| |
| // Given that the list sizes are cumulative, the index of the component |
| // that start the list is the size of the previous list. |
| std::advance(this->I, PrevListSize); |
| } |
| |
| // Return the array with the current list. The sizes are cumulative, so the |
| // array size is the difference between the current size and previous one. |
| std::tuple<const ValueDecl *, MappableExprComponentListRef, |
| const ValueDecl *> |
| operator*() const { |
| assert(ListSizeCur != ListSizeEnd && "Invalid iterator!"); |
| const ValueDecl *Mapper = nullptr; |
| if (SupportsMapper && *MapperCur) |
| Mapper = cast<ValueDecl>(cast<DeclRefExpr>(*MapperCur)->getDecl()); |
| return std::make_tuple( |
| *DeclCur, |
| MappableExprComponentListRef(&*this->I, *ListSizeCur - PrevListSize), |
| Mapper); |
| } |
| std::tuple<const ValueDecl *, MappableExprComponentListRef, |
| const ValueDecl *> |
| operator->() const { |
| return **this; |
| } |
| |
| // Skip the components of the current list. |
| const_component_lists_iterator &operator++() { |
| assert(ListSizeCur != ListSizeEnd && RemainingLists && |
| "Invalid iterator!"); |
| |
| // If we don't have more lists just skip all the components. Otherwise, |
| // advance the iterator by the number of components in the current list. |
| if (std::next(ListSizeCur) == ListSizeEnd) { |
| this->I = End; |
| RemainingLists = 0; |
| } else { |
| std::advance(this->I, *ListSizeCur - PrevListSize); |
| PrevListSize = *ListSizeCur; |
| |
| // We are done with a declaration, move to the next one. |
| if (!(--RemainingLists)) { |
| ++DeclCur; |
| ++NumListsCur; |
| RemainingLists = *NumListsCur; |
| assert(RemainingLists && "No lists in the following declaration??"); |
| } |
| } |
| |
| ++ListSizeCur; |
| if (SupportsMapper) |
| ++MapperCur; |
| return *this; |
| } |
| }; |
| |
| using const_component_lists_range = |
| llvm::iterator_range<const_component_lists_iterator>; |
| |
| /// Iterators for all component lists. |
| const_component_lists_iterator component_lists_begin() const { |
| return const_component_lists_iterator( |
| getUniqueDeclsRef(), getDeclNumListsRef(), getComponentListSizesRef(), |
| getComponentsRef(), SupportsMapper, |
| SupportsMapper ? getUDMapperRefs() : llvm::None); |
| } |
| const_component_lists_iterator component_lists_end() const { |
| return const_component_lists_iterator( |
| ArrayRef<ValueDecl *>(), ArrayRef<unsigned>(), ArrayRef<unsigned>(), |
| MappableExprComponentListRef(getComponentsRef().end(), |
| getComponentsRef().end()), |
| SupportsMapper, llvm::None); |
| } |
| const_component_lists_range component_lists() const { |
| return {component_lists_begin(), component_lists_end()}; |
| } |
| |
| /// Iterators for component lists associated with the provided |
| /// declaration. |
| const_component_lists_iterator |
| decl_component_lists_begin(const ValueDecl *VD) const { |
| return const_component_lists_iterator( |
| VD, getUniqueDeclsRef(), getDeclNumListsRef(), |
| getComponentListSizesRef(), getComponentsRef(), SupportsMapper, |
| SupportsMapper ? getUDMapperRefs() : llvm::None); |
| } |
| const_component_lists_iterator decl_component_lists_end() const { |
| return component_lists_end(); |
| } |
| const_component_lists_range decl_component_lists(const ValueDecl *VD) const { |
| return {decl_component_lists_begin(VD), decl_component_lists_end()}; |
| } |
| |
| /// Iterators to access all the declarations, number of lists, list sizes, and |
| /// components. |
| using const_all_decls_iterator = ArrayRef<ValueDecl *>::iterator; |
| using const_all_decls_range = llvm::iterator_range<const_all_decls_iterator>; |
| |
| const_all_decls_range all_decls() const { |
| auto A = getUniqueDeclsRef(); |
| return const_all_decls_range(A.begin(), A.end()); |
| } |
| |
| using const_all_num_lists_iterator = ArrayRef<unsigned>::iterator; |
| using const_all_num_lists_range = |
| llvm::iterator_range<const_all_num_lists_iterator>; |
| |
| const_all_num_lists_range all_num_lists() const { |
| auto A = getDeclNumListsRef(); |
| return const_all_num_lists_range(A.begin(), A.end()); |
| } |
| |
| using const_all_lists_sizes_iterator = ArrayRef<unsigned>::iterator; |
| using const_all_lists_sizes_range = |
| llvm::iterator_range<const_all_lists_sizes_iterator>; |
| |
| const_all_lists_sizes_range all_lists_sizes() const { |
| auto A = getComponentListSizesRef(); |
| return const_all_lists_sizes_range(A.begin(), A.end()); |
| } |
| |
| using const_all_components_iterator = ArrayRef<MappableComponent>::iterator; |
| using const_all_components_range = |
| llvm::iterator_range<const_all_components_iterator>; |
| |
| const_all_components_range all_components() const { |
| auto A = getComponentsRef(); |
| return const_all_components_range(A.begin(), A.end()); |
| } |
| |
| using mapperlist_iterator = MutableArrayRef<Expr *>::iterator; |
| using mapperlist_const_iterator = ArrayRef<const Expr *>::iterator; |
| using mapperlist_range = llvm::iterator_range<mapperlist_iterator>; |
| using mapperlist_const_range = |
| llvm::iterator_range<mapperlist_const_iterator>; |
| |
| mapperlist_iterator mapperlist_begin() { return getUDMapperRefs().begin(); } |
| mapperlist_iterator mapperlist_end() { return getUDMapperRefs().end(); } |
| mapperlist_const_iterator mapperlist_begin() const { |
| return getUDMapperRefs().begin(); |
| } |
| mapperlist_const_iterator mapperlist_end() const { |
| return getUDMapperRefs().end(); |
| } |
| mapperlist_range mapperlists() { |
| return mapperlist_range(mapperlist_begin(), mapperlist_end()); |
| } |
| mapperlist_const_range mapperlists() const { |
| return mapperlist_const_range(mapperlist_begin(), mapperlist_end()); |
| } |
| }; |
| |
| /// This represents clause 'map' in the '#pragma omp ...' |
| /// directives. |
| /// |
| /// \code |
| /// #pragma omp target map(a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp target' has clause 'map' |
| /// with the variables 'a' and 'b'. |
| class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>, |
| private llvm::TrailingObjects< |
| OMPMapClause, Expr *, ValueDecl *, unsigned, |
| OMPClauseMappableExprCommon::MappableComponent> { |
| friend class OMPClauseReader; |
| friend OMPMappableExprListClause; |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Define the sizes of each trailing object array except the last one. This |
| /// is required for TrailingObjects to work properly. |
| size_t numTrailingObjects(OverloadToken<Expr *>) const { |
| // There are varlist_size() of expressions, and varlist_size() of |
| // user-defined mappers. |
| return 2 * varlist_size(); |
| } |
| size_t numTrailingObjects(OverloadToken<ValueDecl *>) const { |
| return getUniqueDeclarationsNum(); |
| } |
| size_t numTrailingObjects(OverloadToken<unsigned>) const { |
| return getUniqueDeclarationsNum() + getTotalComponentListNum(); |
| } |
| |
| private: |
| /// Map-type-modifiers for the 'map' clause. |
| OpenMPMapModifierKind MapTypeModifiers[NumberOfOMPMapClauseModifiers] = { |
| OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, |
| OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, |
| OMPC_MAP_MODIFIER_unknown}; |
| |
| /// Location of map-type-modifiers for the 'map' clause. |
| SourceLocation MapTypeModifiersLoc[NumberOfOMPMapClauseModifiers]; |
| |
| /// Map type for the 'map' clause. |
| OpenMPMapClauseKind MapType = OMPC_MAP_unknown; |
| |
| /// Is this an implicit map type or not. |
| bool MapTypeIsImplicit = false; |
| |
| /// Location of the map type. |
| SourceLocation MapLoc; |
| |
| /// Colon location. |
| SourceLocation ColonLoc; |
| |
| /// Build a clause for \a NumVars listed expressions, \a |
| /// NumUniqueDeclarations declarations, \a NumComponentLists total component |
| /// lists, and \a NumComponents total expression components. |
| /// |
| /// \param MapModifiers Map-type-modifiers. |
| /// \param MapModifiersLoc Locations of map-type-modifiers. |
| /// \param MapperQualifierLoc C++ nested name specifier for the associated |
| /// user-defined mapper. |
| /// \param MapperIdInfo The identifier of associated user-defined mapper. |
| /// \param MapType Map type. |
| /// \param MapTypeIsImplicit Map type is inferred implicitly. |
| /// \param MapLoc Location of the map type. |
| /// \param Locs Locations needed to build a mappable clause. It includes 1) |
| /// StartLoc: starting location of the clause (the clause keyword); 2) |
| /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. |
| /// \param Sizes All required sizes to build a mappable clause. It includes 1) |
| /// NumVars: number of expressions listed in this clause; 2) |
| /// NumUniqueDeclarations: number of unique base declarations in this clause; |
| /// 3) NumComponentLists: number of component lists in this clause; and 4) |
| /// NumComponents: total number of expression components in the clause. |
| explicit OMPMapClause(ArrayRef<OpenMPMapModifierKind> MapModifiers, |
| ArrayRef<SourceLocation> MapModifiersLoc, |
| NestedNameSpecifierLoc MapperQualifierLoc, |
| DeclarationNameInfo MapperIdInfo, |
| OpenMPMapClauseKind MapType, bool MapTypeIsImplicit, |
| SourceLocation MapLoc, const OMPVarListLocTy &Locs, |
| const OMPMappableExprListSizeTy &Sizes) |
| : OMPMappableExprListClause(llvm::omp::OMPC_map, Locs, Sizes, |
| /*SupportsMapper=*/true, &MapperQualifierLoc, |
| &MapperIdInfo), |
| MapType(MapType), MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) { |
| assert(llvm::array_lengthof(MapTypeModifiers) == MapModifiers.size() && |
| "Unexpected number of map type modifiers."); |
| llvm::copy(MapModifiers, std::begin(MapTypeModifiers)); |
| |
| assert(llvm::array_lengthof(MapTypeModifiersLoc) == |
| MapModifiersLoc.size() && |
| "Unexpected number of map type modifier locations."); |
| llvm::copy(MapModifiersLoc, std::begin(MapTypeModifiersLoc)); |
| } |
| |
| /// Build an empty clause. |
| /// |
| /// \param Sizes All required sizes to build a mappable clause. It includes 1) |
| /// NumVars: number of expressions listed in this clause; 2) |
| /// NumUniqueDeclarations: number of unique base declarations in this clause; |
| /// 3) NumComponentLists: number of component lists in this clause; and 4) |
| /// NumComponents: total number of expression components in the clause. |
| explicit OMPMapClause(const OMPMappableExprListSizeTy &Sizes) |
| : OMPMappableExprListClause(llvm::omp::OMPC_map, OMPVarListLocTy(), Sizes, |
| /*SupportsMapper=*/true) {} |
| |
| /// Set map-type-modifier for the clause. |
| /// |
| /// \param I index for map-type-modifier. |
| /// \param T map-type-modifier for the clause. |
| void setMapTypeModifier(unsigned I, OpenMPMapModifierKind T) { |
| assert(I < NumberOfOMPMapClauseModifiers && |
| "Unexpected index to store map type modifier, exceeds array size."); |
| MapTypeModifiers[I] = T; |
| } |
| |
| /// Set location for the map-type-modifier. |
| /// |
| /// \param I index for map-type-modifier location. |
| /// \param TLoc map-type-modifier location. |
| void setMapTypeModifierLoc(unsigned I, SourceLocation TLoc) { |
| assert(I < NumberOfOMPMapClauseModifiers && |
| "Index to store map type modifier location exceeds array size."); |
| MapTypeModifiersLoc[I] = TLoc; |
| } |
| |
| /// Set type for the clause. |
| /// |
| /// \param T Type for the clause. |
| void setMapType(OpenMPMapClauseKind T) { MapType = T; } |
| |
| /// Set type location. |
| /// |
| /// \param TLoc Type location. |
| void setMapLoc(SourceLocation TLoc) { MapLoc = TLoc; } |
| |
| /// Set colon location. |
| void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } |
| |
| public: |
| /// Creates clause with a list of variables \a VL. |
| /// |
| /// \param C AST context. |
| /// \param Locs Locations needed to build a mappable clause. It includes 1) |
| /// StartLoc: starting location of the clause (the clause keyword); 2) |
| /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. |
| /// \param Vars The original expression used in the clause. |
| /// \param Declarations Declarations used in the clause. |
| /// \param ComponentLists Component lists used in the clause. |
| /// \param UDMapperRefs References to user-defined mappers associated with |
| /// expressions used in the clause. |
| /// \param MapModifiers Map-type-modifiers. |
| /// \param MapModifiersLoc Location of map-type-modifiers. |
| /// \param UDMQualifierLoc C++ nested name specifier for the associated |
| /// user-defined mapper. |
| /// \param MapperId The identifier of associated user-defined mapper. |
| /// \param Type Map type. |
| /// \param TypeIsImplicit Map type is inferred implicitly. |
| /// \param TypeLoc Location of the map type. |
| static OMPMapClause * |
| Create(const ASTContext &C, const OMPVarListLocTy &Locs, |
| ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations, |
| MappableExprComponentListsRef ComponentLists, |
| ArrayRef<Expr *> UDMapperRefs, |
| ArrayRef<OpenMPMapModifierKind> MapModifiers, |
| ArrayRef<SourceLocation> MapModifiersLoc, |
| NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId, |
| OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc); |
| |
| /// Creates an empty clause with the place for \a NumVars original |
| /// expressions, \a NumUniqueDeclarations declarations, \NumComponentLists |
| /// lists, and \a NumComponents expression components. |
| /// |
| /// \param C AST context. |
| /// \param Sizes All required sizes to build a mappable clause. It includes 1) |
| /// NumVars: number of expressions listed in this clause; 2) |
| /// NumUniqueDeclarations: number of unique base declarations in this clause; |
| /// 3) NumComponentLists: number of component lists in this clause; and 4) |
| /// NumComponents: total number of expression components in the clause. |
| static OMPMapClause *CreateEmpty(const ASTContext &C, |
| const OMPMappableExprListSizeTy &Sizes); |
| |
| /// Fetches mapping kind for the clause. |
| OpenMPMapClauseKind getMapType() const LLVM_READONLY { return MapType; } |
| |
| /// Is this an implicit map type? |
| /// We have to capture 'IsMapTypeImplicit' from the parser for more |
| /// informative error messages. It helps distinguish map(r) from |
| /// map(tofrom: r), which is important to print more helpful error |
| /// messages for some target directives. |
| bool isImplicitMapType() const LLVM_READONLY { return MapTypeIsImplicit; } |
| |
| /// Fetches the map-type-modifier at 'Cnt' index of array of modifiers. |
| /// |
| /// \param Cnt index for map-type-modifier. |
| OpenMPMapModifierKind getMapTypeModifier(unsigned Cnt) const LLVM_READONLY { |
| assert(Cnt < NumberOfOMPMapClauseModifiers && |
| "Requested modifier exceeds the total number of modifiers."); |
| return MapTypeModifiers[Cnt]; |
| } |
| |
| /// Fetches the map-type-modifier location at 'Cnt' index of array of |
| /// modifiers' locations. |
| /// |
| /// \param Cnt index for map-type-modifier location. |
| SourceLocation getMapTypeModifierLoc(unsigned Cnt) const LLVM_READONLY { |
| assert(Cnt < NumberOfOMPMapClauseModifiers && |
| "Requested modifier location exceeds total number of modifiers."); |
| return MapTypeModifiersLoc[Cnt]; |
| } |
| |
| /// Fetches ArrayRef of map-type-modifiers. |
| ArrayRef<OpenMPMapModifierKind> getMapTypeModifiers() const LLVM_READONLY { |
| return llvm::makeArrayRef(MapTypeModifiers); |
| } |
| |
| /// Fetches ArrayRef of location of map-type-modifiers. |
| ArrayRef<SourceLocation> getMapTypeModifiersLoc() const LLVM_READONLY { |
| return llvm::makeArrayRef(MapTypeModifiersLoc); |
| } |
| |
| /// Fetches location of clause mapping kind. |
| SourceLocation getMapLoc() const LLVM_READONLY { return MapLoc; } |
| |
| /// Get colon location. |
| SourceLocation getColonLoc() const { return ColonLoc; } |
| |
| child_range children() { |
| return child_range( |
| reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPMapClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| child_range used_children() { |
| if (MapType == OMPC_MAP_to || MapType == OMPC_MAP_tofrom) |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| return child_range(child_iterator(), child_iterator()); |
| } |
| const_child_range used_children() const { |
| auto Children = const_cast<OMPMapClause *>(this)->used_children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| |
| static bool classof(const OMPClause *T) { |
| return T->getClauseKind() == llvm::omp::OMPC_map; |
| } |
| }; |
| |
| /// This represents 'num_teams' clause in the '#pragma omp ...' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp teams num_teams(n) |
| /// \endcode |
| /// In this example directive '#pragma omp teams' has clause 'num_teams' |
| /// with single expression 'n'. |
| class OMPNumTeamsClause : public OMPClause, public OMPClauseWithPreInit { |
| friend class OMPClauseReader; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// NumTeams number. |
| Stmt *NumTeams = nullptr; |
| |
| /// Set the NumTeams number. |
| /// |
| /// \param E NumTeams number. |
| void setNumTeams(Expr *E) { NumTeams = E; } |
| |
| public: |
| /// Build 'num_teams' clause. |
| /// |
| /// \param E Expression associated with this clause. |
| /// \param HelperE Helper Expression associated with this clause. |
| /// \param CaptureRegion Innermost OpenMP region where expressions in this |
| /// clause must be captured. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| OMPNumTeamsClause(Expr *E, Stmt *HelperE, OpenMPDirectiveKind CaptureRegion, |
| SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_num_teams, StartLoc, EndLoc), |
| OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumTeams(E) { |
| setPreInitStmt(HelperE, CaptureRegion); |
| } |
| |
| /// Build an empty clause. |
| OMPNumTeamsClause() |
| : OMPClause(llvm::omp::OMPC_num_teams, SourceLocation(), |
| SourceLocation()), |
| OMPClauseWithPreInit(this) {} |
| |
| /// Sets the location of '('. |
| void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } |
| |
| /// Returns the location of '('. |
| SourceLocation getLParenLoc() const { return LParenLoc; } |
| |
| /// Return NumTeams number. |
| Expr *getNumTeams() { return cast<Expr>(NumTeams); } |
| |
| /// Return NumTeams number. |
| Expr *getNumTeams() const { return cast<Expr>(NumTeams); } |
| |
| child_range children() { return child_range(&NumTeams, &NumTeams + 1); } |
| |
| const_child_range children() const { |
| return const_child_range(&NumTeams, &NumTeams + 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_teams; |
| } |
| }; |
| |
| /// This represents 'thread_limit' clause in the '#pragma omp ...' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp teams thread_limit(n) |
| /// \endcode |
| /// In this example directive '#pragma omp teams' has clause 'thread_limit' |
| /// with single expression 'n'. |
| class OMPThreadLimitClause : public OMPClause, public OMPClauseWithPreInit { |
| friend class OMPClauseReader; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// ThreadLimit number. |
| Stmt *ThreadLimit = nullptr; |
| |
| /// Set the ThreadLimit number. |
| /// |
| /// \param E ThreadLimit number. |
| void setThreadLimit(Expr *E) { ThreadLimit = E; } |
| |
| public: |
| /// Build 'thread_limit' clause. |
| /// |
| /// \param E Expression associated with this clause. |
| /// \param HelperE Helper Expression associated with this clause. |
| /// \param CaptureRegion Innermost OpenMP region where expressions in this |
| /// clause must be captured. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| OMPThreadLimitClause(Expr *E, Stmt *HelperE, |
| OpenMPDirectiveKind CaptureRegion, |
| SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_thread_limit, StartLoc, EndLoc), |
| OMPClauseWithPreInit(this), LParenLoc(LParenLoc), ThreadLimit(E) { |
| setPreInitStmt(HelperE, CaptureRegion); |
| } |
| |
| /// Build an empty clause. |
| OMPThreadLimitClause() |
| : OMPClause(llvm::omp::OMPC_thread_limit, SourceLocation(), |
| SourceLocation()), |
| OMPClauseWithPreInit(this) {} |
| |
| /// Sets the location of '('. |
| void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } |
| |
| /// Returns the location of '('. |
| SourceLocation getLParenLoc() const { return LParenLoc; } |
| |
| /// Return ThreadLimit number. |
| Expr *getThreadLimit() { return cast<Expr>(ThreadLimit); } |
| |
| /// Return ThreadLimit number. |
| Expr *getThreadLimit() const { return cast<Expr>(ThreadLimit); } |
| |
| child_range children() { return child_range(&ThreadLimit, &ThreadLimit + 1); } |
| |
| const_child_range children() const { |
| return const_child_range(&ThreadLimit, &ThreadLimit + 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_thread_limit; |
| } |
| }; |
| |
| /// This represents 'priority' clause in the '#pragma omp ...' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp task priority(n) |
| /// \endcode |
| /// In this example directive '#pragma omp teams' has clause 'priority' with |
| /// single expression 'n'. |
| class OMPPriorityClause : public OMPClause, public OMPClauseWithPreInit { |
| friend class OMPClauseReader; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// Priority number. |
| Stmt *Priority = nullptr; |
| |
| /// Set the Priority number. |
| /// |
| /// \param E Priority number. |
| void setPriority(Expr *E) { Priority = E; } |
| |
| public: |
| /// Build 'priority' clause. |
| /// |
| /// \param Priority Expression associated with this clause. |
| /// \param HelperPriority Helper priority for the construct. |
| /// \param CaptureRegion Innermost OpenMP region where expressions in this |
| /// clause must be captured. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| OMPPriorityClause(Expr *Priority, Stmt *HelperPriority, |
| OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, |
| SourceLocation LParenLoc, SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_priority, StartLoc, EndLoc), |
| OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Priority(Priority) { |
| setPreInitStmt(HelperPriority, CaptureRegion); |
| } |
| |
| /// Build an empty clause. |
| OMPPriorityClause() |
| : OMPClause(llvm::omp::OMPC_priority, SourceLocation(), SourceLocation()), |
| OMPClauseWithPreInit(this) {} |
| |
| /// Sets the location of '('. |
| void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } |
| |
| /// Returns the location of '('. |
| SourceLocation getLParenLoc() const { return LParenLoc; } |
| |
| /// Return Priority number. |
| Expr *getPriority() { return cast<Expr>(Priority); } |
| |
| /// Return Priority number. |
| Expr *getPriority() const { return cast<Expr>(Priority); } |
| |
| child_range children() { return child_range(&Priority, &Priority + 1); } |
| |
| const_child_range children() const { |
| return const_child_range(&Priority, &Priority + 1); |
| } |
| |
| child_range used_children(); |
| const_child_range used_children() const { |
| auto Children = const_cast<OMPPriorityClause *>(this)->used_children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| static bool classof(const OMPClause *T) { |
| return T->getClauseKind() == llvm::omp::OMPC_priority; |
| } |
| }; |
| |
| /// This represents 'grainsize' clause in the '#pragma omp ...' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp taskloop grainsize(4) |
| /// \endcode |
| /// In this example directive '#pragma omp taskloop' has clause 'grainsize' |
| /// with single expression '4'. |
| class OMPGrainsizeClause : public OMPClause, public OMPClauseWithPreInit { |
| friend class OMPClauseReader; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// Safe iteration space distance. |
| Stmt *Grainsize = nullptr; |
| |
| /// Set safelen. |
| void setGrainsize(Expr *Size) { Grainsize = Size; } |
| |
| public: |
| /// Build 'grainsize' clause. |
| /// |
| /// \param Size Expression associated with this clause. |
| /// \param HelperSize Helper grainsize for the construct. |
| /// \param CaptureRegion Innermost OpenMP region where expressions in this |
| /// clause must be captured. |
| /// \param StartLoc Starting location of the clause. |
| /// \param EndLoc Ending location of the clause. |
| OMPGrainsizeClause(Expr *Size, Stmt *HelperSize, |
| OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, |
| SourceLocation LParenLoc, SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_grainsize, StartLoc, EndLoc), |
| OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Grainsize(Size) { |
| setPreInitStmt(HelperSize, CaptureRegion); |
| } |
| |
| /// Build an empty clause. |
| explicit OMPGrainsizeClause() |
| : OMPClause(llvm::omp::OMPC_grainsize, SourceLocation(), |
| SourceLocation()), |
| OMPClauseWithPreInit(this) {} |
| |
| /// Sets the location of '('. |
| void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } |
| |
| /// Returns the location of '('. |
| SourceLocation getLParenLoc() const { return LParenLoc; } |
| |
| /// Return safe iteration space distance. |
| Expr *getGrainsize() const { return cast_or_null<Expr>(Grainsize); } |
| |
| child_range children() { return child_range(&Grainsize, &Grainsize + 1); } |
| |
| const_child_range children() const { |
| return const_child_range(&Grainsize, &Grainsize + 1); |
| } |
| |
| child_range used_children(); |
| const_child_range used_children() const { |
| auto Children = const_cast<OMPGrainsizeClause *>(this)->used_children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| static bool classof(const OMPClause *T) { |
| return T->getClauseKind() == llvm::omp::OMPC_grainsize; |
| } |
| }; |
| |
| /// This represents 'nogroup' clause in the '#pragma omp ...' directive. |
| /// |
| /// \code |
| /// #pragma omp taskloop nogroup |
| /// \endcode |
| /// In this example directive '#pragma omp taskloop' has 'nogroup' clause. |
| class OMPNogroupClause : public OMPClause { |
| public: |
| /// Build 'nogroup' clause. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param EndLoc Ending location of the clause. |
| OMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_nogroup, StartLoc, EndLoc) {} |
| |
| /// Build an empty clause. |
| OMPNogroupClause() |
| : OMPClause(llvm::omp::OMPC_nogroup, 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_nogroup; |
| } |
| }; |
| |
| /// This represents 'num_tasks' clause in the '#pragma omp ...' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp taskloop num_tasks(4) |
| /// \endcode |
| /// In this example directive '#pragma omp taskloop' has clause 'num_tasks' |
| /// with single expression '4'. |
| class OMPNumTasksClause : public OMPClause, public OMPClauseWithPreInit { |
| friend class OMPClauseReader; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// Safe iteration space distance. |
| Stmt *NumTasks = nullptr; |
| |
| /// Set safelen. |
| void setNumTasks(Expr *Size) { NumTasks = Size; } |
| |
| public: |
| /// Build 'num_tasks' clause. |
| /// |
| /// \param Size Expression associated with this clause. |
| /// \param HelperSize Helper grainsize for the construct. |
| /// \param CaptureRegion Innermost OpenMP region where expressions in this |
| /// clause must be captured. |
| /// \param StartLoc Starting location of the clause. |
| /// \param EndLoc Ending location of the clause. |
| OMPNumTasksClause(Expr *Size, Stmt *HelperSize, |
| OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, |
| SourceLocation LParenLoc, SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_num_tasks, StartLoc, EndLoc), |
| OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumTasks(Size) { |
| setPreInitStmt(HelperSize, CaptureRegion); |
| } |
| |
| /// Build an empty clause. |
| explicit OMPNumTasksClause() |
| : OMPClause(llvm::omp::OMPC_num_tasks, SourceLocation(), |
| SourceLocation()), |
| OMPClauseWithPreInit(this) {} |
| |
| /// Sets the location of '('. |
| void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } |
| |
| /// Returns the location of '('. |
| SourceLocation getLParenLoc() const { return LParenLoc; } |
| |
| /// Return safe iteration space distance. |
| Expr *getNumTasks() const { return cast_or_null<Expr>(NumTasks); } |
| |
| child_range children() { return child_range(&NumTasks, &NumTasks + 1); } |
| |
| const_child_range children() const { |
| return const_child_range(&NumTasks, &NumTasks + 1); |
| } |
| |
| child_range used_children(); |
| const_child_range used_children() const { |
| auto Children = const_cast<OMPNumTasksClause *>(this)->used_children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| static bool classof(const OMPClause *T) { |
| return T->getClauseKind() == llvm::omp::OMPC_num_tasks; |
| } |
| }; |
| |
| /// This represents 'hint' clause in the '#pragma omp ...' directive. |
| /// |
| /// \code |
| /// #pragma omp critical (name) hint(6) |
| /// \endcode |
| /// In this example directive '#pragma omp critical' has name 'name' and clause |
| /// 'hint' with argument '6'. |
| class OMPHintClause : public OMPClause { |
| friend class OMPClauseReader; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// Hint expression of the 'hint' clause. |
| Stmt *Hint = nullptr; |
| |
| /// Set hint expression. |
| void setHint(Expr *H) { Hint = H; } |
| |
| public: |
| /// Build 'hint' clause with expression \a Hint. |
| /// |
| /// \param Hint Hint expression. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| OMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_hint, StartLoc, EndLoc), LParenLoc(LParenLoc), |
| Hint(Hint) {} |
| |
| /// Build an empty clause. |
| OMPHintClause() |
| : OMPClause(llvm::omp::OMPC_hint, SourceLocation(), SourceLocation()) {} |
| |
| /// Sets the location of '('. |
| void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } |
| |
| /// Returns the location of '('. |
| SourceLocation getLParenLoc() const { return LParenLoc; } |
| |
| /// Returns number of threads. |
| Expr *getHint() const { return cast_or_null<Expr>(Hint); } |
| |
| child_range children() { return child_range(&Hint, &Hint + 1); } |
| |
| const_child_range children() const { |
| return const_child_range(&Hint, &Hint + 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_hint; |
| } |
| }; |
| |
| /// This represents 'dist_schedule' clause in the '#pragma omp ...' |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp distribute dist_schedule(static, 3) |
| /// \endcode |
| /// In this example directive '#pragma omp distribute' has 'dist_schedule' |
| /// clause with arguments 'static' and '3'. |
| class OMPDistScheduleClause : public OMPClause, public OMPClauseWithPreInit { |
| friend class OMPClauseReader; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// A kind of the 'schedule' clause. |
| OpenMPDistScheduleClauseKind Kind = OMPC_DIST_SCHEDULE_unknown; |
| |
| /// Start location of the schedule kind in source code. |
| SourceLocation KindLoc; |
| |
| /// Location of ',' (if any). |
| SourceLocation CommaLoc; |
| |
| /// Chunk size. |
| Expr *ChunkSize = nullptr; |
| |
| /// Set schedule kind. |
| /// |
| /// \param K Schedule kind. |
| void setDistScheduleKind(OpenMPDistScheduleClauseKind K) { Kind = K; } |
| |
| /// Sets the location of '('. |
| /// |
| /// \param Loc Location of '('. |
| void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } |
| |
| /// Set schedule kind start location. |
| /// |
| /// \param KLoc Schedule kind location. |
| void setDistScheduleKindLoc(SourceLocation KLoc) { KindLoc = KLoc; } |
| |
| /// Set location of ','. |
| /// |
| /// \param Loc Location of ','. |
| void setCommaLoc(SourceLocation Loc) { CommaLoc = Loc; } |
| |
| /// Set chunk size. |
| /// |
| /// \param E Chunk size. |
| void setChunkSize(Expr *E) { ChunkSize = E; } |
| |
| public: |
| /// Build 'dist_schedule' clause with schedule kind \a Kind and chunk |
| /// size expression \a ChunkSize. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param KLoc Starting location of the argument. |
| /// \param CommaLoc Location of ','. |
| /// \param EndLoc Ending location of the clause. |
| /// \param Kind DistSchedule kind. |
| /// \param ChunkSize Chunk size. |
| /// \param HelperChunkSize Helper chunk size for combined directives. |
| OMPDistScheduleClause(SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation KLoc, SourceLocation CommaLoc, |
| SourceLocation EndLoc, |
| OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, |
| Stmt *HelperChunkSize) |
| : OMPClause(llvm::omp::OMPC_dist_schedule, StartLoc, EndLoc), |
| OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Kind(Kind), |
| KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) { |
| setPreInitStmt(HelperChunkSize); |
| } |
| |
| /// Build an empty clause. |
| explicit OMPDistScheduleClause() |
| : OMPClause(llvm::omp::OMPC_dist_schedule, SourceLocation(), |
| SourceLocation()), |
| OMPClauseWithPreInit(this) {} |
| |
| /// Get kind of the clause. |
| OpenMPDistScheduleClauseKind getDistScheduleKind() const { return Kind; } |
| |
| /// Get location of '('. |
| SourceLocation getLParenLoc() { return LParenLoc; } |
| |
| /// Get kind location. |
| SourceLocation getDistScheduleKindLoc() { return KindLoc; } |
| |
| /// Get location of ','. |
| SourceLocation getCommaLoc() { return CommaLoc; } |
| |
| /// Get chunk size. |
| Expr *getChunkSize() { return ChunkSize; } |
| |
| /// Get chunk size. |
| const Expr *getChunkSize() const { return ChunkSize; } |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(&ChunkSize), |
| reinterpret_cast<Stmt **>(&ChunkSize) + 1); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPDistScheduleClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| 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_dist_schedule; |
| } |
| }; |
| |
| /// This represents 'defaultmap' clause in the '#pragma omp ...' directive. |
| /// |
| /// \code |
| /// #pragma omp target defaultmap(tofrom: scalar) |
| /// \endcode |
| /// In this example directive '#pragma omp target' has 'defaultmap' clause of kind |
| /// 'scalar' with modifier 'tofrom'. |
| class OMPDefaultmapClause : public OMPClause { |
| friend class OMPClauseReader; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// Modifiers for 'defaultmap' clause. |
| OpenMPDefaultmapClauseModifier Modifier = OMPC_DEFAULTMAP_MODIFIER_unknown; |
| |
| /// Locations of modifiers. |
| SourceLocation ModifierLoc; |
| |
| /// A kind of the 'defaultmap' clause. |
| OpenMPDefaultmapClauseKind Kind = OMPC_DEFAULTMAP_unknown; |
| |
| /// Start location of the defaultmap kind in source code. |
| SourceLocation KindLoc; |
| |
| /// Set defaultmap kind. |
| /// |
| /// \param K Defaultmap kind. |
| void setDefaultmapKind(OpenMPDefaultmapClauseKind K) { Kind = K; } |
| |
| /// Set the defaultmap modifier. |
| /// |
| /// \param M Defaultmap modifier. |
| void setDefaultmapModifier(OpenMPDefaultmapClauseModifier M) { |
| Modifier = M; |
| } |
| |
| /// Set location of the defaultmap modifier. |
| void setDefaultmapModifierLoc(SourceLocation Loc) { |
| ModifierLoc = Loc; |
| } |
| |
| /// Sets the location of '('. |
| /// |
| /// \param Loc Location of '('. |
| void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } |
| |
| /// Set defaultmap kind start location. |
| /// |
| /// \param KLoc Defaultmap kind location. |
| void setDefaultmapKindLoc(SourceLocation KLoc) { KindLoc = KLoc; } |
| |
| public: |
| /// Build 'defaultmap' clause with defaultmap kind \a Kind |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param KLoc Starting location of the argument. |
| /// \param EndLoc Ending location of the clause. |
| /// \param Kind Defaultmap kind. |
| /// \param M The modifier applied to 'defaultmap' clause. |
| /// \param MLoc Location of the modifier |
| OMPDefaultmapClause(SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation MLoc, SourceLocation KLoc, |
| SourceLocation EndLoc, OpenMPDefaultmapClauseKind Kind, |
| OpenMPDefaultmapClauseModifier M) |
| : OMPClause(llvm::omp::OMPC_defaultmap, StartLoc, EndLoc), |
| LParenLoc(LParenLoc), Modifier(M), ModifierLoc(MLoc), Kind(Kind), |
| KindLoc(KLoc) {} |
| |
| /// Build an empty clause. |
| explicit OMPDefaultmapClause() |
| : OMPClause(llvm::omp::OMPC_defaultmap, SourceLocation(), |
| SourceLocation()) {} |
| |
| /// Get kind of the clause. |
| OpenMPDefaultmapClauseKind getDefaultmapKind() const { return Kind; } |
| |
| /// Get the modifier of the clause. |
| OpenMPDefaultmapClauseModifier getDefaultmapModifier() const { |
| return Modifier; |
| } |
| |
| /// Get location of '('. |
| SourceLocation getLParenLoc() { return LParenLoc; } |
| |
| /// Get kind location. |
| SourceLocation getDefaultmapKindLoc() { return KindLoc; } |
| |
| /// Get the modifier location. |
| SourceLocation getDefaultmapModifierLoc() const { |
| return ModifierLoc; |
| } |
| |
| 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_defaultmap; |
| } |
| }; |
| |
| /// This represents clause 'to' in the '#pragma omp ...' |
| /// directives. |
| /// |
| /// \code |
| /// #pragma omp target update to(a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp target update' has clause 'to' |
| /// with the variables 'a' and 'b'. |
| class OMPToClause final : public OMPMappableExprListClause<OMPToClause>, |
| private llvm::TrailingObjects< |
| OMPToClause, Expr *, ValueDecl *, unsigned, |
| OMPClauseMappableExprCommon::MappableComponent> { |
| friend class OMPClauseReader; |
| friend OMPMappableExprListClause; |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Motion-modifiers for the 'to' clause. |
| OpenMPMotionModifierKind MotionModifiers[NumberOfOMPMotionModifiers] = { |
| OMPC_MOTION_MODIFIER_unknown, OMPC_MOTION_MODIFIER_unknown}; |
| |
| /// Location of motion-modifiers for the 'to' clause. |
| SourceLocation MotionModifiersLoc[NumberOfOMPMotionModifiers]; |
| |
| /// Colon location. |
| SourceLocation ColonLoc; |
| |
| /// Build clause with number of variables \a NumVars. |
| /// |
| /// \param TheMotionModifiers Motion-modifiers. |
| /// \param TheMotionModifiersLoc Locations of motion-modifiers. |
| /// \param MapperQualifierLoc C++ nested name specifier for the associated |
| /// user-defined mapper. |
| /// \param MapperIdInfo The identifier of associated user-defined mapper. |
| /// \param Locs Locations needed to build a mappable clause. It includes 1) |
| /// StartLoc: starting location of the clause (the clause keyword); 2) |
| /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. |
| /// \param Sizes All required sizes to build a mappable clause. It includes 1) |
| /// NumVars: number of expressions listed in this clause; 2) |
| /// NumUniqueDeclarations: number of unique base declarations in this clause; |
| /// 3) NumComponentLists: number of component lists in this clause; and 4) |
| /// NumComponents: total number of expression components in the clause. |
| explicit OMPToClause(ArrayRef<OpenMPMotionModifierKind> TheMotionModifiers, |
| ArrayRef<SourceLocation> TheMotionModifiersLoc, |
| NestedNameSpecifierLoc MapperQualifierLoc, |
| DeclarationNameInfo MapperIdInfo, |
| const OMPVarListLocTy &Locs, |
| const OMPMappableExprListSizeTy &Sizes) |
| : OMPMappableExprListClause(llvm::omp::OMPC_to, Locs, Sizes, |
| /*SupportsMapper=*/true, &MapperQualifierLoc, |
| &MapperIdInfo) { |
| assert(llvm::array_lengthof(MotionModifiers) == TheMotionModifiers.size() && |
| "Unexpected number of motion modifiers."); |
| llvm::copy(TheMotionModifiers, std::begin(MotionModifiers)); |
| |
| assert(llvm::array_lengthof(MotionModifiersLoc) == |
| TheMotionModifiersLoc.size() && |
| "Unexpected number of motion modifier locations."); |
| llvm::copy(TheMotionModifiersLoc, std::begin(MotionModifiersLoc)); |
| } |
| |
| /// Build an empty clause. |
| /// |
| /// \param Sizes All required sizes to build a mappable clause. It includes 1) |
| /// NumVars: number of expressions listed in this clause; 2) |
| /// NumUniqueDeclarations: number of unique base declarations in this clause; |
| /// 3) NumComponentLists: number of component lists in this clause; and 4) |
| /// NumComponents: total number of expression components in the clause. |
| explicit OMPToClause(const OMPMappableExprListSizeTy &Sizes) |
| : OMPMappableExprListClause(llvm::omp::OMPC_to, OMPVarListLocTy(), Sizes, |
| /*SupportsMapper=*/true) {} |
| |
| /// Set motion-modifier for the clause. |
| /// |
| /// \param I index for motion-modifier. |
| /// \param T motion-modifier for the clause. |
| void setMotionModifier(unsigned I, OpenMPMotionModifierKind T) { |
| assert(I < NumberOfOMPMotionModifiers && |
| "Unexpected index to store motion modifier, exceeds array size."); |
| MotionModifiers[I] = T; |
| } |
| |
| /// Set location for the motion-modifier. |
| /// |
| /// \param I index for motion-modifier location. |
| /// \param TLoc motion-modifier location. |
| void setMotionModifierLoc(unsigned I, SourceLocation TLoc) { |
| assert(I < NumberOfOMPMotionModifiers && |
| "Index to store motion modifier location exceeds array size."); |
| MotionModifiersLoc[I] = TLoc; |
| } |
| |
| /// Set colon location. |
| void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } |
| |
| /// Define the sizes of each trailing object array except the last one. This |
| /// is required for TrailingObjects to work properly. |
| size_t numTrailingObjects(OverloadToken<Expr *>) const { |
| // There are varlist_size() of expressions, and varlist_size() of |
| // user-defined mappers. |
| return 2 * varlist_size(); |
| } |
| size_t numTrailingObjects(OverloadToken<ValueDecl *>) const { |
| return getUniqueDeclarationsNum(); |
| } |
| size_t numTrailingObjects(OverloadToken<unsigned>) const { |
| return getUniqueDeclarationsNum() + getTotalComponentListNum(); |
| } |
| |
| public: |
| /// Creates clause with a list of variables \a Vars. |
| /// |
| /// \param C AST context. |
| /// \param Locs Locations needed to build a mappable clause. It includes 1) |
| /// StartLoc: starting location of the clause (the clause keyword); 2) |
| /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. |
| /// \param Vars The original expression used in the clause. |
| /// \param Declarations Declarations used in the clause. |
| /// \param ComponentLists Component lists used in the clause. |
| /// \param MotionModifiers Motion-modifiers. |
| /// \param MotionModifiersLoc Location of motion-modifiers. |
| /// \param UDMapperRefs References to user-defined mappers associated with |
| /// expressions used in the clause. |
| /// \param UDMQualifierLoc C++ nested name specifier for the associated |
| /// user-defined mapper. |
| /// \param MapperId The identifier of associated user-defined mapper. |
| static OMPToClause *Create(const ASTContext &C, const OMPVarListLocTy &Locs, |
| ArrayRef<Expr *> Vars, |
| ArrayRef<ValueDecl *> Declarations, |
| MappableExprComponentListsRef ComponentLists, |
| ArrayRef<Expr *> UDMapperRefs, |
| ArrayRef<OpenMPMotionModifierKind> MotionModifiers, |
| ArrayRef<SourceLocation> MotionModifiersLoc, |
| NestedNameSpecifierLoc UDMQualifierLoc, |
| DeclarationNameInfo MapperId); |
| |
| /// Creates an empty clause with the place for \a NumVars variables. |
| /// |
| /// \param C AST context. |
| /// \param Sizes All required sizes to build a mappable clause. It includes 1) |
| /// NumVars: number of expressions listed in this clause; 2) |
| /// NumUniqueDeclarations: number of unique base declarations in this clause; |
| /// 3) NumComponentLists: number of component lists in this clause; and 4) |
| /// NumComponents: total number of expression components in the clause. |
| static OMPToClause *CreateEmpty(const ASTContext &C, |
| const OMPMappableExprListSizeTy &Sizes); |
| |
| /// Fetches the motion-modifier at 'Cnt' index of array of modifiers. |
| /// |
| /// \param Cnt index for motion-modifier. |
| OpenMPMotionModifierKind getMotionModifier(unsigned Cnt) const LLVM_READONLY { |
| assert(Cnt < NumberOfOMPMotionModifiers && |
| "Requested modifier exceeds the total number of modifiers."); |
| return MotionModifiers[Cnt]; |
| } |
| |
| /// Fetches the motion-modifier location at 'Cnt' index of array of modifiers' |
| /// locations. |
| /// |
| /// \param Cnt index for motion-modifier location. |
| SourceLocation getMotionModifierLoc(unsigned Cnt) const LLVM_READONLY { |
| assert(Cnt < NumberOfOMPMotionModifiers && |
| "Requested modifier location exceeds total number of modifiers."); |
| return MotionModifiersLoc[Cnt]; |
| } |
| |
| /// Fetches ArrayRef of motion-modifiers. |
| ArrayRef<OpenMPMotionModifierKind> getMotionModifiers() const LLVM_READONLY { |
| return llvm::makeArrayRef(MotionModifiers); |
| } |
| |
| /// Fetches ArrayRef of location of motion-modifiers. |
| ArrayRef<SourceLocation> getMotionModifiersLoc() const LLVM_READONLY { |
| return llvm::makeArrayRef(MotionModifiersLoc); |
| } |
| |
| /// Get colon location. |
| SourceLocation getColonLoc() const { return ColonLoc; } |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPToClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| 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_to; |
| } |
| }; |
| |
| /// This represents clause 'from' in the '#pragma omp ...' |
| /// directives. |
| /// |
| /// \code |
| /// #pragma omp target update from(a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp target update' has clause 'from' |
| /// with the variables 'a' and 'b'. |
| class OMPFromClause final |
| : public OMPMappableExprListClause<OMPFromClause>, |
| private llvm::TrailingObjects< |
| OMPFromClause, Expr *, ValueDecl *, unsigned, |
| OMPClauseMappableExprCommon::MappableComponent> { |
| friend class OMPClauseReader; |
| friend OMPMappableExprListClause; |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Motion-modifiers for the 'from' clause. |
| OpenMPMotionModifierKind MotionModifiers[NumberOfOMPMotionModifiers] = { |
| OMPC_MOTION_MODIFIER_unknown, OMPC_MOTION_MODIFIER_unknown}; |
| |
| /// Location of motion-modifiers for the 'from' clause. |
| SourceLocation MotionModifiersLoc[NumberOfOMPMotionModifiers]; |
| |
| /// Colon location. |
| SourceLocation ColonLoc; |
| |
| /// Build clause with number of variables \a NumVars. |
| /// |
| /// \param TheMotionModifiers Motion-modifiers. |
| /// \param TheMotionModifiersLoc Locations of motion-modifiers. |
| /// \param MapperQualifierLoc C++ nested name specifier for the associated |
| /// user-defined mapper. |
| /// \param MapperIdInfo The identifier of associated user-defined mapper. |
| /// \param Locs Locations needed to build a mappable clause. It includes 1) |
| /// StartLoc: starting location of the clause (the clause keyword); 2) |
| /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. |
| /// \param Sizes All required sizes to build a mappable clause. It includes 1) |
| /// NumVars: number of expressions listed in this clause; 2) |
| /// NumUniqueDeclarations: number of unique base declarations in this clause; |
| /// 3) NumComponentLists: number of component lists in this clause; and 4) |
| /// NumComponents: total number of expression components in the clause. |
| explicit OMPFromClause(ArrayRef<OpenMPMotionModifierKind> TheMotionModifiers, |
| ArrayRef<SourceLocation> TheMotionModifiersLoc, |
| NestedNameSpecifierLoc MapperQualifierLoc, |
| DeclarationNameInfo MapperIdInfo, |
| const OMPVarListLocTy &Locs, |
| const OMPMappableExprListSizeTy &Sizes) |
| : OMPMappableExprListClause(llvm::omp::OMPC_from, Locs, Sizes, |
| /*SupportsMapper=*/true, &MapperQualifierLoc, |
| &MapperIdInfo) { |
| assert(llvm::array_lengthof(MotionModifiers) == TheMotionModifiers.size() && |
| "Unexpected number of motion modifiers."); |
| llvm::copy(TheMotionModifiers, std::begin(MotionModifiers)); |
| |
| assert(llvm::array_lengthof(MotionModifiersLoc) == |
| TheMotionModifiersLoc.size() && |
| "Unexpected number of motion modifier locations."); |
| llvm::copy(TheMotionModifiersLoc, std::begin(MotionModifiersLoc)); |
| } |
| |
| /// Build an empty clause. |
| /// |
| /// \param Sizes All required sizes to build a mappable clause. It includes 1) |
| /// NumVars: number of expressions listed in this clause; 2) |
| /// NumUniqueDeclarations: number of unique base declarations in this clause; |
| /// 3) NumComponentLists: number of component lists in this clause; and 4) |
| /// NumComponents: total number of expression components in the clause. |
| explicit OMPFromClause(const OMPMappableExprListSizeTy &Sizes) |
| : OMPMappableExprListClause(llvm::omp::OMPC_from, OMPVarListLocTy(), |
| Sizes, /*SupportsMapper=*/true) {} |
| |
| /// Set motion-modifier for the clause. |
| /// |
| /// \param I index for motion-modifier. |
| /// \param T motion-modifier for the clause. |
| void setMotionModifier(unsigned I, OpenMPMotionModifierKind T) { |
| assert(I < NumberOfOMPMotionModifiers && |
| "Unexpected index to store motion modifier, exceeds array size."); |
| MotionModifiers[I] = T; |
| } |
| |
| /// Set location for the motion-modifier. |
| /// |
| /// \param I index for motion-modifier location. |
| /// \param TLoc motion-modifier location. |
| void setMotionModifierLoc(unsigned I, SourceLocation TLoc) { |
| assert(I < NumberOfOMPMotionModifiers && |
| "Index to store motion modifier location exceeds array size."); |
| MotionModifiersLoc[I] = TLoc; |
| } |
| |
| /// Set colon location. |
| void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } |
| |
| /// Define the sizes of each trailing object array except the last one. This |
| /// is required for TrailingObjects to work properly. |
| size_t numTrailingObjects(OverloadToken<Expr *>) const { |
| // There are varlist_size() of expressions, and varlist_size() of |
| // user-defined mappers. |
| return 2 * varlist_size(); |
| } |
| size_t numTrailingObjects(OverloadToken<ValueDecl *>) const { |
| return getUniqueDeclarationsNum(); |
| } |
| size_t numTrailingObjects(OverloadToken<unsigned>) const { |
| return getUniqueDeclarationsNum() + getTotalComponentListNum(); |
| } |
| |
| public: |
| /// Creates clause with a list of variables \a Vars. |
| /// |
| /// \param C AST context. |
| /// \param Locs Locations needed to build a mappable clause. It includes 1) |
| /// StartLoc: starting location of the clause (the clause keyword); 2) |
| /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. |
| /// \param Vars The original expression used in the clause. |
| /// \param Declarations Declarations used in the clause. |
| /// \param ComponentLists Component lists used in the clause. |
| /// \param MotionModifiers Motion-modifiers. |
| /// \param MotionModifiersLoc Location of motion-modifiers. |
| /// \param UDMapperRefs References to user-defined mappers associated with |
| /// expressions used in the clause. |
| /// \param UDMQualifierLoc C++ nested name specifier for the associated |
| /// user-defined mapper. |
| /// \param MapperId The identifier of associated user-defined mapper. |
| static OMPFromClause * |
| Create(const ASTContext &C, const OMPVarListLocTy &Locs, |
| ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations, |
| MappableExprComponentListsRef ComponentLists, |
| ArrayRef<Expr *> UDMapperRefs, |
| ArrayRef<OpenMPMotionModifierKind> MotionModifiers, |
| ArrayRef<SourceLocation> MotionModifiersLoc, |
| NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId); |
| |
| /// Creates an empty clause with the place for \a NumVars variables. |
| /// |
| /// \param C AST context. |
| /// \param Sizes All required sizes to build a mappable clause. It includes 1) |
| /// NumVars: number of expressions listed in this clause; 2) |
| /// NumUniqueDeclarations: number of unique base declarations in this clause; |
| /// 3) NumComponentLists: number of component lists in this clause; and 4) |
| /// NumComponents: total number of expression components in the clause. |
| static OMPFromClause *CreateEmpty(const ASTContext &C, |
| const OMPMappableExprListSizeTy &Sizes); |
| |
| /// Fetches the motion-modifier at 'Cnt' index of array of modifiers. |
| /// |
| /// \param Cnt index for motion-modifier. |
| OpenMPMotionModifierKind getMotionModifier(unsigned Cnt) const LLVM_READONLY { |
| assert(Cnt < NumberOfOMPMotionModifiers && |
| "Requested modifier exceeds the total number of modifiers."); |
| return MotionModifiers[Cnt]; |
| } |
| |
| /// Fetches the motion-modifier location at 'Cnt' index of array of modifiers' |
| /// locations. |
| /// |
| /// \param Cnt index for motion-modifier location. |
| SourceLocation getMotionModifierLoc(unsigned Cnt) const LLVM_READONLY { |
| assert(Cnt < NumberOfOMPMotionModifiers && |
| "Requested modifier location exceeds total number of modifiers."); |
| return MotionModifiersLoc[Cnt]; |
| } |
| |
| /// Fetches ArrayRef of motion-modifiers. |
| ArrayRef<OpenMPMotionModifierKind> getMotionModifiers() const LLVM_READONLY { |
| return llvm::makeArrayRef(MotionModifiers); |
| } |
| |
| /// Fetches ArrayRef of location of motion-modifiers. |
| ArrayRef<SourceLocation> getMotionModifiersLoc() const LLVM_READONLY { |
| return llvm::makeArrayRef(MotionModifiersLoc); |
| } |
| |
| /// Get colon location. |
| SourceLocation getColonLoc() const { return ColonLoc; } |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPFromClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| 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_from; |
| } |
| }; |
| |
| /// This represents clause 'use_device_ptr' in the '#pragma omp ...' |
| /// directives. |
| /// |
| /// \code |
| /// #pragma omp target data use_device_ptr(a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp target data' has clause |
| /// 'use_device_ptr' with the variables 'a' and 'b'. |
| class OMPUseDevicePtrClause final |
| : public OMPMappableExprListClause<OMPUseDevicePtrClause>, |
| private llvm::TrailingObjects< |
| OMPUseDevicePtrClause, Expr *, ValueDecl *, unsigned, |
| OMPClauseMappableExprCommon::MappableComponent> { |
| friend class OMPClauseReader; |
| friend OMPMappableExprListClause; |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Build clause with number of variables \a NumVars. |
| /// |
| /// \param Locs Locations needed to build a mappable clause. It includes 1) |
| /// StartLoc: starting location of the clause (the clause keyword); 2) |
| /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. |
| /// \param Sizes All required sizes to build a mappable clause. It includes 1) |
| /// NumVars: number of expressions listed in this clause; 2) |
| /// NumUniqueDeclarations: number of unique base declarations in this clause; |
| /// 3) NumComponentLists: number of component lists in this clause; and 4) |
| /// NumComponents: total number of expression components in the clause. |
| explicit OMPUseDevicePtrClause(const OMPVarListLocTy &Locs, |
| const OMPMappableExprListSizeTy &Sizes) |
| : OMPMappableExprListClause(llvm::omp::OMPC_use_device_ptr, Locs, Sizes) { |
| } |
| |
| /// Build an empty clause. |
| /// |
| /// \param Sizes All required sizes to build a mappable clause. It includes 1) |
| /// NumVars: number of expressions listed in this clause; 2) |
| /// NumUniqueDeclarations: number of unique base declarations in this clause; |
| /// 3) NumComponentLists: number of component lists in this clause; and 4) |
| /// NumComponents: total number of expression components in the clause. |
| explicit OMPUseDevicePtrClause(const OMPMappableExprListSizeTy &Sizes) |
| : OMPMappableExprListClause(llvm::omp::OMPC_use_device_ptr, |
| OMPVarListLocTy(), Sizes) {} |
| |
| /// Define the sizes of each trailing object array except the last one. This |
| /// is required for TrailingObjects to work properly. |
| size_t numTrailingObjects(OverloadToken<Expr *>) const { |
| return 3 * varlist_size(); |
| } |
| size_t numTrailingObjects(OverloadToken<ValueDecl *>) const { |
| return getUniqueDeclarationsNum(); |
| } |
| size_t numTrailingObjects(OverloadToken<unsigned>) const { |
| return getUniqueDeclarationsNum() + getTotalComponentListNum(); |
| } |
| |
| /// Sets the list of references to private copies with initializers for new |
| /// private variables. |
| /// \param VL List of references. |
| void setPrivateCopies(ArrayRef<Expr *> VL); |
| |
| /// Gets the list of references to private copies with initializers for new |
| /// private variables. |
| MutableArrayRef<Expr *> getPrivateCopies() { |
| return MutableArrayRef<Expr *>(varlist_end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getPrivateCopies() const { |
| return llvm::makeArrayRef(varlist_end(), varlist_size()); |
| } |
| |
| /// Sets the list of references to initializer variables for new private |
| /// variables. |
| /// \param VL List of references. |
| void setInits(ArrayRef<Expr *> VL); |
| |
| /// Gets the list of references to initializer variables for new private |
| /// variables. |
| MutableArrayRef<Expr *> getInits() { |
| return MutableArrayRef<Expr *>(getPrivateCopies().end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getInits() const { |
| return llvm::makeArrayRef(getPrivateCopies().end(), varlist_size()); |
| } |
| |
| public: |
| /// Creates clause with a list of variables \a Vars. |
| /// |
| /// \param C AST context. |
| /// \param Locs Locations needed to build a mappable clause. It includes 1) |
| /// StartLoc: starting location of the clause (the clause keyword); 2) |
| /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. |
| /// \param Vars The original expression used in the clause. |
| /// \param PrivateVars Expressions referring to private copies. |
| /// \param Inits Expressions referring to private copy initializers. |
| /// \param Declarations Declarations used in the clause. |
| /// \param ComponentLists Component lists used in the clause. |
| static OMPUseDevicePtrClause * |
| Create(const ASTContext &C, const OMPVarListLocTy &Locs, |
| ArrayRef<Expr *> Vars, ArrayRef<Expr *> PrivateVars, |
| ArrayRef<Expr *> Inits, ArrayRef<ValueDecl *> Declarations, |
| MappableExprComponentListsRef ComponentLists); |
| |
| /// Creates an empty clause with the place for \a NumVars variables. |
| /// |
| /// \param C AST context. |
| /// \param Sizes All required sizes to build a mappable clause. It includes 1) |
| /// NumVars: number of expressions listed in this clause; 2) |
| /// NumUniqueDeclarations: number of unique base declarations in this clause; |
| /// 3) NumComponentLists: number of component lists in this clause; and 4) |
| /// NumComponents: total number of expression components in the clause. |
| static OMPUseDevicePtrClause * |
| CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes); |
| |
| using private_copies_iterator = MutableArrayRef<Expr *>::iterator; |
| using private_copies_const_iterator = ArrayRef<const Expr *>::iterator; |
| using private_copies_range = llvm::iterator_range<private_copies_iterator>; |
| using private_copies_const_range = |
| llvm::iterator_range<private_copies_const_iterator>; |
| |
| private_copies_range private_copies() { |
| return private_copies_range(getPrivateCopies().begin(), |
| getPrivateCopies().end()); |
| } |
| |
| private_copies_const_range private_copies() const { |
| return private_copies_const_range(getPrivateCopies().begin(), |
| getPrivateCopies().end()); |
| } |
| |
| using inits_iterator = MutableArrayRef<Expr *>::iterator; |
| using inits_const_iterator = ArrayRef<const Expr *>::iterator; |
| using inits_range = llvm::iterator_range<inits_iterator>; |
| using inits_const_range = llvm::iterator_range<inits_const_iterator>; |
| |
| inits_range inits() { |
| return inits_range(getInits().begin(), getInits().end()); |
| } |
| |
| inits_const_range inits() const { |
| return inits_const_range(getInits().begin(), getInits().end()); |
| } |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPUseDevicePtrClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| 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_use_device_ptr; |
| } |
| }; |
| |
| /// This represents clause 'use_device_addr' in the '#pragma omp ...' |
| /// directives. |
| /// |
| /// \code |
| /// #pragma omp target data use_device_addr(a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp target data' has clause |
| /// 'use_device_addr' with the variables 'a' and 'b'. |
| class OMPUseDeviceAddrClause final |
| : public OMPMappableExprListClause<OMPUseDeviceAddrClause>, |
| private llvm::TrailingObjects< |
| OMPUseDeviceAddrClause, Expr *, ValueDecl *, unsigned, |
| OMPClauseMappableExprCommon::MappableComponent> { |
| friend class OMPClauseReader; |
| friend OMPMappableExprListClause; |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Build clause with number of variables \a NumVars. |
| /// |
| /// \param Locs Locations needed to build a mappable clause. It includes 1) |
| /// StartLoc: starting location of the clause (the clause keyword); 2) |
| /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. |
| /// \param Sizes All required sizes to build a mappable clause. It includes 1) |
| /// NumVars: number of expressions listed in this clause; 2) |
| /// NumUniqueDeclarations: number of unique base declarations in this clause; |
| /// 3) NumComponentLists: number of component lists in this clause; and 4) |
| /// NumComponents: total number of expression components in the clause. |
| explicit OMPUseDeviceAddrClause(const OMPVarListLocTy &Locs, |
| const OMPMappableExprListSizeTy &Sizes) |
| : OMPMappableExprListClause(llvm::omp::OMPC_use_device_addr, Locs, |
| Sizes) {} |
| |
| /// Build an empty clause. |
| /// |
| /// \param Sizes All required sizes to build a mappable clause. It includes 1) |
| /// NumVars: number of expressions listed in this clause; 2) |
| /// NumUniqueDeclarations: number of unique base declarations in this clause; |
| /// 3) NumComponentLists: number of component lists in this clause; and 4) |
| /// NumComponents: total number of expression components in the clause. |
| explicit OMPUseDeviceAddrClause(const OMPMappableExprListSizeTy &Sizes) |
| : OMPMappableExprListClause(llvm::omp::OMPC_use_device_addr, |
| OMPVarListLocTy(), Sizes) {} |
| |
| /// Define the sizes of each trailing object array except the last one. This |
| /// is required for TrailingObjects to work properly. |
| size_t numTrailingObjects(OverloadToken<Expr *>) const { |
| return varlist_size(); |
| } |
| size_t numTrailingObjects(OverloadToken<ValueDecl *>) const { |
| return getUniqueDeclarationsNum(); |
| } |
| size_t numTrailingObjects(OverloadToken<unsigned>) const { |
| return getUniqueDeclarationsNum() + getTotalComponentListNum(); |
| } |
| |
| public: |
| /// Creates clause with a list of variables \a Vars. |
| /// |
| /// \param C AST context. |
| /// \param Locs Locations needed to build a mappable clause. It includes 1) |
| /// StartLoc: starting location of the clause (the clause keyword); 2) |
| /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. |
| /// \param Vars The original expression used in the clause. |
| /// \param Declarations Declarations used in the clause. |
| /// \param ComponentLists Component lists used in the clause. |
| static OMPUseDeviceAddrClause * |
| Create(const ASTContext &C, const OMPVarListLocTy &Locs, |
| ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations, |
| MappableExprComponentListsRef ComponentLists); |
| |
| /// Creates an empty clause with the place for \a NumVars variables. |
| /// |
| /// \param C AST context. |
| /// \param Sizes All required sizes to build a mappable clause. It includes 1) |
| /// NumVars: number of expressions listed in this clause; 2) |
| /// NumUniqueDeclarations: number of unique base declarations in this clause; |
| /// 3) NumComponentLists: number of component lists in this clause; and 4) |
| /// NumComponents: total number of expression components in the clause. |
| static OMPUseDeviceAddrClause * |
| CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes); |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPUseDeviceAddrClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| 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_use_device_addr; |
| } |
| }; |
| |
| /// This represents clause 'is_device_ptr' in the '#pragma omp ...' |
| /// directives. |
| /// |
| /// \code |
| /// #pragma omp target is_device_ptr(a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp target' has clause |
| /// 'is_device_ptr' with the variables 'a' and 'b'. |
| class OMPIsDevicePtrClause final |
| : public OMPMappableExprListClause<OMPIsDevicePtrClause>, |
| private llvm::TrailingObjects< |
| OMPIsDevicePtrClause, Expr *, ValueDecl *, unsigned, |
| OMPClauseMappableExprCommon::MappableComponent> { |
| friend class OMPClauseReader; |
| friend OMPMappableExprListClause; |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Build clause with number of variables \a NumVars. |
| /// |
| /// \param Locs Locations needed to build a mappable clause. It includes 1) |
| /// StartLoc: starting location of the clause (the clause keyword); 2) |
| /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. |
| /// \param Sizes All required sizes to build a mappable clause. It includes 1) |
| /// NumVars: number of expressions listed in this clause; 2) |
| /// NumUniqueDeclarations: number of unique base declarations in this clause; |
| /// 3) NumComponentLists: number of component lists in this clause; and 4) |
| /// NumComponents: total number of expression components in the clause. |
| explicit OMPIsDevicePtrClause(const OMPVarListLocTy &Locs, |
| const OMPMappableExprListSizeTy &Sizes) |
| : OMPMappableExprListClause(llvm::omp::OMPC_is_device_ptr, Locs, Sizes) {} |
| |
| /// Build an empty clause. |
| /// |
| /// \param Sizes All required sizes to build a mappable clause. It includes 1) |
| /// NumVars: number of expressions listed in this clause; 2) |
| /// NumUniqueDeclarations: number of unique base declarations in this clause; |
| /// 3) NumComponentLists: number of component lists in this clause; and 4) |
| /// NumComponents: total number of expression components in the clause. |
| explicit OMPIsDevicePtrClause(const OMPMappableExprListSizeTy &Sizes) |
| : OMPMappableExprListClause(llvm::omp::OMPC_is_device_ptr, |
| OMPVarListLocTy(), Sizes) {} |
| |
| /// Define the sizes of each trailing object array except the last one. This |
| /// is required for TrailingObjects to work properly. |
| size_t numTrailingObjects(OverloadToken<Expr *>) const { |
| return varlist_size(); |
| } |
| size_t numTrailingObjects(OverloadToken<ValueDecl *>) const { |
| return getUniqueDeclarationsNum(); |
| } |
| size_t numTrailingObjects(OverloadToken<unsigned>) const { |
| return getUniqueDeclarationsNum() + getTotalComponentListNum(); |
| } |
| |
| public: |
| /// Creates clause with a list of variables \a Vars. |
| /// |
| /// \param C AST context. |
| /// \param Locs Locations needed to build a mappable clause. It includes 1) |
| /// StartLoc: starting location of the clause (the clause keyword); 2) |
| /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. |
| /// \param Vars The original expression used in the clause. |
| /// \param Declarations Declarations used in the clause. |
| /// \param ComponentLists Component lists used in the clause. |
| static OMPIsDevicePtrClause * |
| Create(const ASTContext &C, const OMPVarListLocTy &Locs, |
| ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations, |
| MappableExprComponentListsRef ComponentLists); |
| |
| /// Creates an empty clause with the place for \a NumVars variables. |
| /// |
| /// \param C AST context. |
| /// \param Sizes All required sizes to build a mappable clause. It includes 1) |
| /// NumVars: number of expressions listed in this clause; 2) |
| /// NumUniqueDeclarations: number of unique base declarations in this clause; |
| /// 3) NumComponentLists: number of component lists in this clause; and 4) |
| /// NumComponents: total number of expression components in the clause. |
| static OMPIsDevicePtrClause * |
| CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes); |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPIsDevicePtrClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| 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_is_device_ptr; |
| } |
| }; |
| |
| /// This represents clause 'nontemporal' in the '#pragma omp ...' directives. |
| /// |
| /// \code |
| /// #pragma omp simd nontemporal(a) |
| /// \endcode |
| /// In this example directive '#pragma omp simd' has clause 'nontemporal' for |
| /// the variable 'a'. |
| class OMPNontemporalClause final |
| : public OMPVarListClause<OMPNontemporalClause>, |
| private llvm::TrailingObjects<OMPNontemporalClause, Expr *> { |
| friend class OMPClauseReader; |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Build clause with number of variables \a N. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param N Number of the variables in the clause. |
| OMPNontemporalClause(SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc, unsigned N) |
| : OMPVarListClause<OMPNontemporalClause>(llvm::omp::OMPC_nontemporal, |
| StartLoc, LParenLoc, EndLoc, N) { |
| } |
| |
| /// Build an empty clause. |
| /// |
| /// \param N Number of variables. |
| explicit OMPNontemporalClause(unsigned N) |
| : OMPVarListClause<OMPNontemporalClause>( |
| llvm::omp::OMPC_nontemporal, SourceLocation(), SourceLocation(), |
| SourceLocation(), N) {} |
| |
| /// Get the list of privatied copies if the member expression was captured by |
| /// one of the privatization clauses. |
| MutableArrayRef<Expr *> getPrivateRefs() { |
| return MutableArrayRef<Expr *>(varlist_end(), varlist_size()); |
| } |
| ArrayRef<const Expr *> getPrivateRefs() const { |
| return llvm::makeArrayRef(varlist_end(), varlist_size()); |
| } |
| |
| public: |
| /// Creates clause with a list of variables \a VL. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param VL List of references to the variables. |
| static OMPNontemporalClause * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc, ArrayRef<Expr *> VL); |
| |
| /// Creates an empty clause with the place for \a N variables. |
| /// |
| /// \param C AST context. |
| /// \param N The number of variables. |
| static OMPNontemporalClause *CreateEmpty(const ASTContext &C, unsigned N); |
| |
| /// Sets the list of references to private copies created in private clauses. |
| /// \param VL List of references. |
| void setPrivateRefs(ArrayRef<Expr *> VL); |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPNontemporalClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| child_range private_refs() { |
| return child_range(reinterpret_cast<Stmt **>(getPrivateRefs().begin()), |
| reinterpret_cast<Stmt **>(getPrivateRefs().end())); |
| } |
| |
| const_child_range private_refs() const { |
| auto Children = const_cast<OMPNontemporalClause *>(this)->private_refs(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| 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_nontemporal; |
| } |
| }; |
| |
| /// This represents 'order' clause in the '#pragma omp ...' directive. |
| /// |
| /// \code |
| /// #pragma omp simd order(concurrent) |
| /// \endcode |
| /// In this example directive '#pragma omp parallel' has simple 'order' |
| /// clause with kind 'concurrent'. |
| class OMPOrderClause final : public OMPClause { |
| friend class OMPClauseReader; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// A kind of the 'default' clause. |
| OpenMPOrderClauseKind Kind = OMPC_ORDER_unknown; |
| |
| /// Start location of the kind in source code. |
| SourceLocation KindKwLoc; |
| |
| /// Set kind of the clause. |
| /// |
| /// \param K Argument of clause. |
| void setKind(OpenMPOrderClauseKind K) { Kind = K; } |
| |
| /// Set argument location. |
| /// |
| /// \param KLoc Argument location. |
| void setKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; } |
| |
| public: |
| /// Build 'order' clause with argument \p A ('concurrent'). |
| /// |
| /// \param A Argument of the clause ('concurrent'). |
| /// \param ALoc Starting location of the argument. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| OMPOrderClause(OpenMPOrderClauseKind A, SourceLocation ALoc, |
| SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_order, StartLoc, EndLoc), |
| LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} |
| |
| /// Build an empty clause. |
| OMPOrderClause() |
| : OMPClause(llvm::omp::OMPC_order, SourceLocation(), SourceLocation()) {} |
| |
| /// Sets the location of '('. |
| void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } |
| |
| /// Returns the location of '('. |
| SourceLocation getLParenLoc() const { return LParenLoc; } |
| |
| /// Returns kind of the clause. |
| OpenMPOrderClauseKind getKind() const { return Kind; } |
| |
| /// Returns location of clause kind. |
| SourceLocation getKindKwLoc() const { return KindKwLoc; } |
| |
| 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_order; |
| } |
| }; |
| |
| /// This represents the 'init' clause in '#pragma omp ...' directives. |
| /// |
| /// \code |
| /// #pragma omp interop init(target:obj) |
| /// \endcode |
| class OMPInitClause final |
| : public OMPVarListClause<OMPInitClause>, |
| private llvm::TrailingObjects<OMPInitClause, Expr *> { |
| friend class OMPClauseReader; |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Location of interop variable. |
| SourceLocation VarLoc; |
| |
| bool IsTarget = false; |
| bool IsTargetSync = false; |
| |
| void setInteropVar(Expr *E) { varlist_begin()[0] = E; } |
| |
| void setIsTarget(bool V) { IsTarget = V; } |
| |
| void setIsTargetSync(bool V) { IsTargetSync = V; } |
| |
| /// Sets the location of the interop variable. |
| void setVarLoc(SourceLocation Loc) { VarLoc = Loc; } |
| |
| /// Build 'init' clause. |
| /// |
| /// \param IsTarget Uses the 'target' interop-type. |
| /// \param IsTargetSync Uses the 'targetsync' interop-type. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param VarLoc Location of the interop variable. |
| /// \param EndLoc Ending location of the clause. |
| /// \param N Number of expressions. |
| OMPInitClause(bool IsTarget, bool IsTargetSync, SourceLocation StartLoc, |
| SourceLocation LParenLoc, SourceLocation VarLoc, |
| SourceLocation EndLoc, unsigned N) |
| : OMPVarListClause<OMPInitClause>(llvm::omp::OMPC_init, StartLoc, |
| LParenLoc, EndLoc, N), |
| VarLoc(VarLoc), IsTarget(IsTarget), IsTargetSync(IsTargetSync) {} |
| |
| /// Build an empty clause. |
| OMPInitClause(unsigned N) |
| : OMPVarListClause<OMPInitClause>(llvm::omp::OMPC_init, SourceLocation(), |
| SourceLocation(), SourceLocation(), N) { |
| } |
| |
| public: |
| /// Creates a fully specified clause. |
| /// |
| /// \param C AST context. |
| /// \param InteropVar The interop variable. |
| /// \param PrefExprs The list of preference expressions. |
| /// \param IsTarget Uses the 'target' interop-type. |
| /// \param IsTargetSync Uses the 'targetsync' interop-type. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param VarLoc Location of the interop variable. |
| /// \param EndLoc Ending location of the clause. |
| static OMPInitClause *Create(const ASTContext &C, Expr *InteropVar, |
| ArrayRef<Expr *> PrefExprs, bool IsTarget, |
| bool IsTargetSync, SourceLocation StartLoc, |
| SourceLocation LParenLoc, SourceLocation VarLoc, |
| SourceLocation EndLoc); |
| |
| /// Creates an empty clause with \a N expressions. |
| /// |
| /// \param C AST context. |
| /// \param N Number of expression items. |
| static OMPInitClause *CreateEmpty(const ASTContext &C, unsigned N); |
| |
| /// Returns the location of the interop variable. |
| SourceLocation getVarLoc() const { return VarLoc; } |
| |
| /// Returns the interop variable. |
| Expr *getInteropVar() { return varlist_begin()[0]; } |
| const Expr *getInteropVar() const { return varlist_begin()[0]; } |
| |
| /// Returns true is interop-type 'target' is used. |
| bool getIsTarget() const { return IsTarget; } |
| |
| /// Returns true is interop-type 'targetsync' is used. |
| bool getIsTargetSync() const { return IsTargetSync; } |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPInitClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| 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()); |
| } |
| |
| using prefs_iterator = MutableArrayRef<Expr *>::iterator; |
| using const_prefs_iterator = ArrayRef<const Expr *>::iterator; |
| using prefs_range = llvm::iterator_range<prefs_iterator>; |
| using const_prefs_range = llvm::iterator_range<const_prefs_iterator>; |
| |
| prefs_range prefs() { |
| return prefs_range(reinterpret_cast<Expr **>(std::next(varlist_begin())), |
| reinterpret_cast<Expr **>(varlist_end())); |
| } |
| |
| const_prefs_range prefs() const { |
| auto Prefs = const_cast<OMPInitClause *>(this)->prefs(); |
| return const_prefs_range(Prefs.begin(), Prefs.end()); |
| } |
| |
| static bool classof(const OMPClause *T) { |
| return T->getClauseKind() == llvm::omp::OMPC_init; |
| } |
| }; |
| |
| /// This represents the 'use' clause in '#pragma omp ...' directives. |
| /// |
| /// \code |
| /// #pragma omp interop use(obj) |
| /// \endcode |
| class OMPUseClause final : public OMPClause { |
| friend class OMPClauseReader; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// Location of interop variable. |
| SourceLocation VarLoc; |
| |
| /// The interop variable. |
| Stmt *InteropVar = nullptr; |
| |
| /// Set the interop variable. |
| void setInteropVar(Expr *E) { InteropVar = E; } |
| |
| /// Sets the location of '('. |
| void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } |
| |
| /// Sets the location of the interop variable. |
| void setVarLoc(SourceLocation Loc) { VarLoc = Loc; } |
| |
| public: |
| /// Build 'use' clause with and interop variable expression \a InteropVar. |
| /// |
| /// \param InteropVar The interop variable. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param VarLoc Location of the interop variable. |
| /// \param EndLoc Ending location of the clause. |
| OMPUseClause(Expr *InteropVar, SourceLocation StartLoc, |
| SourceLocation LParenLoc, SourceLocation VarLoc, |
| SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_use, StartLoc, EndLoc), LParenLoc(LParenLoc), |
| VarLoc(VarLoc), InteropVar(InteropVar) {} |
| |
| /// Build an empty clause. |
| OMPUseClause() |
| : OMPClause(llvm::omp::OMPC_use, SourceLocation(), SourceLocation()) {} |
| |
| /// Returns the location of '('. |
| SourceLocation getLParenLoc() const { return LParenLoc; } |
| |
| /// Returns the location of the interop variable. |
| SourceLocation getVarLoc() const { return VarLoc; } |
| |
| /// Returns the interop variable. |
| Expr *getInteropVar() const { return cast<Expr>(InteropVar); } |
| |
| child_range children() { return child_range(&InteropVar, &InteropVar + 1); } |
| |
| const_child_range children() const { |
| return const_child_range(&InteropVar, &InteropVar + 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_use; |
| } |
| }; |
| |
| /// This represents 'destroy' clause in the '#pragma omp depobj' |
| /// directive or the '#pragma omp interop' directive.. |
| /// |
| /// \code |
| /// #pragma omp depobj(a) destroy |
| /// #pragma omp interop destroy(obj) |
| /// \endcode |
| /// In these examples directive '#pragma omp depobj' and '#pragma omp interop' |
| /// have a 'destroy' clause. The 'interop' directive includes an object. |
| class OMPDestroyClause final : public OMPClause { |
| friend class OMPClauseReader; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// Location of interop variable. |
| SourceLocation VarLoc; |
| |
| /// The interop variable. |
| Stmt *InteropVar = nullptr; |
| |
| /// Set the interop variable. |
| void setInteropVar(Expr *E) { InteropVar = E; } |
| |
| /// Sets the location of '('. |
| void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } |
| |
| /// Sets the location of the interop variable. |
| void setVarLoc(SourceLocation Loc) { VarLoc = Loc; } |
| |
| public: |
| /// Build 'destroy' clause with an interop variable expression \a InteropVar. |
| /// |
| /// \param InteropVar The interop variable. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param VarLoc Location of the interop variable. |
| /// \param EndLoc Ending location of the clause. |
| OMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc, |
| SourceLocation LParenLoc, SourceLocation VarLoc, |
| SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_destroy, StartLoc, EndLoc), |
| LParenLoc(LParenLoc), VarLoc(VarLoc), InteropVar(InteropVar) {} |
| |
| /// Build 'destroy' clause. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param EndLoc Ending location of the clause. |
| OMPDestroyClause(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_destroy, StartLoc, EndLoc) {} |
| |
| /// Build an empty clause. |
| OMPDestroyClause() |
| : OMPClause(llvm::omp::OMPC_destroy, SourceLocation(), SourceLocation()) { |
| } |
| |
| /// Returns the location of '('. |
| SourceLocation getLParenLoc() const { return LParenLoc; } |
| |
| /// Returns the location of the interop variable. |
| SourceLocation getVarLoc() const { return VarLoc; } |
| |
| /// Returns the interop variable. |
| Expr *getInteropVar() const { return cast_or_null<Expr>(InteropVar); } |
| |
| child_range children() { |
| if (InteropVar) |
| return child_range(&InteropVar, &InteropVar + 1); |
| return child_range(child_iterator(), child_iterator()); |
| } |
| |
| const_child_range children() const { |
| if (InteropVar) |
| return const_child_range(&InteropVar, &InteropVar + 1); |
| 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_destroy; |
| } |
| }; |
| |
| /// This represents 'novariants' clause in the '#pragma omp ...' directive. |
| /// |
| /// \code |
| /// #pragma omp dispatch novariants(a > 5) |
| /// \endcode |
| /// In this example directive '#pragma omp dispatch' has simple 'novariants' |
| /// clause with condition 'a > 5'. |
| class OMPNovariantsClause final : public 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; } |
| |
| public: |
| /// Build 'novariants' clause with condition \a Cond. |
| /// |
| /// \param Cond Condition of the clause. |
| /// \param HelperCond Helper condition for the construct. |
| /// \param CaptureRegion Innermost OpenMP region where expressions in this |
| /// clause must be captured. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| OMPNovariantsClause(Expr *Cond, Stmt *HelperCond, |
| OpenMPDirectiveKind CaptureRegion, |
| SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_novariants, StartLoc, EndLoc), |
| OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond) { |
| 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; } |
| |
| /// 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); |
| } |
| |
| 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. |
| /// |
| /// \code |
| /// #pragma omp dispatch nocontext(a > 5) |
| /// \endcode |
| /// In this example directive '#pragma omp dispatch' has simple 'nocontext' |
| /// clause with condition 'a > 5'. |
| class OMPNocontextClause final : public 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; } |
| |
| public: |
| /// Build 'nocontext' clause with condition \a Cond. |
| /// |
| /// \param Cond Condition of the clause. |
| /// \param HelperCond Helper condition for the construct. |
| /// \param CaptureRegion Innermost OpenMP region where expressions in this |
| /// clause must be captured. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| 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) { |
| 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; } |
| |
| /// 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); |
| } |
| |
| 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. |
| /// |
| /// \code |
| /// #pragma omp task detach(evt) |
| /// \endcode |
| /// In this example directive '#pragma omp detach' has simple 'detach' clause |
| /// with the variable 'evt'. |
| class OMPDetachClause final : public 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; } |
| |
| public: |
| /// Build 'detach' clause with event-handler \a Evt. |
| /// |
| /// \param Evt Event handler expression. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \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) {} |
| |
| /// Build an empty clause. |
| OMPDetachClause() |
| : OMPClause(llvm::omp::OMPC_detach, SourceLocation(), SourceLocation()) {} |
| |
| /// Returns the location of '('. |
| SourceLocation getLParenLoc() const { return LParenLoc; } |
| |
| /// 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; |
| } |
| }; |
| |
| /// This represents clause 'inclusive' in the '#pragma omp scan' directive. |
| /// |
| /// \code |
| /// #pragma omp scan inclusive(a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp scan' has clause 'inclusive' |
| /// with the variables 'a' and 'b'. |
| class OMPInclusiveClause final |
| : public OMPVarListClause<OMPInclusiveClause>, |
| private llvm::TrailingObjects<OMPInclusiveClause, Expr *> { |
| friend class OMPClauseReader; |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Build clause with number of variables \a N. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param N Number of the variables in the clause. |
| OMPInclusiveClause(SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc, unsigned N) |
| : OMPVarListClause<OMPInclusiveClause>(llvm::omp::OMPC_inclusive, |
| StartLoc, LParenLoc, EndLoc, N) {} |
| |
| /// Build an empty clause. |
| /// |
| /// \param N Number of variables. |
| explicit OMPInclusiveClause(unsigned N) |
| : OMPVarListClause<OMPInclusiveClause>(llvm::omp::OMPC_inclusive, |
| SourceLocation(), SourceLocation(), |
| SourceLocation(), N) {} |
| |
| public: |
| /// Creates clause with a list of variables \a VL. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param VL List of references to the original variables. |
| static OMPInclusiveClause *Create(const ASTContext &C, |
| SourceLocation StartLoc, |
| SourceLocation LParenLoc, |
| SourceLocation EndLoc, ArrayRef<Expr *> VL); |
| |
| /// Creates an empty clause with the place for \a N variables. |
| /// |
| /// \param C AST context. |
| /// \param N The number of variables. |
| static OMPInclusiveClause *CreateEmpty(const ASTContext &C, unsigned N); |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPInclusiveClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| 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_inclusive; |
| } |
| }; |
| |
| /// This represents clause 'exclusive' in the '#pragma omp scan' directive. |
| /// |
| /// \code |
| /// #pragma omp scan exclusive(a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp scan' has clause 'exclusive' |
| /// with the variables 'a' and 'b'. |
| class OMPExclusiveClause final |
| : public OMPVarListClause<OMPExclusiveClause>, |
| private llvm::TrailingObjects<OMPExclusiveClause, Expr *> { |
| friend class OMPClauseReader; |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Build clause with number of variables \a N. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param N Number of the variables in the clause. |
| OMPExclusiveClause(SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc, unsigned N) |
| : OMPVarListClause<OMPExclusiveClause>(llvm::omp::OMPC_exclusive, |
| StartLoc, LParenLoc, EndLoc, N) {} |
| |
| /// Build an empty clause. |
| /// |
| /// \param N Number of variables. |
| explicit OMPExclusiveClause(unsigned N) |
| : OMPVarListClause<OMPExclusiveClause>(llvm::omp::OMPC_exclusive, |
| SourceLocation(), SourceLocation(), |
| SourceLocation(), N) {} |
| |
| public: |
| /// Creates clause with a list of variables \a VL. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param VL List of references to the original variables. |
| static OMPExclusiveClause *Create(const ASTContext &C, |
| SourceLocation StartLoc, |
| SourceLocation LParenLoc, |
| SourceLocation EndLoc, ArrayRef<Expr *> VL); |
| |
| /// Creates an empty clause with the place for \a N variables. |
| /// |
| /// \param C AST context. |
| /// \param N The number of variables. |
| static OMPExclusiveClause *CreateEmpty(const ASTContext &C, unsigned N); |
| |
| child_range children() { |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end())); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPExclusiveClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| 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_exclusive; |
| } |
| }; |
| |
| /// This represents clause 'uses_allocators' in the '#pragma omp target'-based |
| /// directives. |
| /// |
| /// \code |
| /// #pragma omp target uses_allocators(default_allocator, my_allocator(traits)) |
| /// \endcode |
| /// In this example directive '#pragma omp target' has clause 'uses_allocators' |
| /// with the allocators 'default_allocator' and user-defined 'my_allocator'. |
| class OMPUsesAllocatorsClause final |
| : public OMPClause, |
| private llvm::TrailingObjects<OMPUsesAllocatorsClause, Expr *, |
| SourceLocation> { |
| public: |
| /// Data for list of allocators. |
| struct Data { |
| /// Allocator. |
| Expr *Allocator = nullptr; |
| /// Allocator traits. |
| Expr *AllocatorTraits = nullptr; |
| /// Locations of '(' and ')' symbols. |
| SourceLocation LParenLoc, RParenLoc; |
| }; |
| |
| private: |
| friend class OMPClauseReader; |
| friend TrailingObjects; |
| |
| enum class ExprOffsets { |
| Allocator, |
| AllocatorTraits, |
| Total, |
| }; |
| |
| enum class ParenLocsOffsets { |
| LParen, |
| RParen, |
| Total, |
| }; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| /// Total number of allocators in the clause. |
| unsigned NumOfAllocators = 0; |
| |
| /// Build clause. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param N Number of allocators asssociated with the clause. |
| OMPUsesAllocatorsClause(SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc, unsigned N) |
| : OMPClause(llvm::omp::OMPC_uses_allocators, StartLoc, EndLoc), |
| LParenLoc(LParenLoc), NumOfAllocators(N) {} |
| |
| /// Build an empty clause. |
| /// \param N Number of allocators asssociated with the clause. |
| /// |
| explicit OMPUsesAllocatorsClause(unsigned N) |
| : OMPClause(llvm::omp::OMPC_uses_allocators, SourceLocation(), |
| SourceLocation()), |
| NumOfAllocators(N) {} |
| |
| unsigned numTrailingObjects(OverloadToken<Expr *>) const { |
| return NumOfAllocators * static_cast<int>(ExprOffsets::Total); |
| } |
| |
| /// Sets the location of '('. |
| void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } |
| |
| /// Sets the allocators data for the clause. |
| void setAllocatorsData(ArrayRef<OMPUsesAllocatorsClause::Data> Data); |
| |
| public: |
| /// Creates clause with a list of allocators \p Data. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| /// \param Data List of allocators. |
| static OMPUsesAllocatorsClause * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc, ArrayRef<OMPUsesAllocatorsClause::Data> Data); |
| |
| /// Creates an empty clause with the place for \p N allocators. |
| /// |
| /// \param C AST context. |
| /// \param N The number of allocators. |
| static OMPUsesAllocatorsClause *CreateEmpty(const ASTContext &C, unsigned N); |
| |
| /// Returns the location of '('. |
| SourceLocation getLParenLoc() const { return LParenLoc; } |
| |
| /// Returns number of allocators associated with the clause. |
| unsigned getNumberOfAllocators() const { return NumOfAllocators; } |
| |
| /// Returns data for the specified allocator. |
| OMPUsesAllocatorsClause::Data getAllocatorData(unsigned I) const; |
| |
| // Iterators |
| child_range children() { |
| Stmt **Begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>()); |
| return child_range(Begin, Begin + NumOfAllocators * |
| static_cast<int>(ExprOffsets::Total)); |
| } |
| const_child_range children() const { |
| Stmt *const *Begin = |
| reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>()); |
| return const_child_range( |
| Begin, Begin + NumOfAllocators * static_cast<int>(ExprOffsets::Total)); |
| } |
| |
| 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_uses_allocators; |
| } |
| }; |
| |
| /// This represents clause 'affinity' in the '#pragma omp task'-based |
| /// directives. |
| /// |
| /// \code |
| /// #pragma omp task affinity(iterator(i = 0:n) : ([3][n])a, b[:n], c[i]) |
| /// \endcode |
| /// In this example directive '#pragma omp task' has clause 'affinity' with the |
| /// affinity modifer 'iterator(i = 0:n)' and locator items '([3][n])a', 'b[:n]' |
| /// and 'c[i]'. |
| class OMPAffinityClause final |
| : public OMPVarListClause<OMPAffinityClause>, |
| private llvm::TrailingObjects<OMPAffinityClause, Expr *> { |
| friend class OMPClauseReader; |
| friend OMPVarListClause; |
| friend TrailingObjects; |
| |
| /// Location of ':' symbol. |
| SourceLocation ColonLoc; |
| |
| /// Build clause. |
| /// |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param ColonLoc Location of ':'. |
| /// \param EndLoc Ending location of the clause. |
| /// \param N Number of locators asssociated with the clause. |
| OMPAffinityClause(SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N) |
| : OMPVarListClause<OMPAffinityClause>(llvm::omp::OMPC_affinity, StartLoc, |
| LParenLoc, EndLoc, N) {} |
| |
| /// Build an empty clause. |
| /// \param N Number of locators asssociated with the clause. |
| /// |
| explicit OMPAffinityClause(unsigned N) |
| : OMPVarListClause<OMPAffinityClause>(llvm::omp::OMPC_affinity, |
| SourceLocation(), SourceLocation(), |
| SourceLocation(), N) {} |
| |
| /// Sets the affinity modifier for the clause, if any. |
| void setModifier(Expr *E) { |
| getTrailingObjects<Expr *>()[varlist_size()] = E; |
| } |
| |
| /// Sets the location of ':' symbol. |
| void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } |
| |
| public: |
| /// Creates clause with a modifier a list of locator items. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param ColonLoc Location of ':'. |
| /// \param EndLoc Ending location of the clause. |
| /// \param Locators List of locator items. |
| static OMPAffinityClause *Create(const ASTContext &C, SourceLocation StartLoc, |
| SourceLocation LParenLoc, |
| SourceLocation ColonLoc, |
| SourceLocation EndLoc, Expr *Modifier, |
| ArrayRef<Expr *> Locators); |
| |
| /// Creates an empty clause with the place for \p N locator items. |
| /// |
| /// \param C AST context. |
| /// \param N The number of locator items. |
| static OMPAffinityClause *CreateEmpty(const ASTContext &C, unsigned N); |
| |
| /// Gets affinity modifier. |
| Expr *getModifier() { return getTrailingObjects<Expr *>()[varlist_size()]; } |
| Expr *getModifier() const { |
| return getTrailingObjects<Expr *>()[varlist_size()]; |
| } |
| |
| /// Gets the location of ':' symbol. |
| SourceLocation getColonLoc() const { return ColonLoc; } |
| |
| // Iterators |
| child_range children() { |
| int Offset = getModifier() ? 1 : 0; |
| return child_range(reinterpret_cast<Stmt **>(varlist_begin()), |
| reinterpret_cast<Stmt **>(varlist_end() + Offset)); |
| } |
| |
| const_child_range children() const { |
| auto Children = const_cast<OMPAffinityClause *>(this)->children(); |
| return const_child_range(Children.begin(), Children.end()); |
| } |
| |
| 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_affinity; |
| } |
| }; |
| |
| /// This represents 'filter' clause in the '#pragma omp ...' directive. |
| /// |
| /// \code |
| /// #pragma omp masked filter(tid) |
| /// \endcode |
| /// In this example directive '#pragma omp masked' has 'filter' clause with |
| /// thread id. |
| class OMPFilterClause final : public 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; } |
| |
| public: |
| /// Build 'filter' clause with thread-id \a ThreadID. |
| /// |
| /// \param ThreadID Thread identifier. |
| /// \param HelperE Helper expression associated with this clause. |
| /// \param CaptureRegion Innermost OpenMP region where expressions in this |
| /// clause must be captured. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| 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) { |
| 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; } |
| |
| /// Return thread identifier. |
| Expr *getThreadID() { return cast<Expr>(ThreadID); } |
| |
| /// 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; |
| } |
| }; |
| |
| /// This represents 'bind' clause in the '#pragma omp ...' directives. |
| /// |
| /// \code |
| /// #pragma omp loop bind(parallel) |
| /// \endcode |
| class OMPBindClause final : public OMPClause { |
| friend class OMPClauseReader; |
| |
| /// Location of '('. |
| SourceLocation LParenLoc; |
| |
| /// The binding kind of 'bind' clause. |
| OpenMPBindClauseKind Kind = OMPC_BIND_unknown; |
| |
| /// Start location of the kind in source code. |
| SourceLocation KindLoc; |
| |
| /// Sets the location of '('. |
| void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } |
| |
| /// Set the binding kind. |
| void setBindKind(OpenMPBindClauseKind K) { Kind = K; } |
| |
| /// Set the binding kind location. |
| void setBindKindLoc(SourceLocation KLoc) { KindLoc = KLoc; } |
| |
| /// Build 'bind' clause with kind \a K ('teams', 'parallel', or 'thread'). |
| /// |
| /// \param K Binding kind of the clause ('teams', 'parallel' or 'thread'). |
| /// \param KLoc Starting location of the binding kind. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| OMPBindClause(OpenMPBindClauseKind K, SourceLocation KLoc, |
| SourceLocation StartLoc, SourceLocation LParenLoc, |
| SourceLocation EndLoc) |
| : OMPClause(llvm::omp::OMPC_bind, StartLoc, EndLoc), LParenLoc(LParenLoc), |
| Kind(K), KindLoc(KLoc) {} |
| |
| /// Build an empty clause. |
| OMPBindClause() |
| : OMPClause(llvm::omp::OMPC_bind, SourceLocation(), SourceLocation()) {} |
| |
| public: |
| /// Build 'bind' clause with kind \a K ('teams', 'parallel', or 'thread'). |
| /// |
| /// \param C AST context |
| /// \param K Binding kind of the clause ('teams', 'parallel' or 'thread'). |
| /// \param KLoc Starting location of the binding kind. |
| /// \param StartLoc Starting location of the clause. |
| /// \param LParenLoc Location of '('. |
| /// \param EndLoc Ending location of the clause. |
| static OMPBindClause *Create(const ASTContext &C, OpenMPBindClauseKind K, |
| SourceLocation KLoc, SourceLocation StartLoc, |
| SourceLocation LParenLoc, SourceLocation EndLoc); |
| |
| /// Build an empty 'bind' clause. |
| /// |
| /// \param C AST context |
| static OMPBindClause *CreateEmpty(const ASTContext &C); |
| |
| /// Returns the location of '('. |
| SourceLocation getLParenLoc() const { return LParenLoc; } |
| |
| /// Returns kind of the clause. |
| OpenMPBindClauseKind getBindKind() const { return Kind; } |
| |
| /// 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 |
| /// subclasses. |
| template<class ImplClass, template <typename> class Ptr, typename RetTy> |
| class OMPClauseVisitorBase { |
| public: |
| #define PTR(CLASS) Ptr<CLASS> |
| #define DISPATCH(CLASS) \ |
| return static_cast<ImplClass*>(this)->Visit##CLASS(static_cast<PTR(CLASS)>(S)) |
| |
| #define GEN_CLANG_CLAUSE_CLASS |
| #define CLAUSE_CLASS(Enum, Str, Class) \ |
| RetTy Visit##Class(PTR(Class) S) { DISPATCH(Class); } |
| #include "llvm/Frontend/OpenMP/OMP.inc" |
| |
| RetTy Visit(PTR(OMPClause) S) { |
| // Top switch clause: visit each OMPClause. |
| switch (S->getClauseKind()) { |
| #define GEN_CLANG_CLAUSE_CLASS |
| #define CLAUSE_CLASS(Enum, Str, Class) \ |
| case llvm::omp::Clause::Enum: \ |
| return Visit##Class(static_cast<PTR(Class)>(S)); |
| #define CLAUSE_NO_CLASS(Enum, Str) \ |
| case llvm::omp::Clause::Enum: \ |
| break; |
| #include "llvm/Frontend/OpenMP/OMP.inc" |
| } |
| } |
| // Base case, ignore it. :) |
| RetTy VisitOMPClause(PTR(OMPClause) Node) { return RetTy(); } |
| #undef PTR |
| #undef DISPATCH |
| }; |
| |
| template <typename T> using const_ptr = std::add_pointer_t<std::add_const_t<T>>; |
| |
| template <class ImplClass, typename RetTy = void> |
| class OMPClauseVisitor |
| : public OMPClauseVisitorBase<ImplClass, std::add_pointer_t, RetTy> {}; |
| template<class ImplClass, typename RetTy = void> |
| class ConstOMPClauseVisitor : |
| public OMPClauseVisitorBase <ImplClass, const_ptr, RetTy> {}; |
| |
| class OMPClausePrinter final : public OMPClauseVisitor<OMPClausePrinter> { |
| raw_ostream &OS; |
| const PrintingPolicy &Policy; |
| |
| /// Process clauses with list of variables. |
| template <typename T> void VisitOMPClauseList(T *Node, char StartSym); |
| /// Process motion clauses. |
| template <typename T> void VisitOMPMotionClause(T *Node); |
| |
| public: |
| OMPClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy) |
| : OS(OS), Policy(Policy) {} |
| |
| #define GEN_CLANG_CLAUSE_CLASS |
| #define CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(Class *S); |
| #include "llvm/Frontend/OpenMP/OMP.inc" |
| }; |
| |
| struct OMPTraitProperty { |
| llvm::omp::TraitProperty Kind = llvm::omp::TraitProperty::invalid; |
| |
| /// The raw string as we parsed it. This is needed for the `isa` trait set |
| /// (which accepts anything) and (later) extensions. |
| StringRef RawString; |
| }; |
| struct OMPTraitSelector { |
| Expr *ScoreOrCondition = nullptr; |
| llvm::omp::TraitSelector Kind = llvm::omp::TraitSelector::invalid; |
| llvm::SmallVector<OMPTraitProperty, 1> Properties; |
| }; |
| struct OMPTraitSet { |
| llvm::omp::TraitSet Kind = llvm::omp::TraitSet::invalid; |
| llvm::SmallVector<OMPTraitSelector, 2> Selectors; |
| }; |
| |
| /// Helper data structure representing the traits in a match clause of an |
| /// `declare variant` or `metadirective`. The outer level is an ordered |
| /// collection of selector sets, each with an associated kind and an ordered |
| /// collection of selectors. A selector has a kind, an optional score/condition, |
| /// and an ordered collection of properties. |
| class OMPTraitInfo { |
| /// Private constructor accesible only by ASTContext. |
| OMPTraitInfo() {} |
| friend class ASTContext; |
| |
| public: |
| /// Reconstruct a (partial) OMPTraitInfo object from a mangled name. |
| OMPTraitInfo(StringRef MangledName); |
| |
| /// The outermost level of selector sets. |
| llvm::SmallVector<OMPTraitSet, 2> Sets; |
| |
| bool anyScoreOrCondition( |
| llvm::function_ref<bool(Expr *&, bool /* IsScore */)> Cond) { |
| return llvm::any_of(Sets, [&](OMPTraitSet &Set) { |
| return llvm::any_of( |
| Set.Selectors, [&](OMPTraitSelector &Selector) { |
| return Cond(Selector.ScoreOrCondition, |
| /* IsScore */ Selector.Kind != |
| llvm::omp::TraitSelector::user_condition); |
| }); |
| }); |
| } |
| |
| /// Create a variant match info object from this trait info object. While the |
| /// former is a flat representation the actual main difference is that the |
| /// latter uses clang::Expr to store the score/condition while the former is |
| /// independent of clang. Thus, expressions and conditions are evaluated in |
| /// this method. |
| void getAsVariantMatchInfo(ASTContext &ASTCtx, |
| llvm::omp::VariantMatchInfo &VMI) const; |
| |
| /// Return a string representation identifying this context selector. |
| std::string getMangledName() const; |
| |
| /// Check the extension trait \p TP is active. |
| bool isExtensionActive(llvm::omp::TraitProperty TP) { |
| for (const OMPTraitSet &Set : Sets) { |
| if (Set.Kind != llvm::omp::TraitSet::implementation) |
| continue; |
| for (const OMPTraitSelector &Selector : Set.Selectors) { |
| if (Selector.Kind != llvm::omp::TraitSelector::implementation_extension) |
| continue; |
| for (const OMPTraitProperty &Property : Selector.Properties) { |
| if (Property.Kind == TP) |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| /// Print a human readable representation into \p OS. |
| void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const; |
| }; |
| llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo &TI); |
| llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo *TI); |
| |
| /// Clang specific specialization of the OMPContext to lookup target features. |
| struct TargetOMPContext final : public llvm::omp::OMPContext { |
| TargetOMPContext(ASTContext &ASTCtx, |
| std::function<void(StringRef)> &&DiagUnknownTrait, |
| const FunctionDecl *CurrentFunctionDecl, |
| ArrayRef<llvm::omp::TraitProperty> ConstructTraits); |
| |
| virtual ~TargetOMPContext() = default; |
| |
| /// See llvm::omp::OMPContext::matchesISATrait |
| bool matchesISATrait(StringRef RawString) const override; |
| |
| private: |
| std::function<bool(StringRef)> FeatureValidityCheck; |
| std::function<void(StringRef)> DiagUnknownTrait; |
| llvm::StringMap<bool> FeatureMap; |
| }; |
| |
| /// Contains data for OpenMP directives: clauses, children |
| /// expressions/statements (helpers for codegen) and associated statement, if |
| /// any. |
| class OMPChildren final |
| : private llvm::TrailingObjects<OMPChildren, OMPClause *, Stmt *> { |
| friend TrailingObjects; |
| friend class OMPClauseReader; |
| friend class OMPExecutableDirective; |
| template <typename T> friend class OMPDeclarativeDirective; |
| |
| /// Numbers of clauses. |
| unsigned NumClauses = 0; |
| /// Number of child expressions/stmts. |
| unsigned NumChildren = 0; |
| /// true if the directive has associated statement. |
| bool HasAssociatedStmt = false; |
| |
| /// Define the sizes of each trailing object array except the last one. This |
| /// is required for TrailingObjects to work properly. |
| size_t numTrailingObjects(OverloadToken<OMPClause *>) const { |
| return NumClauses; |
| } |
| |
| OMPChildren() = delete; |
| |
| OMPChildren(unsigned NumClauses, unsigned NumChildren, bool HasAssociatedStmt) |
| : NumClauses(NumClauses), NumChildren(NumChildren), |
| HasAssociatedStmt(HasAssociatedStmt) {} |
| |
| static size_t size(unsigned NumClauses, bool HasAssociatedStmt, |
| unsigned NumChildren); |
| |
| static OMPChildren *Create(void *Mem, ArrayRef<OMPClause *> Clauses); |
| static OMPChildren *Create(void *Mem, ArrayRef<OMPClause *> Clauses, Stmt *S, |
| unsigned NumChildren = 0); |
| static OMPChildren *CreateEmpty(void *Mem, unsigned NumClauses, |
| bool HasAssociatedStmt = false, |
| unsigned NumChildren = 0); |
| |
| public: |
| unsigned getNumClauses() const { return NumClauses; } |
| unsigned getNumChildren() const { return NumChildren; } |
| bool hasAssociatedStmt() const { return HasAssociatedStmt; } |
| |
| /// Set associated statement. |
| void setAssociatedStmt(Stmt *S) { |
| getTrailingObjects<Stmt *>()[NumChildren] = S; |
| } |
| |
| void setChildren(ArrayRef<Stmt *> Children); |
| |
| /// Sets the list of variables for this clause. |
| /// |
| /// \param Clauses The list of clauses for the directive. |
| /// |
| void setClauses(ArrayRef<OMPClause *> Clauses); |
| |
| /// Returns statement associated with the directive. |
| const Stmt *getAssociatedStmt() const { |
| return const_cast<OMPChildren *>(this)->getAssociatedStmt(); |
| } |
| Stmt *getAssociatedStmt() { |
| assert(HasAssociatedStmt && |
| "Expected directive with the associated statement."); |
| return getTrailingObjects<Stmt *>()[NumChildren]; |
| } |
| |
| /// Get the clauses storage. |
| MutableArrayRef<OMPClause *> getClauses() { |
| return llvm::makeMutableArrayRef(getTrailingObjects<OMPClause *>(), |
| NumClauses); |
| } |
| ArrayRef<OMPClause *> getClauses() const { |
| return const_cast<OMPChildren *>(this)->getClauses(); |
| } |
| |
| /// Returns the captured statement associated with the |
| /// component region within the (combined) directive. |
| /// |
| /// \param RegionKind Component region kind. |
| const CapturedStmt * |
| getCapturedStmt(OpenMPDirectiveKind RegionKind, |
| ArrayRef<OpenMPDirectiveKind> CaptureRegions) const { |
| assert(llvm::any_of( |
| CaptureRegions, |
| [=](const OpenMPDirectiveKind K) { return K == RegionKind; }) && |
| "RegionKind not found in OpenMP CaptureRegions."); |
| auto *CS = cast<CapturedStmt>(getAssociatedStmt()); |
| for (auto ThisCaptureRegion : CaptureRegions) { |
| if (ThisCaptureRegion == RegionKind) |
| return CS; |
| CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
| } |
| llvm_unreachable("Incorrect RegionKind specified for directive."); |
| } |
| |
| /// Get innermost captured statement for the construct. |
| CapturedStmt * |
| getInnermostCapturedStmt(ArrayRef<OpenMPDirectiveKind> CaptureRegions) { |
| assert(hasAssociatedStmt() && "Must have associated captured statement."); |
| assert(!CaptureRegions.empty() && |
| "At least one captured statement must be provided."); |
| auto *CS = cast<CapturedStmt>(getAssociatedStmt()); |
| for (unsigned Level = CaptureRegions.size(); Level > 1; --Level) |
| CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
| return CS; |
| } |
| |
| const CapturedStmt * |
| getInnermostCapturedStmt(ArrayRef<OpenMPDirectiveKind> CaptureRegions) const { |
| return const_cast<OMPChildren *>(this)->getInnermostCapturedStmt( |
| CaptureRegions); |
| } |
| |
| MutableArrayRef<Stmt *> getChildren(); |
| ArrayRef<Stmt *> getChildren() const { |
| return const_cast<OMPChildren *>(this)->getChildren(); |
| } |
| |
| Stmt *getRawStmt() { |
| assert(HasAssociatedStmt && |
| "Expected directive with the associated statement."); |
| if (auto *CS = dyn_cast<CapturedStmt>(getAssociatedStmt())) { |
| Stmt *S = nullptr; |
| do { |
| S = CS->getCapturedStmt(); |
| CS = dyn_cast<CapturedStmt>(S); |
| } while (CS); |
| return S; |
| } |
| return getAssociatedStmt(); |
| } |
| const Stmt *getRawStmt() const { |
| return const_cast<OMPChildren *>(this)->getRawStmt(); |
| } |
| |
| Stmt::child_range getAssociatedStmtAsRange() { |
| if (!HasAssociatedStmt) |
| return Stmt::child_range(Stmt::child_iterator(), Stmt::child_iterator()); |
| return Stmt::child_range(&getTrailingObjects<Stmt *>()[NumChildren], |
| &getTrailingObjects<Stmt *>()[NumChildren + 1]); |
| } |
| }; |
| |
| } // namespace clang |
| |
| #endif // LLVM_CLANG_AST_OPENMPCLAUSE_H |