diff options
Diffstat (limited to 'include/clang/AST/StmtOpenMP.h')
-rw-r--r-- | include/clang/AST/StmtOpenMP.h | 1159 |
1 files changed, 832 insertions, 327 deletions
diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h index 8570d8850a2f4..db02afe0568b5 100644 --- a/include/clang/AST/StmtOpenMP.h +++ b/include/clang/AST/StmtOpenMP.h @@ -1,4 +1,4 @@ -//===- StmtOpenMP.h - Classes for OpenMP directives and clauses --*- C++ -*-===// +//===- StmtOpenMP.h - Classes for OpenMP directives ------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -15,514 +15,1019 @@ #ifndef LLVM_CLANG_AST_STMTOPENMP_H #define LLVM_CLANG_AST_STMTOPENMP_H -#include "clang/Basic/OpenMPKinds.h" -#include "clang/Basic/SourceLocation.h" #include "clang/AST/Expr.h" +#include "clang/AST/OpenMPClause.h" #include "clang/AST/Stmt.h" +#include "clang/Basic/OpenMPKinds.h" +#include "clang/Basic/SourceLocation.h" namespace clang { //===----------------------------------------------------------------------===// -// AST classes for clauses. +// AST classes for directives. //===----------------------------------------------------------------------===// -/// \brief This is a basic class for representing single OpenMP clause. +/// \brief This is a basic class for representing single OpenMP executable +/// directive. /// -class OMPClause { - /// \brief Starting location of the clause (the clause keyword). +class OMPExecutableDirective : public Stmt { + friend class ASTStmtReader; + /// \brief Kind of the directive. + OpenMPDirectiveKind Kind; + /// \brief Starting location of the directive (directive keyword). SourceLocation StartLoc; - /// \brief Ending location of the clause. + /// \brief Ending location of the directive. SourceLocation EndLoc; - /// \brief Kind of the clause. - OpenMPClauseKind Kind; + /// \brief Numbers of clauses. + const unsigned NumClauses; + /// \brief Number of child expressions/stmts. + const unsigned NumChildren; + /// \brief Offset from this to the start of clauses. + /// There are NumClauses pointers to clauses, they are followed by + /// NumChildren pointers to child stmts/exprs (if the directive type + /// requires an associated stmt, then it has to be the first of them). + const unsigned ClausesOffset; + + /// \brief Get the clauses storage. + MutableArrayRef<OMPClause *> getClauses() { + OMPClause **ClauseStorage = reinterpret_cast<OMPClause **>( + reinterpret_cast<char *>(this) + ClausesOffset); + return MutableArrayRef<OMPClause *>(ClauseStorage, NumClauses); + } + protected: - OMPClause(OpenMPClauseKind K, SourceLocation StartLoc, SourceLocation EndLoc) - : StartLoc(StartLoc), EndLoc(EndLoc), Kind(K) {} + /// \brief Build instance of directive of class \a K. + /// + /// \param SC Statement class. + /// \param K Kind of OpenMP directive. + /// \param StartLoc Starting location of the directive (directive keyword). + /// \param EndLoc Ending location of the directive. + /// + template <typename T> + OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K, + SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses, unsigned NumChildren) + : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)), + EndLoc(std::move(EndLoc)), NumClauses(NumClauses), + NumChildren(NumChildren), + ClausesOffset(llvm::RoundUpToAlignment(sizeof(T), + llvm::alignOf<OMPClause *>())) {} + + /// \brief Sets the list of variables for this clause. + /// + /// \param Clauses The list of clauses for the directive. + /// + void setClauses(ArrayRef<OMPClause *> Clauses); + + /// \brief Set the associated statement for the directive. + /// + /// /param S Associated statement. + /// + void setAssociatedStmt(Stmt *S) { + assert(hasAssociatedStmt() && "no associated statement."); + *child_begin() = S; + } public: + /// \brief Iterates over a filtered subrange of clauses applied to a + /// directive. + /// + /// This iterator visits only those declarations that meet some run-time + /// criteria. + template <class FilterPredicate> class filtered_clause_iterator { + ArrayRef<OMPClause *>::const_iterator Current; + ArrayRef<OMPClause *>::const_iterator End; + FilterPredicate Pred; + void SkipToNextClause() { + while (Current != End && !Pred(*Current)) + ++Current; + } + + public: + typedef const OMPClause *value_type; + filtered_clause_iterator() : Current(), End() {} + filtered_clause_iterator(ArrayRef<OMPClause *> Arr, FilterPredicate Pred) + : Current(Arr.begin()), End(Arr.end()), Pred(Pred) { + SkipToNextClause(); + } + value_type operator*() const { return *Current; } + value_type operator->() const { return *Current; } + filtered_clause_iterator &operator++() { + ++Current; + SkipToNextClause(); + return *this; + } + + filtered_clause_iterator operator++(int) { + filtered_clause_iterator tmp(*this); + ++(*this); + return tmp; + } - /// \brief Returns the starting location of the clause. + bool operator!() { return Current == End; } + operator bool() { return Current != End; } + }; + + /// \brief Returns starting location of directive kind. SourceLocation getLocStart() const { return StartLoc; } - /// \brief Returns the ending location of the clause. + /// \brief Returns ending location of directive. SourceLocation getLocEnd() const { return EndLoc; } - /// \brief Sets the starting location of the clause. + /// \brief Set starting location of directive kind. + /// + /// \param Loc New starting location of directive. + /// void setLocStart(SourceLocation Loc) { StartLoc = Loc; } - /// \brief Sets the ending location of the clause. + /// \brief Set ending location of directive. + /// + /// \param Loc New ending location of directive. + /// void setLocEnd(SourceLocation Loc) { EndLoc = Loc; } - /// \brief Returns kind of OpenMP clause (private, shared, reduction, etc.). - OpenMPClauseKind getClauseKind() const { return Kind; } + /// \brief Get number of clauses. + unsigned getNumClauses() const { return NumClauses; } + + /// \brief Returns specified clause. + /// + /// \param i Number of clause. + /// + OMPClause *getClause(unsigned i) const { return clauses()[i]; } - bool isImplicit() const { return StartLoc.isInvalid();} + /// \brief Returns true if directive has associated statement. + bool hasAssociatedStmt() const { return NumChildren > 0; } - StmtRange children(); - ConstStmtRange children() const { - return const_cast<OMPClause *>(this)->children(); + /// \brief Returns statement associated with the directive. + Stmt *getAssociatedStmt() const { + assert(hasAssociatedStmt() && "no associated statement."); + return const_cast<Stmt *>(*child_begin()); } - static bool classof(const OMPClause *T) { - return true; + + OpenMPDirectiveKind getDirectiveKind() const { return Kind; } + + static bool classof(const Stmt *S) { + return S->getStmtClass() >= firstOMPExecutableDirectiveConstant && + S->getStmtClass() <= lastOMPExecutableDirectiveConstant; } -}; -/// \brief 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 OMPVarList { - friend class OMPClauseReader; - /// \brief Location of '('. - SourceLocation LParenLoc; - /// \brief Number of variables in the list. - unsigned NumVars; -protected: - /// \brief Fetches list of variables associated with this clause. - llvm::MutableArrayRef<Expr *> getVarRefs() { - return llvm::MutableArrayRef<Expr *>( - reinterpret_cast<Expr **>(static_cast<T *>(this) + 1), - NumVars); + child_range children() { + if (!hasAssociatedStmt()) + return child_range(); + Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end()); + return child_range(ChildStorage, ChildStorage + NumChildren); } - /// \brief 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(), - reinterpret_cast<Expr **>(static_cast<T *>(this) + 1)); + ArrayRef<OMPClause *> clauses() { return getClauses(); } + + ArrayRef<OMPClause *> clauses() const { + return const_cast<OMPExecutableDirective *>(this)->getClauses(); } +}; + +/// \brief This represents '#pragma omp parallel' directive. +/// +/// \code +/// #pragma omp parallel private(a,b) reduction(+: c,d) +/// \endcode +/// In this example directive '#pragma omp parallel' has clauses 'private' +/// with the variables 'a' and 'b' and 'reduction' with operator '+' and +/// variables 'c' and 'd'. +/// +class OMPParallelDirective : public OMPExecutableDirective { + /// \brief Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive (directive keyword). + /// \param EndLoc Ending Location of the directive. + /// + OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) + : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel, + StartLoc, EndLoc, NumClauses, 1) {} - /// \brief Build clause with number of variables \a N. + /// \brief Build an empty directive. /// - /// \param N Number of the variables in the clause. + /// \param NumClauses Number of clauses. /// - OMPVarList(SourceLocation LParenLoc, unsigned N) - : LParenLoc(LParenLoc), NumVars(N) { } + explicit OMPParallelDirective(unsigned NumClauses) + : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel, + SourceLocation(), SourceLocation(), NumClauses, + 1) {} + public: - typedef llvm::MutableArrayRef<Expr *>::iterator varlist_iterator; - typedef ArrayRef<const Expr *>::iterator varlist_const_iterator; - - unsigned varlist_size() const { return NumVars; } - bool varlist_empty() const { return NumVars == 0; } - 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(); } - - /// \brief Sets the location of '('. - void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } - /// \brief Returns the location of '('. - SourceLocation getLParenLoc() const { return LParenLoc; } - - /// \brief Fetches list of all variables in the clause. - ArrayRef<const Expr *> getVarRefs() const { - return ArrayRef<const Expr *>( - reinterpret_cast<const Expr *const *>(static_cast<const T *>(this) + 1), - NumVars); + /// \brief Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement associated with the directive. + /// + static OMPParallelDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); + + /// \brief Creates an empty directive with the place for \a N clauses. + /// + /// \param C AST context. + /// \param NumClauses Number of clauses. + /// + static OMPParallelDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPParallelDirectiveClass; } }; -/// \brief This represents 'default' clause in the '#pragma omp ...' directive. +/// \brief This represents '#pragma omp simd' directive. /// /// \code -/// #pragma omp parallel default(shared) +/// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d) /// \endcode -/// In this example directive '#pragma omp parallel' has simple 'default' -/// clause with kind 'shared'. +/// In this example directive '#pragma omp simd' has clauses 'private' +/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and +/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'. /// -class OMPDefaultClause : public OMPClause { - friend class OMPClauseReader; - /// \brief Location of '('. - SourceLocation LParenLoc; - /// \brief A kind of the 'default' clause. - OpenMPDefaultClauseKind Kind; - /// \brief Start location of the kind in source code. - SourceLocation KindKwLoc; - - /// \brief Set kind of the clauses. +class OMPSimdDirective : public OMPExecutableDirective { + friend class ASTStmtReader; + /// \brief Number of collapsed loops as specified by 'collapse' clause. + unsigned CollapsedNum; + /// \brief Build directive with the given start and end location. /// - /// \param K Argument of clause. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. /// - void setDefaultKind(OpenMPDefaultClauseKind K) { Kind = K; } + OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, unsigned NumClauses) + : OMPExecutableDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc, + EndLoc, NumClauses, 1), + CollapsedNum(CollapsedNum) {} - /// \brief Set argument location. + /// \brief Build an empty directive. /// - /// \param KLoc Argument location. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. /// - void setDefaultKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; } + explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses) + : OMPExecutableDirective(this, OMPSimdDirectiveClass, OMPD_simd, + SourceLocation(), SourceLocation(), NumClauses, + 1), + CollapsedNum(CollapsedNum) {} + public: - /// \brief Build 'default' clause with argument \a A ('none' or 'shared'). + /// \brief Creates directive with a list of \a Clauses. /// - /// \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. + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param CollapsedNum Number of collapsed loops. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. /// - OMPDefaultClause(OpenMPDefaultClauseKind A, SourceLocation ALoc, - SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc) - : OMPClause(OMPC_default, StartLoc, EndLoc), LParenLoc(LParenLoc), - Kind(A), KindKwLoc(ALoc) { } + static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation EndLoc, unsigned CollapsedNum, + ArrayRef<OMPClause *> Clauses, + Stmt *AssociatedStmt); - /// \brief Build an empty clause. + /// \brief Creates an empty directive with the place + /// for \a NumClauses clauses. + /// + /// \param C AST context. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. /// - OMPDefaultClause() - : OMPClause(OMPC_default, SourceLocation(), SourceLocation()), - LParenLoc(SourceLocation()), Kind(OMPC_DEFAULT_unknown), - KindKwLoc(SourceLocation()) { } + static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, + unsigned CollapsedNum, EmptyShell); - /// \brief Sets the location of '('. - void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } - /// \brief Returns the location of '('. - SourceLocation getLParenLoc() const { return LParenLoc; } + unsigned getCollapsedNumber() const { return CollapsedNum; } - /// \brief Returns kind of the clause. - OpenMPDefaultClauseKind getDefaultKind() const { return Kind; } + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPSimdDirectiveClass; + } +}; - /// \brief Returns location of clause kind. - SourceLocation getDefaultKindKwLoc() const { return KindKwLoc; } +/// \brief This represents '#pragma omp for' directive. +/// +/// \code +/// #pragma omp for private(a,b) reduction(+:c,d) +/// \endcode +/// In this example directive '#pragma omp for' has clauses 'private' with the +/// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c' +/// and 'd'. +/// +class OMPForDirective : public OMPExecutableDirective { + friend class ASTStmtReader; + /// \brief Number of collapsed loops as specified by 'collapse' clause. + unsigned CollapsedNum; + /// \brief Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, unsigned NumClauses) + : OMPExecutableDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, + EndLoc, NumClauses, 1), + CollapsedNum(CollapsedNum) {} - static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_default; - } + /// \brief Build an empty directive. + /// + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses) + : OMPExecutableDirective(this, OMPForDirectiveClass, OMPD_for, + SourceLocation(), SourceLocation(), NumClauses, + 1), + CollapsedNum(CollapsedNum) {} + +public: + /// \brief Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param CollapsedNum Number of collapsed loops. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. + /// + static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation EndLoc, unsigned CollapsedNum, + ArrayRef<OMPClause *> Clauses, + Stmt *AssociatedStmt); + + /// \brief Creates an empty directive with the place + /// for \a NumClauses clauses. + /// + /// \param C AST context. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, + unsigned CollapsedNum, EmptyShell); - StmtRange children() { - return StmtRange(); + unsigned getCollapsedNumber() const { return CollapsedNum; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPForDirectiveClass; } }; -/// \brief This represents clause 'private' in the '#pragma omp ...' directives. +/// \brief This represents '#pragma omp sections' directive. /// /// \code -/// #pragma omp parallel private(a,b) +/// #pragma omp sections private(a,b) reduction(+:c,d) /// \endcode -/// In this example directive '#pragma omp parallel' has clause 'private' -/// with the variables 'a' and 'b'. +/// In this example directive '#pragma omp sections' has clauses 'private' with +/// the variables 'a' and 'b' and 'reduction' with operator '+' and variables +/// 'c' and 'd'. /// -class OMPPrivateClause : public OMPClause, public OMPVarList<OMPPrivateClause> { - /// \brief Build clause with number of variables \a N. +class OMPSectionsDirective : public OMPExecutableDirective { + friend class ASTStmtReader; + /// \brief Build directive with the given start and end location. /// - /// \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 StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// \param NumClauses Number of clauses. /// - OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc, unsigned N) - : OMPClause(OMPC_private, StartLoc, EndLoc), - OMPVarList<OMPPrivateClause>(LParenLoc, N) { } + OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) + : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections, + StartLoc, EndLoc, NumClauses, 1) {} - /// \brief Build an empty clause. + /// \brief Build an empty directive. /// - /// \param N Number of variables. + /// \param NumClauses Number of clauses. /// - explicit OMPPrivateClause(unsigned N) - : OMPClause(OMPC_private, SourceLocation(), SourceLocation()), - OMPVarList<OMPPrivateClause>(SourceLocation(), N) { } + explicit OMPSectionsDirective(unsigned NumClauses) + : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections, + SourceLocation(), SourceLocation(), NumClauses, + 1) {} + public: - /// \brief Creates clause with a list of variables \a VL. + /// \brief Creates directive with a list of \a Clauses. /// /// \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 StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. /// - static OMPPrivateClause *Create(const ASTContext &C, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc, - ArrayRef<Expr *> VL); - /// \brief Creates an empty clause with the place for \a N variables. + static OMPSectionsDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); + + /// \brief Creates an empty directive with the place for \a NumClauses + /// clauses. /// /// \param C AST context. - /// \param N The number of variables. + /// \param NumClauses Number of clauses. /// - static OMPPrivateClause *CreateEmpty(const ASTContext &C, unsigned N); + static OMPSectionsDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, EmptyShell); - StmtRange children() { - return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), - reinterpret_cast<Stmt **>(varlist_end())); + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPSectionsDirectiveClass; } +}; + +/// \brief This represents '#pragma omp section' directive. +/// +/// \code +/// #pragma omp section +/// \endcode +/// +class OMPSectionDirective : public OMPExecutableDirective { + friend class ASTStmtReader; + /// \brief Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// + OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section, + StartLoc, EndLoc, 0, 1) {} - static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_private; + /// \brief Build an empty directive. + /// + explicit OMPSectionDirective() + : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section, + SourceLocation(), SourceLocation(), 0, 1) {} + +public: + /// \brief Creates directive. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param AssociatedStmt Statement, associated with the directive. + /// + static OMPSectionDirective *Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation EndLoc, + Stmt *AssociatedStmt); + + /// \brief Creates an empty directive. + /// + /// \param C AST context. + /// + static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPSectionDirectiveClass; } }; -/// \brief This represents clause 'firstprivate' in the '#pragma omp ...' -/// directives. +/// \brief This represents '#pragma omp single' directive. /// /// \code -/// #pragma omp parallel firstprivate(a,b) +/// #pragma omp single private(a,b) copyprivate(c,d) /// \endcode -/// In this example directive '#pragma omp parallel' has clause 'firstprivate' -/// with the variables 'a' and 'b'. +/// In this example directive '#pragma omp single' has clauses 'private' with +/// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'. /// -class OMPFirstprivateClause : public OMPClause, - public OMPVarList<OMPFirstprivateClause> { - /// \brief Build clause with number of variables \a N. +class OMPSingleDirective : public OMPExecutableDirective { + friend class ASTStmtReader; + /// \brief Build directive with the given start and end location. /// - /// \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 StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// \param NumClauses Number of clauses. /// - OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc, unsigned N) - : OMPClause(OMPC_firstprivate, StartLoc, EndLoc), - OMPVarList<OMPFirstprivateClause>(LParenLoc, N) { } + OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) + : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single, + StartLoc, EndLoc, NumClauses, 1) {} - /// \brief Build an empty clause. + /// \brief Build an empty directive. /// - /// \param N Number of variables. + /// \param NumClauses Number of clauses. /// - explicit OMPFirstprivateClause(unsigned N) - : OMPClause(OMPC_firstprivate, SourceLocation(), SourceLocation()), - OMPVarList<OMPFirstprivateClause>(SourceLocation(), N) { } + explicit OMPSingleDirective(unsigned NumClauses) + : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single, + SourceLocation(), SourceLocation(), NumClauses, + 1) {} + public: - /// \brief Creates clause with a list of variables \a VL. + /// \brief Creates directive with a list of \a Clauses. /// /// \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 OMPFirstprivateClause *Create(const ASTContext &C, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc, - ArrayRef<Expr *> VL); - /// \brief Creates an empty clause with the place for \a N variables. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. + /// + static OMPSingleDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); + + /// \brief Creates an empty directive with the place for \a NumClauses + /// clauses. /// /// \param C AST context. - /// \param N The number of variables. + /// \param NumClauses Number of clauses. /// - static OMPFirstprivateClause *CreateEmpty(const ASTContext &C, unsigned N); + static OMPSingleDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, EmptyShell); - StmtRange children() { - return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), - reinterpret_cast<Stmt **>(varlist_end())); + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPSingleDirectiveClass; } +}; + +/// \brief This represents '#pragma omp master' directive. +/// +/// \code +/// #pragma omp master +/// \endcode +/// +class OMPMasterDirective : public OMPExecutableDirective { + friend class ASTStmtReader; + /// \brief Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// + OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master, + StartLoc, EndLoc, 0, 1) {} + + /// \brief Build an empty directive. + /// + explicit OMPMasterDirective() + : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master, + SourceLocation(), SourceLocation(), 0, 1) {} + +public: + /// \brief Creates directive. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param AssociatedStmt Statement, associated with the directive. + /// + static OMPMasterDirective *Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation EndLoc, + Stmt *AssociatedStmt); + + /// \brief Creates an empty directive. + /// + /// \param C AST context. + /// + static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell); - static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_firstprivate; + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPMasterDirectiveClass; } }; -/// \brief This represents clause 'shared' in the '#pragma omp ...' directives. +/// \brief This represents '#pragma omp critical' directive. /// /// \code -/// #pragma omp parallel shared(a,b) +/// #pragma omp critical /// \endcode -/// In this example directive '#pragma omp parallel' has clause 'shared' -/// with the variables 'a' and 'b'. /// -class OMPSharedClause : public OMPClause, public OMPVarList<OMPSharedClause> { - /// \brief Build clause with number of variables \a N. +class OMPCriticalDirective : public OMPExecutableDirective { + friend class ASTStmtReader; + /// \brief Name of the directive. + DeclarationNameInfo DirName; + /// \brief Build directive with the given start and end location. + /// + /// \param Name Name of the directive. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. /// - /// \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. + OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc, + SourceLocation EndLoc) + : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical, + StartLoc, EndLoc, 0, 1), + DirName(Name) {} + + /// \brief Build an empty directive. /// - OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc, unsigned N) - : OMPClause(OMPC_shared, StartLoc, EndLoc), - OMPVarList<OMPSharedClause>(LParenLoc, N) { } + explicit OMPCriticalDirective() + : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical, + SourceLocation(), SourceLocation(), 0, 1), + DirName() {} - /// \brief Build an empty clause. + /// \brief Set name of the directive. /// - /// \param N Number of variables. + /// \param Name Name of the directive. /// - explicit OMPSharedClause(unsigned N) - : OMPClause(OMPC_shared, SourceLocation(), SourceLocation()), - OMPVarList<OMPSharedClause>(SourceLocation(), N) { } + void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; } + public: - /// \brief Creates clause with a list of variables \a VL. + /// \brief Creates directive. /// /// \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 Name Name of the directive. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param AssociatedStmt Statement, associated with the directive. /// - static OMPSharedClause *Create(const ASTContext &C, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc, ArrayRef<Expr *> VL); - /// \brief Creates an empty clause with \a N variables. + static OMPCriticalDirective * + Create(const ASTContext &C, const DeclarationNameInfo &Name, + SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt); + + /// \brief Creates an empty directive. /// /// \param C AST context. - /// \param N The number of variables. /// - static OMPSharedClause *CreateEmpty(const ASTContext &C, unsigned N); + static OMPCriticalDirective *CreateEmpty(const ASTContext &C, EmptyShell); - StmtRange children() { - return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), - reinterpret_cast<Stmt **>(varlist_end())); - } + /// \brief Return name of the directive. + /// + DeclarationNameInfo getDirectiveName() const { return DirName; } - static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_shared; + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPCriticalDirectiveClass; } }; -//===----------------------------------------------------------------------===// -// AST classes for directives. -//===----------------------------------------------------------------------===// - -/// \brief This is a basic class for representing single OpenMP executable -/// directive. +/// \brief This represents '#pragma omp parallel for' directive. /// -class OMPExecutableDirective : public Stmt { +/// \code +/// #pragma omp parallel for private(a,b) reduction(+:c,d) +/// \endcode +/// In this example directive '#pragma omp parallel for' has clauses 'private' +/// with the variables 'a' and 'b' and 'reduction' with operator '+' and +/// variables 'c' and 'd'. +/// +class OMPParallelForDirective : public OMPExecutableDirective { friend class ASTStmtReader; - /// \brief Kind of the directive. - OpenMPDirectiveKind Kind; - /// \brief Starting location of the directive (directive keyword). - SourceLocation StartLoc; - /// \brief Ending location of the directive. - SourceLocation EndLoc; - /// \brief Pointer to the list of clauses. - llvm::MutableArrayRef<OMPClause *> Clauses; - /// \brief Associated statement (if any) and expressions. - llvm::MutableArrayRef<Stmt *> StmtAndExpressions; -protected: - /// \brief Build instance of directive of class \a K. + /// \brief Number of collapsed loops as specified by 'collapse' clause. + unsigned CollapsedNum; + /// \brief Build directive with the given start and end location. /// - /// \param SC Statement class. - /// \param K Kind of OpenMP directive. - /// \param StartLoc Starting location of the directive (directive keyword). + /// \param StartLoc Starting location of the directive kind. /// \param EndLoc Ending location of the directive. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. /// - template <typename T> - OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K, - SourceLocation StartLoc, SourceLocation EndLoc, - unsigned NumClauses, unsigned NumberOfExpressions) - : Stmt(SC), Kind(K), StartLoc(StartLoc), EndLoc(EndLoc), - Clauses(reinterpret_cast<OMPClause **>(static_cast<T *>(this) + 1), - NumClauses), - StmtAndExpressions(reinterpret_cast<Stmt **>(Clauses.end()), - NumberOfExpressions) { } + OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, unsigned NumClauses) + : OMPExecutableDirective(this, OMPParallelForDirectiveClass, + OMPD_parallel_for, StartLoc, EndLoc, NumClauses, + 1), + CollapsedNum(CollapsedNum) {} - /// \brief Sets the list of variables for this clause. + /// \brief Build an empty directive. /// - /// \param Clauses The list of clauses for the directive. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. /// - void setClauses(ArrayRef<OMPClause *> Clauses); + explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses) + : OMPExecutableDirective(this, OMPParallelForDirectiveClass, + OMPD_parallel_for, SourceLocation(), + SourceLocation(), NumClauses, 1), + CollapsedNum(CollapsedNum) {} - /// \brief Set the associated statement for the directive. +public: + /// \brief Creates directive with a list of \a Clauses. /// - /// /param S Associated statement. + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param CollapsedNum Number of collapsed loops. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. /// - void setAssociatedStmt(Stmt *S) { - StmtAndExpressions[0] = S; + static OMPParallelForDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, + Stmt *AssociatedStmt); + + /// \brief Creates an empty directive with the place + /// for \a NumClauses clauses. + /// + /// \param C AST context. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + static OMPParallelForDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, + EmptyShell); + + unsigned getCollapsedNumber() const { return CollapsedNum; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPParallelForDirectiveClass; } +}; + +/// \brief This represents '#pragma omp parallel sections' directive. +/// +/// \code +/// #pragma omp parallel sections private(a,b) reduction(+:c,d) +/// \endcode +/// In this example directive '#pragma omp parallel sections' has clauses +/// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' +/// and variables 'c' and 'd'. +/// +class OMPParallelSectionsDirective : public OMPExecutableDirective { + friend class ASTStmtReader; + /// \brief Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// \param NumClauses Number of clauses. + /// + OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) + : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass, + OMPD_parallel_sections, StartLoc, EndLoc, + NumClauses, 1) {} + + /// \brief Build an empty directive. + /// + /// \param NumClauses Number of clauses. + /// + explicit OMPParallelSectionsDirective(unsigned NumClauses) + : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass, + OMPD_parallel_sections, SourceLocation(), + SourceLocation(), NumClauses, 1) {} public: - /// \brief Returns starting location of directive kind. - SourceLocation getLocStart() const { return StartLoc; } - /// \brief Returns ending location of directive. - SourceLocation getLocEnd() const { return EndLoc; } + /// \brief Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. + /// + static OMPParallelSectionsDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); - /// \brief Set starting location of directive kind. + /// \brief Creates an empty directive with the place for \a NumClauses + /// clauses. /// - /// \param Loc New starting location of directive. + /// \param C AST context. + /// \param NumClauses Number of clauses. /// - void setLocStart(SourceLocation Loc) { StartLoc = Loc; } - /// \brief Set ending location of directive. + static OMPParallelSectionsDirective * + CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPParallelSectionsDirectiveClass; + } +}; + +/// \brief This represents '#pragma omp task' directive. +/// +/// \code +/// #pragma omp task private(a,b) final(d) +/// \endcode +/// In this example directive '#pragma omp task' has clauses 'private' with the +/// variables 'a' and 'b' and 'final' with condition 'd'. +/// +class OMPTaskDirective : public OMPExecutableDirective { + friend class ASTStmtReader; + /// \brief Build directive with the given start and end location. /// - /// \param Loc New ending location of directive. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// \param NumClauses Number of clauses. /// - void setLocEnd(SourceLocation Loc) { EndLoc = Loc; } + OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) + : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc, + EndLoc, NumClauses, 1) {} - /// \brief Get number of clauses. - unsigned getNumClauses() const { return Clauses.size(); } + /// \brief Build an empty directive. + /// + /// \param NumClauses Number of clauses. + /// + explicit OMPTaskDirective(unsigned NumClauses) + : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, + SourceLocation(), SourceLocation(), NumClauses, + 1) {} - /// \brief Returns specified clause. +public: + /// \brief Creates directive with a list of \a Clauses. /// - /// \param i Number of clause. + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. /// - OMPClause *getClause(unsigned i) const { - assert(i < Clauses.size() && "index out of bound!"); - return Clauses[i]; - } + static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses, + Stmt *AssociatedStmt); - /// \brief Returns statement associated with the directive. - Stmt *getAssociatedStmt() const { - return StmtAndExpressions[0]; + /// \brief Creates an empty directive with the place for \a NumClauses + /// clauses. + /// + /// \param C AST context. + /// \param NumClauses Number of clauses. + /// + static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, + EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPTaskDirectiveClass; } +}; - OpenMPDirectiveKind getDirectiveKind() const { return Kind; } +/// \brief This represents '#pragma omp taskyield' directive. +/// +/// \code +/// #pragma omp taskyield +/// \endcode +/// +class OMPTaskyieldDirective : public OMPExecutableDirective { + friend class ASTStmtReader; + /// \brief Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// + OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield, + StartLoc, EndLoc, 0, 0) {} - static bool classof(const Stmt *S) { - return S->getStmtClass() >= firstOMPExecutableDirectiveConstant && - S->getStmtClass() <= lastOMPExecutableDirectiveConstant; - } + /// \brief Build an empty directive. + /// + explicit OMPTaskyieldDirective() + : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield, + SourceLocation(), SourceLocation(), 0, 0) {} - child_range children() { - return child_range(StmtAndExpressions.begin(), StmtAndExpressions.end()); +public: + /// \brief Creates directive. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// + static OMPTaskyieldDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); + + /// \brief Creates an empty directive. + /// + /// \param C AST context. + /// + static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPTaskyieldDirectiveClass; } +}; + +/// \brief This represents '#pragma omp barrier' directive. +/// +/// \code +/// #pragma omp barrier +/// \endcode +/// +class OMPBarrierDirective : public OMPExecutableDirective { + friend class ASTStmtReader; + /// \brief Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// + OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier, + StartLoc, EndLoc, 0, 0) {} - ArrayRef<OMPClause *> clauses() { return Clauses; } + /// \brief Build an empty directive. + /// + explicit OMPBarrierDirective() + : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier, + SourceLocation(), SourceLocation(), 0, 0) {} - ArrayRef<OMPClause *> clauses() const { return Clauses; } +public: + /// \brief Creates directive. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// + static OMPBarrierDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); + + /// \brief Creates an empty directive. + /// + /// \param C AST context. + /// + static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPBarrierDirectiveClass; + } }; -/// \brief This represents '#pragma omp parallel' directive. +/// \brief This represents '#pragma omp taskwait' directive. /// /// \code -/// #pragma omp parallel private(a,b) reduction(+: c,d) +/// #pragma omp taskwait /// \endcode -/// In this example directive '#pragma omp parallel' has clauses 'private' -/// with the variables 'a' and 'b' and 'reduction' with operator '+' and -/// variables 'c' and 'd'. /// -class OMPParallelDirective : public OMPExecutableDirective { +class OMPTaskwaitDirective : public OMPExecutableDirective { + friend class ASTStmtReader; /// \brief Build directive with the given start and end location. /// - /// \param StartLoc Starting location of the directive (directive keyword). + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// + OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait, + StartLoc, EndLoc, 0, 0) {} + + /// \brief Build an empty directive. + /// + explicit OMPTaskwaitDirective() + : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait, + SourceLocation(), SourceLocation(), 0, 0) {} + +public: + /// \brief Creates directive. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. /// \param EndLoc Ending Location of the directive. /// - OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc, - unsigned N) - : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel, - StartLoc, EndLoc, N, 1) { } + static OMPTaskwaitDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); + + /// \brief Creates an empty directive. + /// + /// \param C AST context. + /// + static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPTaskwaitDirectiveClass; + } +}; + +/// \brief This represents '#pragma omp flush' directive. +/// +/// \code +/// #pragma omp flush(a,b) +/// \endcode +/// In this example directive '#pragma omp flush' has 2 arguments- variables 'a' +/// and 'b'. +/// 'omp flush' directive does not have clauses but have an optional list of +/// variables to flush. This list of variables is stored within some fake clause +/// FlushClause. +class OMPFlushDirective : public OMPExecutableDirective { + friend class ASTStmtReader; + /// \brief Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// \param NumClauses Number of clauses. + /// + OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) + : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush, + StartLoc, EndLoc, NumClauses, 0) {} /// \brief Build an empty directive. /// - /// \param N Number of clauses. + /// \param NumClauses Number of clauses. /// - explicit OMPParallelDirective(unsigned N) - : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel, - SourceLocation(), SourceLocation(), N, 1) { } + explicit OMPFlushDirective(unsigned NumClauses) + : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush, + SourceLocation(), SourceLocation(), NumClauses, + 0) {} + public: /// \brief Creates directive with a list of \a Clauses. /// /// \param C AST context. /// \param StartLoc Starting location of the directive kind. /// \param EndLoc Ending Location of the directive. - /// \param Clauses List of clauses. - /// \param AssociatedStmt Statement associated with the directive. + /// \param Clauses List of clauses (only single OMPFlushClause clause is + /// allowed). /// - static OMPParallelDirective *Create(const ASTContext &C, - SourceLocation StartLoc, - SourceLocation EndLoc, - ArrayRef<OMPClause *> Clauses, - Stmt *AssociatedStmt); + static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses); - /// \brief Creates an empty directive with the place for \a N clauses. + /// \brief Creates an empty directive with the place for \a NumClauses + /// clauses. /// /// \param C AST context. - /// \param N The number of clauses. + /// \param NumClauses Number of clauses. /// - static OMPParallelDirective *CreateEmpty(const ASTContext &C, unsigned N, - EmptyShell); + static OMPFlushDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, EmptyShell); static bool classof(const Stmt *T) { - return T->getStmtClass() == OMPParallelDirectiveClass; + return T->getStmtClass() == OMPFlushDirectiveClass; } }; -} // end namespace clang +} // end namespace clang #endif |