diff options
Diffstat (limited to 'clang/include')
-rw-r--r-- | clang/include/clang-c/Index.h | 6 | ||||
-rw-r--r-- | clang/include/clang/AST/RecursiveASTVisitor.h | 3 | ||||
-rw-r--r-- | clang/include/clang/AST/StmtOpenMP.h | 82 | ||||
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | clang/include/clang/Basic/OpenMPKinds.h | 7 | ||||
-rw-r--r-- | clang/include/clang/Basic/StmtNodes.td | 1 | ||||
-rw-r--r-- | clang/include/clang/Sema/Sema.h | 6 | ||||
-rw-r--r-- | clang/include/clang/Serialization/ASTBitCodes.h | 1 |
8 files changed, 107 insertions, 2 deletions
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index b49acf6b5854..b0d7ef509c26 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -2596,7 +2596,11 @@ enum CXCursorKind { */ CXCursor_OMPMetaDirective = 294, - CXCursor_LastStmt = CXCursor_OMPMetaDirective, + /** OpenMP loop directive. + */ + CXCursor_OMPGenericLoopDirective = 295, + + CXCursor_LastStmt = CXCursor_OMPGenericLoopDirective, /** * Cursor that represents the translation unit itself. diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index f200cd3920e6..74c49546c00b 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -3023,6 +3023,9 @@ DEF_TRAVERSE_STMT(OMPDispatchDirective, DEF_TRAVERSE_STMT(OMPMaskedDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) +DEF_TRAVERSE_STMT(OMPGenericLoopDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + // OpenMP clauses. template <typename Derived> bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) { diff --git a/clang/include/clang/AST/StmtOpenMP.h b/clang/include/clang/AST/StmtOpenMP.h index 60d47b93ba79..48b2dce152a6 100644 --- a/clang/include/clang/AST/StmtOpenMP.h +++ b/clang/include/clang/AST/StmtOpenMP.h @@ -1144,7 +1144,7 @@ protected: if (isOpenMPLoopBoundSharingDirective(Kind)) return CombinedDistributeEnd; if (isOpenMPWorksharingDirective(Kind) || isOpenMPTaskLoopDirective(Kind) || - isOpenMPDistributeDirective(Kind)) + isOpenMPGenericLoopDirective(Kind) || isOpenMPDistributeDirective(Kind)) return WorksharingEnd; return DefaultEnd; } @@ -1176,6 +1176,7 @@ protected: } void setIsLastIterVariable(Expr *IL) { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPGenericLoopDirective(getDirectiveKind()) || isOpenMPTaskLoopDirective(getDirectiveKind()) || isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); @@ -1183,6 +1184,7 @@ protected: } void setLowerBoundVariable(Expr *LB) { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPGenericLoopDirective(getDirectiveKind()) || isOpenMPTaskLoopDirective(getDirectiveKind()) || isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); @@ -1190,6 +1192,7 @@ protected: } void setUpperBoundVariable(Expr *UB) { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPGenericLoopDirective(getDirectiveKind()) || isOpenMPTaskLoopDirective(getDirectiveKind()) || isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); @@ -1197,6 +1200,7 @@ protected: } void setStrideVariable(Expr *ST) { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPGenericLoopDirective(getDirectiveKind()) || isOpenMPTaskLoopDirective(getDirectiveKind()) || isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); @@ -1204,6 +1208,7 @@ protected: } void setEnsureUpperBound(Expr *EUB) { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPGenericLoopDirective(getDirectiveKind()) || isOpenMPTaskLoopDirective(getDirectiveKind()) || isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); @@ -1211,6 +1216,7 @@ protected: } void setNextLowerBound(Expr *NLB) { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPGenericLoopDirective(getDirectiveKind()) || isOpenMPTaskLoopDirective(getDirectiveKind()) || isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); @@ -1218,6 +1224,7 @@ protected: } void setNextUpperBound(Expr *NUB) { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPGenericLoopDirective(getDirectiveKind()) || isOpenMPTaskLoopDirective(getDirectiveKind()) || isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); @@ -1225,6 +1232,7 @@ protected: } void setNumIterations(Expr *NI) { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPGenericLoopDirective(getDirectiveKind()) || isOpenMPTaskLoopDirective(getDirectiveKind()) || isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); @@ -1327,6 +1335,7 @@ public: Stmt *getPreInits() { return Data->getChildren()[PreInitsOffset]; } Expr *getIsLastIterVariable() const { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPGenericLoopDirective(getDirectiveKind()) || isOpenMPTaskLoopDirective(getDirectiveKind()) || isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); @@ -1334,6 +1343,7 @@ public: } Expr *getLowerBoundVariable() const { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPGenericLoopDirective(getDirectiveKind()) || isOpenMPTaskLoopDirective(getDirectiveKind()) || isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); @@ -1341,6 +1351,7 @@ public: } Expr *getUpperBoundVariable() const { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPGenericLoopDirective(getDirectiveKind()) || isOpenMPTaskLoopDirective(getDirectiveKind()) || isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); @@ -1348,6 +1359,7 @@ public: } Expr *getStrideVariable() const { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPGenericLoopDirective(getDirectiveKind()) || isOpenMPTaskLoopDirective(getDirectiveKind()) || isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); @@ -1355,6 +1367,7 @@ public: } Expr *getEnsureUpperBound() const { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPGenericLoopDirective(getDirectiveKind()) || isOpenMPTaskLoopDirective(getDirectiveKind()) || isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); @@ -1362,6 +1375,7 @@ public: } Expr *getNextLowerBound() const { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPGenericLoopDirective(getDirectiveKind()) || isOpenMPTaskLoopDirective(getDirectiveKind()) || isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); @@ -1369,6 +1383,7 @@ public: } Expr *getNextUpperBound() const { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPGenericLoopDirective(getDirectiveKind()) || isOpenMPTaskLoopDirective(getDirectiveKind()) || isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); @@ -1376,6 +1391,7 @@ public: } Expr *getNumIterations() const { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPGenericLoopDirective(getDirectiveKind()) || isOpenMPTaskLoopDirective(getDirectiveKind()) || isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); @@ -1509,6 +1525,7 @@ public: T->getStmtClass() == OMPTaskLoopSimdDirectiveClass || T->getStmtClass() == OMPMasterTaskLoopDirectiveClass || T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass || + T->getStmtClass() == OMPGenericLoopDirectiveClass || T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass || T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass || T->getStmtClass() == OMPDistributeDirectiveClass || @@ -5461,6 +5478,69 @@ public: } }; +/// This represents '#pragma omp loop' directive. +/// +/// \code +/// #pragma omp loop private(a,b) binding(parallel) order(concurrent) +/// \endcode +/// In this example directive '#pragma omp loop' has +/// clauses 'private' with the variables 'a' and 'b', 'binding' with +/// modifier 'parallel' and 'order(concurrent). +/// +class OMPGenericLoopDirective final : public OMPLoopDirective { + friend class ASTStmtReader; + friend class OMPExecutableDirective; + /// 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. + /// + OMPGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum) + : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop, + StartLoc, EndLoc, CollapsedNum) {} + + /// Build an empty directive. + /// + /// \param CollapsedNum Number of collapsed nested loops. + /// + explicit OMPGenericLoopDirective(unsigned CollapsedNum) + : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop, + SourceLocation(), SourceLocation(), CollapsedNum) {} + +public: + /// Creates directive with a list of \p Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param CollapsedNum Number of collapsed loops. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. + /// \param Exprs Helper expressions for CodeGen. + /// + static OMPGenericLoopDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, + Stmt *AssociatedStmt, const HelperExprs &Exprs); + + /// Creates an empty directive with a place for \a NumClauses clauses. + /// + /// \param C AST context. + /// \param NumClauses Number of clauses. + /// \param CollapsedNum Number of collapsed nested loops. + /// + static OMPGenericLoopDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, + EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPGenericLoopDirectiveClass; + } +}; + } // end namespace clang #endif diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 7153b9c66563..7f7410a20084 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10803,6 +10803,9 @@ def note_omp_protected_structured_block : Note<"jump bypasses OpenMP structured block">; def note_omp_exits_structured_block : Note<"jump exits scope of OpenMP structured block">; +def err_omp_lastprivate_loop_var_non_loop_iteration : Error< + "only loop iteration variables are allowed in 'lastprivate' clause in " + "'omp loop' directives">; def err_omp_interop_variable_expected : Error< "expected%select{| non-const}0 variable of type 'omp_interop_t'">; def err_omp_interop_variable_wrong_type : Error< diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h index c90bd429d87c..269f8d96f0bb 100644 --- a/clang/include/clang/Basic/OpenMPKinds.h +++ b/clang/include/clang/Basic/OpenMPKinds.h @@ -253,6 +253,13 @@ bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind); /// otherwise - false. bool isOpenMPNestingDistributeDirective(OpenMPDirectiveKind DKind); +/// Checks if the specified directive constitutes a 'loop' directive in the +/// outermost nest. For example, 'omp teams loop' or 'omp loop'. +/// \param DKind Specified directive. +/// \return true - the directive has loop on the outermost nest. +/// otherwise - false. +bool isOpenMPGenericLoopDirective(OpenMPDirectiveKind DKind); + /// Checks if the specified clause is one of private clauses like /// 'private', 'firstprivate', 'reduction' etc.. /// \param Kind Clause kind. diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index f002c3632829..ab31c544ea9d 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -282,3 +282,4 @@ def OMPTargetTeamsDistributeSimdDirective : StmtNode<OMPLoopDirective>; def OMPInteropDirective : StmtNode<OMPExecutableDirective>; def OMPDispatchDirective : StmtNode<OMPExecutableDirective>; def OMPMaskedDirective : StmtNode<OMPExecutableDirective>; +def OMPGenericLoopDirective : StmtNode<OMPLoopDirective>; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index b87532c51f63..11e157bc7d73 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -10940,6 +10940,12 @@ public: Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc); + /// Called on well-formed '\#pragma omp loop' after parsing of the + /// associated statement. + StmtResult ActOnOpenMPGenericLoopDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA); + /// Checks correctness of linear modifiers. bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, SourceLocation LinLoc); diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 68520cd9b3e3..341da5bd1d62 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1957,6 +1957,7 @@ enum StmtCode { STMT_OMP_INTEROP_DIRECTIVE, STMT_OMP_DISPATCH_DIRECTIVE, STMT_OMP_MASKED_DIRECTIVE, + STMT_OMP_GENERIC_LOOP_DIRECTIVE, EXPR_OMP_ARRAY_SECTION, EXPR_OMP_ARRAY_SHAPING, EXPR_OMP_ITERATOR, |