Author: Alexey Bataev Date: 2020-03-20T14:20:38-04:00 New Revision: 06dea73307e75f0227ba24cab2adf2e4dad62b88
URL: https://github.com/llvm/llvm-project/commit/06dea73307e75f0227ba24cab2adf2e4dad62b88 DIFF: https://github.com/llvm/llvm-project/commit/06dea73307e75f0227ba24cab2adf2e4dad62b88.diff LOG: [OPENMP50]Initial support for inclusive clause. Added parsing/sema/serialization support for inclusive clause in scan directive. Added: Modified: clang/include/clang/AST/OpenMPClause.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Basic/OpenMPKinds.def clang/include/clang/Sema/Sema.h clang/lib/AST/OpenMPClause.cpp clang/lib/AST/StmtProfile.cpp clang/lib/Basic/OpenMPKinds.cpp clang/lib/CodeGen/CGStmtOpenMP.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/test/OpenMP/nesting_of_regions.cpp clang/test/OpenMP/scan_ast_print.cpp clang/test/OpenMP/scan_messages.cpp clang/tools/libclang/CIndex.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index e82a5f09a32d..38485cb1ad7e 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -6911,6 +6911,80 @@ class OMPDetachClause final : public OMPClause { } }; +/// 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>(OMPC_inclusive, StartLoc, + LParenLoc, EndLoc, N) {} + + /// Build an empty clause. + /// + /// \param N Number of variables. + explicit OMPInclusiveClause(unsigned N) + : OMPVarListClause<OMPInclusiveClause>(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() == OMPC_inclusive; + } +}; + /// This class implements a simple visitor for OMPClause /// subclasses. template<class ImplClass, template <typename> class Ptr, typename RetTy> diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 4cc8b95c3bd1..94f68f555fdf 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -3183,6 +3183,13 @@ bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) { return true; } +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPInclusiveClause( + OMPInclusiveClause *C) { + TRY_TO(VisitOMPClauseList(C)); + return true; +} + template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) { TRY_TO(VisitOMPClauseList(C)); diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 38d0fe445268..39d29060372f 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10055,6 +10055,8 @@ def err_omp_depobj_expected : Error< "expected depobj expression">; def err_omp_depobj_single_clause_expected : Error< "exactly one of 'depend', 'destroy', or 'update' clauses is expected">; +def err_omp_scan_single_clause_expected : Error< + "exactly one of 'inclusive' or 'exclusive' clauses is expected">; def err_omp_expected_predefined_allocator : Error< "expected one of the predefined allocators for the variables with the static " "storage: 'omp_default_mem_alloc', 'omp_large_cap_mem_alloc', " diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def index 0488dad6706b..1e4b2b116a98 100644 --- a/clang/include/clang/Basic/OpenMPKinds.def +++ b/clang/include/clang/Basic/OpenMPKinds.def @@ -215,6 +215,9 @@ #ifndef OPENMP_DEVICE_MODIFIER #define OPENMP_DEVICE_MODIFIER(Name) #endif +#ifndef OPENMP_SCAN_CLAUSE +#define OPENMP_SCAN_CLAUSE(Name) +#endif // OpenMP clauses. OPENMP_CLAUSE(allocator, OMPAllocatorClause) @@ -281,6 +284,10 @@ OPENMP_CLAUSE(order, OMPOrderClause) OPENMP_CLAUSE(depobj, OMPDepobjClause) OPENMP_CLAUSE(destroy, OMPDestroyClause) OPENMP_CLAUSE(detach, OMPDetachClause) +OPENMP_CLAUSE(inclusive, OMPInclusiveClause) + +// Clauses allowed for OpenMP directive 'scan'. +OPENMP_SCAN_CLAUSE(inclusive) // Clauses allowed for OpenMP directive 'parallel'. OPENMP_PARALLEL_CLAUSE(if) @@ -1098,6 +1105,7 @@ OPENMP_DEPOBJ_CLAUSE(depend) OPENMP_DEPOBJ_CLAUSE(destroy) OPENMP_DEPOBJ_CLAUSE(update) +#undef OPENMP_SCAN_CLAUSE #undef OPENMP_DEVICE_MODIFIER #undef OPENMP_DEPOBJ_CLAUSE #undef OPENMP_FLUSH_CLAUSE diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index d09d095eb357..b2c849f7e1b8 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -10495,6 +10495,11 @@ class Sema final { ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, SourceLocation DepLinMapLastLoc); + /// Called on well-formed 'inclusive' clause. + OMPClause *ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); /// Called on well-formed 'allocate' clause. OMPClause * ActOnOpenMPAllocateClause(Expr *Allocator, ArrayRef<Expr *> VarList, diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index a95789067056..de8fd67a0250 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -146,6 +146,7 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) { case OMPC_order: case OMPC_destroy: case OMPC_detach: + case OMPC_inclusive: break; } @@ -233,6 +234,7 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C) case OMPC_order: case OMPC_destroy: case OMPC_detach: + case OMPC_inclusive: break; } @@ -1248,6 +1250,24 @@ void OMPNontemporalClause::setPrivateRefs(ArrayRef<Expr *> VL) { std::copy(VL.begin(), VL.end(), varlist_end()); } +OMPInclusiveClause *OMPInclusiveClause::Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc, + ArrayRef<Expr *> VL) { + void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size())); + auto *Clause = + new (Mem) OMPInclusiveClause(StartLoc, LParenLoc, EndLoc, VL.size()); + Clause->setVarRefs(VL); + return Clause; +} + +OMPInclusiveClause *OMPInclusiveClause::CreateEmpty(const ASTContext &C, + unsigned N) { + void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N)); + return new (Mem) OMPInclusiveClause(N); +} + //===----------------------------------------------------------------------===// // OpenMP clauses printing methods //===----------------------------------------------------------------------===// @@ -1805,6 +1825,14 @@ void OMPClausePrinter::VisitOMPOrderClause(OMPOrderClause *Node) { << ")"; } +void OMPClausePrinter::VisitOMPInclusiveClause(OMPInclusiveClause *Node) { + if (!Node->varlist_empty()) { + OS << "inclusive"; + VisitOMPClauseList(Node, '('); + OS << ")"; + } +} + void OMPTraitInfo::getAsVariantMatchInfo( ASTContext &ASTCtx, llvm::omp::VariantMatchInfo &VMI) const { for (const OMPTraitSet &Set : Sets) { diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 832eff46a7c0..a31a65fad35f 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -795,6 +795,9 @@ void OMPClauseProfiler::VisitOMPNontemporalClause( for (auto *E : C->private_refs()) Profiler->VisitStmt(E); } +void OMPClauseProfiler::VisitOMPInclusiveClause(const OMPInclusiveClause *C) { + VisitOMPClauseList(C); +} void OMPClauseProfiler::VisitOMPOrderClause(const OMPOrderClause *C) {} } // namespace diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 0e27a1652c39..a905dff440d7 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -212,6 +212,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, case OMPC_nontemporal: case OMPC_destroy: case OMPC_detach: + case OMPC_inclusive: break; } llvm_unreachable("Invalid OpenMP simple clause kind"); @@ -447,6 +448,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, case OMPC_nontemporal: case OMPC_destroy: case OMPC_detach: + case OMPC_inclusive: break; } llvm_unreachable("Invalid OpenMP simple clause kind"); diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 37bdb53bb1dc..e05829f0a890 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -4616,6 +4616,7 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, case OMPC_order: case OMPC_destroy: case OMPC_detach: + case OMPC_inclusive: llvm_unreachable("Clause is not allowed in 'omp atomic'."); } } diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index c5026f7eda14..bb239c833b82 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -2344,7 +2344,7 @@ bool Parser::ParseOpenMPSimpleVarList( /// from-clause | is_device_ptr-clause | task_reduction-clause | /// in_reduction-clause | allocator-clause | allocate-clause | /// acq_rel-clause | acquire-clause | release-clause | relaxed-clause | -/// depobj-clause | destroy-clause | detach-clause +/// depobj-clause | destroy-clause | detach-clause | inclusive-clause /// OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, bool FirstClause) { @@ -2513,6 +2513,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_is_device_ptr: case OMPC_allocate: case OMPC_nontemporal: + case OMPC_inclusive: Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective); break; case OMPC_device_type: @@ -3237,8 +3238,8 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, } /// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate', -/// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction' or -/// 'in_reduction'. +/// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction', +/// 'in_reduction', 'nontemporal' or 'inclusive'. /// /// private-clause: /// 'private' '(' list ')' @@ -3278,6 +3279,10 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, /// 'is_device_ptr' '(' list ')' /// allocate-clause: /// 'allocate' '(' [ allocator ':' ] list ')' +/// nontemporal-clause: +/// 'nontemporal' '(' list ')' +/// inclusive-clause: +/// 'inclusive' '(' list ')' /// /// For 'linear' clause linear-list may have the following forms: /// list diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 777cc5447545..861b75a774d8 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -5177,6 +5177,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( case OMPC_nontemporal: case OMPC_order: case OMPC_destroy: + case OMPC_inclusive: continue; case OMPC_allocator: case OMPC_flush: @@ -8794,6 +8795,11 @@ StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc) { + if (Clauses.size() != 1) { + Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), + diag::err_omp_scan_single_clause_expected); + return StmtError(); + } return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); } @@ -11145,6 +11151,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, case OMPC_nontemporal: case OMPC_order: case OMPC_destroy: + case OMPC_inclusive: llvm_unreachable("Clause is not allowed."); } return Res; @@ -11880,6 +11887,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPC_order: case OMPC_destroy: case OMPC_detach: + case OMPC_inclusive: llvm_unreachable("Unexpected OpenMP clause."); } return CaptureRegion; @@ -12317,6 +12325,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause( case OMPC_nontemporal: case OMPC_destroy: case OMPC_detach: + case OMPC_inclusive: llvm_unreachable("Clause is not allowed."); } return Res; @@ -12540,6 +12549,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( case OMPC_order: case OMPC_destroy: case OMPC_detach: + case OMPC_inclusive: llvm_unreachable("Clause is not allowed."); } return Res; @@ -12770,6 +12780,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, case OMPC_nontemporal: case OMPC_order: case OMPC_detach: + case OMPC_inclusive: llvm_unreachable("Clause is not allowed."); } return Res; @@ -12977,6 +12988,9 @@ OMPClause *Sema::ActOnOpenMPVarListClause( case OMPC_nontemporal: Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); break; + case OMPC_inclusive: + Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); + break; case OMPC_if: case OMPC_depobj: case OMPC_final: @@ -18043,3 +18057,31 @@ OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); } + +OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc) { + SmallVector<Expr *, 8> Vars; + for (Expr *RefExpr : VarList) { + assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); + SourceLocation ELoc; + SourceRange ERange; + Expr *SimpleRefExpr = RefExpr; + auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, + /*AllowArraySection=*/true); + if (Res.second) + // It will be analyzed later. + Vars.push_back(RefExpr); + ValueDecl *D = Res.first; + if (!D) + continue; + + Vars.push_back(RefExpr); + } + + if (Vars.empty()) + return nullptr; + + return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); +} diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 8d0c466edec3..8a22eb89d806 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -2053,6 +2053,18 @@ class TreeTransform { EndLoc); } + /// Build a new OpenMP 'inclusive' clause. + /// + /// By default, performs semantic analysis to build the new OpenMP clause. + /// Subclasses may override this routine to provide diff erent behavior. + OMPClause *RebuildOMPInclusiveClause(ArrayRef<Expr *> VarList, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc) { + return getSema().ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, + EndLoc); + } + /// Build a new OpenMP 'order' clause. /// /// By default, performs semantic analysis to build the new OpenMP clause. @@ -9521,6 +9533,21 @@ TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) { Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); } +template <typename Derived> +OMPClause * +TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) { + llvm::SmallVector<Expr *, 16> Vars; + Vars.reserve(C->varlist_size()); + for (auto *VE : C->varlists()) { + ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); + if (EVar.isInvalid()) + return nullptr; + Vars.push_back(EVar.get()); + } + return getDerived().RebuildOMPInclusiveClause( + Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); +} + template <typename Derived> OMPClause * TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) { diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index dd0fa9f70daf..12a80619c540 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -11824,6 +11824,9 @@ OMPClause *OMPClauseReader::readClause() { case OMPC_nontemporal: C = OMPNontemporalClause::CreateEmpty(Context, Record.readInt()); break; + case OMPC_inclusive: + C = OMPInclusiveClause::CreateEmpty(Context, Record.readInt()); + break; case OMPC_order: C = new (Context) OMPOrderClause(); break; @@ -12634,6 +12637,16 @@ void OMPClauseReader::VisitOMPNontemporalClause(OMPNontemporalClause *C) { C->setPrivateRefs(Vars); } +void OMPClauseReader::VisitOMPInclusiveClause(OMPInclusiveClause *C) { + C->setLParenLoc(Record.readSourceLocation()); + unsigned NumVars = C->varlist_size(); + SmallVector<Expr *, 16> Vars; + Vars.reserve(NumVars); + for (unsigned i = 0; i != NumVars; ++i) + Vars.push_back(Record.readSubExpr()); + C->setVarRefs(Vars); +} + void OMPClauseReader::VisitOMPOrderClause(OMPOrderClause *C) { C->setKind(Record.readEnum<OpenMPOrderClauseKind>()); C->setLParenLoc(Record.readSourceLocation()); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index c96e46543dba..c95cabcf5f59 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -6593,6 +6593,13 @@ void OMPClauseWriter::VisitOMPNontemporalClause(OMPNontemporalClause *C) { Record.AddStmt(E); } +void OMPClauseWriter::VisitOMPInclusiveClause(OMPInclusiveClause *C) { + Record.push_back(C->varlist_size()); + Record.AddSourceLocation(C->getLParenLoc()); + for (auto *VE : C->varlists()) + Record.AddStmt(VE); +} + void OMPClauseWriter::VisitOMPOrderClause(OMPOrderClause *C) { Record.writeEnum(C->getKind()); Record.AddSourceLocation(C->getLParenLoc()); diff --git a/clang/test/OpenMP/nesting_of_regions.cpp b/clang/test/OpenMP/nesting_of_regions.cpp index 4ecfac6f0777..d987d84c79e3 100644 --- a/clang/test/OpenMP/nesting_of_regions.cpp +++ b/clang/test/OpenMP/nesting_of_regions.cpp @@ -337,7 +337,7 @@ void foo() { } #pragma omp simd for (int i = 0; i < 10; ++i) { -#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}} bar(); } #pragma omp simd @@ -618,7 +618,7 @@ void foo() { } #pragma omp for for (int i = 0; i < 10; ++i) { -#pragma omp scan // omp45-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} +#pragma omp scan // omp45-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} omp50-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}} bar(); } #pragma omp for @@ -876,7 +876,7 @@ void foo() { } #pragma omp for simd for (int i = 0; i < 10; ++i) { -#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}} bar(); } #pragma omp for simd @@ -9861,7 +9861,7 @@ void foo() { } #pragma omp simd for (int i = 0; i < 10; ++i) { -#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}} bar(); } #pragma omp simd @@ -10116,7 +10116,7 @@ void foo() { } #pragma omp for for (int i = 0; i < 10; ++i) { -#pragma omp scan // omp45-error {{region cannot be closely nested inside 'for' region}} +#pragma omp scan // omp45-error {{region cannot be closely nested inside 'for' region}} omp50-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}} bar(); } #pragma omp for @@ -10361,7 +10361,7 @@ void foo() { } #pragma omp for simd for (int i = 0; i < 10; ++i) { -#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}} bar(); } #pragma omp for simd diff --git a/clang/test/OpenMP/scan_ast_print.cpp b/clang/test/OpenMP/scan_ast_print.cpp index 042605d8a508..efcaa2da138a 100644 --- a/clang/test/OpenMP/scan_ast_print.cpp +++ b/clang/test/OpenMP/scan_ast_print.cpp @@ -17,33 +17,33 @@ T tmain(T argc) { static T a; #pragma omp for for (int i = 0; i < 10; ++i) { -#pragma omp scan +#pragma omp scan inclusive(a) } return a + argc; } // CHECK: static T a; // CHECK-NEXT: #pragma omp for // CHECK-NEXT: for (int i = 0; i < 10; ++i) { -// CHECK-NEXT: #pragma omp scan{{$}} +// CHECK-NEXT: #pragma omp scan inclusive(a){{$}} // CHECK: static int a; // CHECK-NEXT: #pragma omp for // CHECK-NEXT: for (int i = 0; i < 10; ++i) { -// CHECK-NEXT: #pragma omp scan +// CHECK-NEXT: #pragma omp scan inclusive(a) // CHECK: static char a; // CHECK-NEXT: #pragma omp for // CHECK-NEXT: for (int i = 0; i < 10; ++i) { -// CHECK-NEXT: #pragma omp scan +// CHECK-NEXT: #pragma omp scan inclusive(a) int main(int argc, char **argv) { static int a; // CHECK: static int a; #pragma omp for simd for (int i = 0; i < 10; ++i) { -#pragma omp scan +#pragma omp scan inclusive(a) } // CHECK-NEXT: #pragma omp for simd // CHECK-NEXT: for (int i = 0; i < 10; ++i) { -// CHECK-NEXT: #pragma omp scan{{$}} +// CHECK-NEXT: #pragma omp scan inclusive(a){{$}} return tmain(argc) + tmain(argv[0][0]) + a; } diff --git a/clang/test/OpenMP/scan_messages.cpp b/clang/test/OpenMP/scan_messages.cpp index 4533b9aed10d..ea4e273e9d0b 100644 --- a/clang/test/OpenMP/scan_messages.cpp +++ b/clang/test/OpenMP/scan_messages.cpp @@ -6,78 +6,78 @@ template <class T> T tmain(T argc) { #pragma omp for for (int i = 0; i < 10; ++i) { -#pragma omp scan +#pragma omp scan // expected-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}} ; } #pragma omp for for (int i = 0; i < 10; ++i) { -#pragma omp scan allocate(argc) // expected-error {{unexpected OpenMP clause 'allocate' in directive '#pragma omp scan'}} -#pragma omp scan untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp scan'}} -#pragma omp scan unknown // expected-warning {{extra tokens at the end of '#pragma omp scan' are ignored}} +#pragma omp scan allocate(argc) // expected-error {{unexpected OpenMP clause 'allocate' in directive '#pragma omp scan'}} expected-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}} +#pragma omp scan untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp scan'}} expected-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}} +#pragma omp scan unknown // expected-warning {{extra tokens at the end of '#pragma omp scan' are ignored}} expected-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}} } #pragma omp for simd for (int i = 0; i < 10; ++i) if (argc) -#pragma omp scan // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} +#pragma omp scan inclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} if (argc) { -#pragma omp scan +#pragma omp scan inclusive(argc) } #pragma omp simd for (int i = 0; i < 10; ++i) while (argc) -#pragma omp scan // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} +#pragma omp scan inclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} while (argc) { -#pragma omp scan +#pragma omp scan inclusive(argc) } #pragma omp simd for (int i = 0; i < 10; ++i) do -#pragma omp scan // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} +#pragma omp scan inclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} while (argc) ; #pragma omp simd for (int i = 0; i < 10; ++i) do { -#pragma omp scan +#pragma omp scan inclusive(argc) } while (argc); #pragma omp simd for (int i = 0; i < 10; ++i) switch (argc) -#pragma omp scan // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} +#pragma omp scan inclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} switch (argc) case 1: -#pragma omp scan // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} +#pragma omp scan inclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} switch (argc) case 1: { -#pragma omp scan +#pragma omp scan inclusive(argc) } #pragma omp simd for (int i = 0; i < 10; ++i) switch (argc) { -#pragma omp scan +#pragma omp scan inclusive(argc) case 1: -#pragma omp scan +#pragma omp scan inclusive(argc) break; default: { -#pragma omp scan +#pragma omp scan inclusive(argc) } break; } #pragma omp simd for (int i = 0; i < 10; ++i) for (;;) -#pragma omp scan // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} +#pragma omp scan inclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} for (;;) { -#pragma omp scan +#pragma omp scan inclusive(argc) } #pragma omp simd for (int i = 0; i < 10; ++i) { label: -#pragma omp scan +#pragma omp scan inclusive(argc) } #pragma omp simd for (int i = 0; i < 10; ++i) { label1 : { -#pragma omp scan +#pragma omp scan inclusive(argc) }} return T(); @@ -86,77 +86,77 @@ label1 : { int main(int argc, char **argv) { #pragma omp simd for (int i = 0; i < 10; ++i) { -#pragma omp scan +#pragma omp scan inclusive(argc) inclusive(argc) // expected-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}} ; } #pragma omp simd for (int i = 0; i < 10; ++i) { -#pragma omp scan untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp scan'}} -#pragma omp scan unknown // expected-warning {{extra tokens at the end of '#pragma omp scan' are ignored}} +#pragma omp scan untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp scan'}} expected-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}} +#pragma omp scan unknown // expected-warning {{extra tokens at the end of '#pragma omp scan' are ignored}} expected-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}} } #pragma omp simd for (int i = 0; i < 10; ++i) if (argc) -#pragma omp scan // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} +#pragma omp scan inclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} if (argc) { -#pragma omp scan +#pragma omp scan inclusive(argc) } #pragma omp simd for (int i = 0; i < 10; ++i) while (argc) -#pragma omp scan // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} +#pragma omp scan inclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} while (argc) { -#pragma omp scan +#pragma omp scan inclusive(argc) } #pragma omp simd for (int i = 0; i < 10; ++i) do -#pragma omp scan // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} +#pragma omp scan inclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} while (argc) ; #pragma omp simd for (int i = 0; i < 10; ++i) do { -#pragma omp scan +#pragma omp scan inclusive(argc) } while (argc); #pragma omp simd for (int i = 0; i < 10; ++i) switch (argc) -#pragma omp scan // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} +#pragma omp scan inclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} switch (argc) case 1: -#pragma omp scan // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} +#pragma omp scan inclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} switch (argc) case 1: { -#pragma omp scan +#pragma omp scan inclusive(argc) } #pragma omp simd for (int i = 0; i < 10; ++i) switch (argc) { -#pragma omp scan +#pragma omp scan inclusive(argc) case 1: -#pragma omp scan +#pragma omp scan inclusive(argc) break; default: { -#pragma omp scan +#pragma omp scan inclusive(argc) } break; } #pragma omp simd for (int i = 0; i < 10; ++i) for (;;) -#pragma omp scan // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} +#pragma omp scan inclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} for (;;) { -#pragma omp scan +#pragma omp scan inclusive(argc) } #pragma omp simd for (int i = 0; i < 10; ++i) { label: -#pragma omp scan +#pragma omp scan inclusive(argc) } #pragma omp simd for (int i = 0; i < 10; ++i) { label1 : { -#pragma omp scan +#pragma omp scan inclusive(argc) } } diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index e4727c86fafe..31a0f364a348 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -2309,6 +2309,9 @@ void OMPClauseEnqueue::VisitOMPClauseList(T *Node) { } } +void OMPClauseEnqueue::VisitOMPInclusiveClause(const OMPInclusiveClause *C) { + VisitOMPClauseList(C); +} void OMPClauseEnqueue::VisitOMPAllocateClause(const OMPAllocateClause *C) { VisitOMPClauseList(C); Visitor->AddStmt(C->getAllocator()); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits