Author: Alexey Bataev Date: 2020-03-20T07:58:15-04:00 New Revision: fcba7c3534f98851531095f8457eb3142e237f0b
URL: https://github.com/llvm/llvm-project/commit/fcba7c3534f98851531095f8457eb3142e237f0b DIFF: https://github.com/llvm/llvm-project/commit/fcba7c3534f98851531095f8457eb3142e237f0b.diff LOG: [OPENMP50]Initial support for scan directive. Addedi basic parsing/sema/serialization support for scan directive. Added: clang/test/OpenMP/scan_ast_print.cpp clang/test/OpenMP/scan_messages.cpp Modified: clang/include/clang-c/Index.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/AST/StmtOpenMP.h clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Basic/StmtNodes.td clang/include/clang/Sema/Sema.h clang/include/clang/Serialization/ASTBitCodes.h clang/lib/AST/StmtOpenMP.cpp clang/lib/AST/StmtPrinter.cpp clang/lib/AST/StmtProfile.cpp clang/lib/Basic/OpenMPKinds.cpp clang/lib/CodeGen/CGOpenMPRuntime.cpp clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp clang/lib/CodeGen/CGStmt.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaExceptionSpec.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReaderStmt.cpp clang/lib/Serialization/ASTWriterStmt.cpp clang/lib/StaticAnalyzer/Core/ExprEngine.cpp clang/test/OpenMP/nesting_of_regions.cpp clang/tools/libclang/CIndex.cpp clang/tools/libclang/CXCursor.cpp llvm/include/llvm/Frontend/OpenMP/OMPKinds.def Removed: ################################################################################ diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 9d4930a3887a..ad2bb6a76c43 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -2578,7 +2578,11 @@ enum CXCursorKind { */ CXCursor_OMPDepobjDirective = 286, - CXCursor_LastStmt = CXCursor_OMPDepobjDirective, + /** OpenMP scan directive. + */ + CXCursor_OMPScanDirective = 287, + + CXCursor_LastStmt = CXCursor_OMPScanDirective, /** * Cursor that represents the translation unit itself. diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 27a0bc774184..4cc8b95c3bd1 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2852,6 +2852,9 @@ DEF_TRAVERSE_STMT(OMPFlushDirective, DEF_TRAVERSE_STMT(OMPDepobjDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) +DEF_TRAVERSE_STMT(OMPScanDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + DEF_TRAVERSE_STMT(OMPOrderedDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) diff --git a/clang/include/clang/AST/StmtOpenMP.h b/clang/include/clang/AST/StmtOpenMP.h index 5f7589acdb9e..b390bf0042f9 100644 --- a/clang/include/clang/AST/StmtOpenMP.h +++ b/clang/include/clang/AST/StmtOpenMP.h @@ -4688,6 +4688,63 @@ class OMPTargetTeamsDistributeSimdDirective final : public OMPLoopDirective { } }; +/// This represents '#pragma omp scan' directive. +/// +/// \code +/// #pragma omp scan inclusive(a) +/// \endcode +/// In this example directive '#pragma omp scan' has clause 'inclusive' with +/// list item 'a'. +class OMPScanDirective final : public OMPExecutableDirective { + friend class ASTStmtReader; + /// 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. + /// + OMPScanDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) + : OMPExecutableDirective(this, OMPScanDirectiveClass, + llvm::omp::OMPD_scan, StartLoc, EndLoc, + NumClauses, 0) {} + + /// Build an empty directive. + /// + /// \param NumClauses Number of clauses. + /// + explicit OMPScanDirective(unsigned NumClauses) + : OMPExecutableDirective(this, OMPScanDirectiveClass, + llvm::omp::OMPD_scan, SourceLocation(), + SourceLocation(), NumClauses, 0) {} + +public: + /// 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 (only single OMPFlushClause clause is + /// allowed). + /// + static OMPScanDirective *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses); + + /// Creates an empty directive with the place for \a NumClauses + /// clauses. + /// + /// \param C AST context. + /// \param NumClauses Number of clauses. + /// + static OMPScanDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, + EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPScanDirectiveClass; + } +}; + } // end namespace clang #endif diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 92af99fe5719..38d0fe445268 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -9823,9 +9823,10 @@ def err_omp_prohibited_region : Error< "%select{|; perhaps you forget to enclose 'omp %3' directive into a parallel region?|" "; perhaps you forget to enclose 'omp %3' directive into a for or a parallel for region with 'ordered' clause?|" "; perhaps you forget to enclose 'omp %3' directive into a target region?|" - "; perhaps you forget to enclose 'omp %3' directive into a teams region?}2">; + "; perhaps you forget to enclose 'omp %3' directive into a teams region?|" + "; perhaps you forget to enclose 'omp %3' directive into a for, simd, or for simd region?}2">; def err_omp_prohibited_region_simd : Error< - "OpenMP constructs may not be nested inside a simd region%select{| except for ordered simd, simd or atomic directive}0">; + "OpenMP constructs may not be nested inside a simd region%select{| except for ordered simd, simd, scan, or atomic directive}0">; def err_omp_prohibited_region_atomic : Error< "OpenMP constructs may not be nested inside an atomic region">; def err_omp_prohibited_region_critical_same_name : Error< @@ -10016,7 +10017,7 @@ def warn_omp_nesting_simd : Warning< InGroup<SourceUsesOpenMP>; def err_omp_orphaned_device_directive : Error< "orphaned 'omp %0' directives are prohibited" - "; perhaps you forget to enclose the directive into a %select{|||target |teams }1region?">; + "; perhaps you forget to enclose the directive into a %select{|||target |teams|for, simd, or for simd }1region?">; def err_omp_reduction_non_addressable_expression : Error< "expected addressable reduction item for the task-based directives">; def err_omp_reduction_with_nogroup : Error< diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index 41c6dbdb42e9..a617ab80021f 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -233,6 +233,7 @@ def OMPTaskwaitDirective : StmtNode<OMPExecutableDirective>; def OMPTaskgroupDirective : StmtNode<OMPExecutableDirective>; def OMPFlushDirective : StmtNode<OMPExecutableDirective>; def OMPDepobjDirective : StmtNode<OMPExecutableDirective>; +def OMPScanDirective : StmtNode<OMPExecutableDirective>; def OMPOrderedDirective : StmtNode<OMPExecutableDirective>; def OMPAtomicDirective : StmtNode<OMPExecutableDirective>; def OMPTargetDirective : StmtNode<OMPExecutableDirective>; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 28f6705b307f..d09d095eb357 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -10094,6 +10094,10 @@ class Sema final { StmtResult ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc); + /// Called on well-formed '\#pragma omp scan'. + StmtResult ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, + SourceLocation StartLoc, + SourceLocation EndLoc); /// Called on well-formed '\#pragma omp ordered' after parsing of the /// associated statement. StmtResult ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 31226fb0516c..e5088ac9cbab 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1826,6 +1826,7 @@ namespace serialization { STMT_OMP_TASKWAIT_DIRECTIVE, STMT_OMP_FLUSH_DIRECTIVE, STMT_OMP_DEPOBJ_DIRECTIVE, + STMT_OMP_SCAN_DIRECTIVE, STMT_OMP_ORDERED_DIRECTIVE, STMT_OMP_ATOMIC_DIRECTIVE, STMT_OMP_TARGET_DIRECTIVE, diff --git a/clang/lib/AST/StmtOpenMP.cpp b/clang/lib/AST/StmtOpenMP.cpp index 153d492598d3..995f710876af 100644 --- a/clang/lib/AST/StmtOpenMP.cpp +++ b/clang/lib/AST/StmtOpenMP.cpp @@ -781,6 +781,27 @@ OMPDepobjDirective *OMPDepobjDirective::CreateEmpty(const ASTContext &C, return new (Mem) OMPDepobjDirective(NumClauses); } +OMPScanDirective *OMPScanDirective::Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses) { + unsigned Size = llvm::alignTo(sizeof(OMPScanDirective), alignof(OMPClause *)); + void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size(), + alignof(OMPScanDirective)); + auto *Dir = new (Mem) OMPScanDirective(StartLoc, EndLoc, Clauses.size()); + Dir->setClauses(Clauses); + return Dir; +} + +OMPScanDirective *OMPScanDirective::CreateEmpty(const ASTContext &C, + unsigned NumClauses, + EmptyShell) { + unsigned Size = llvm::alignTo(sizeof(OMPScanDirective), alignof(OMPClause *)); + void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses, + alignof(OMPScanDirective)); + return new (Mem) OMPScanDirective(NumClauses); +} + OMPOrderedDirective *OMPOrderedDirective::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index f7a97c2743c1..68d0b144ced5 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -758,6 +758,11 @@ void StmtPrinter::VisitOMPDepobjDirective(OMPDepobjDirective *Node) { PrintOMPExecutableDirective(Node); } +void StmtPrinter::VisitOMPScanDirective(OMPScanDirective *Node) { + Indent() << "#pragma omp scan"; + PrintOMPExecutableDirective(Node); +} + void StmtPrinter::VisitOMPOrderedDirective(OMPOrderedDirective *Node) { Indent() << "#pragma omp ordered"; PrintOMPExecutableDirective(Node, Node->hasClausesOfKind<OMPDependClause>()); diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 8d43491ea8f4..832eff46a7c0 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -900,6 +900,10 @@ void StmtProfiler::VisitOMPDepobjDirective(const OMPDepobjDirective *S) { VisitOMPExecutableDirective(S); } +void StmtProfiler::VisitOMPScanDirective(const OMPScanDirective *S) { + VisitOMPExecutableDirective(S); +} + void StmtProfiler::VisitOMPOrderedDirective(const OMPOrderedDirective *S) { VisitOMPExecutableDirective(S); } diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index f2106531d6eb..0e27a1652c39 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -608,6 +608,18 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, break; } break; + case OMPD_scan: + if (OpenMPVersion < 50) + return false; + switch (CKind) { +#define OPENMP_SCAN_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; case OMPD_atomic: if (OpenMPVersion < 50 && (CKind == OMPC_acq_rel || CKind == OMPC_acquire || @@ -1251,6 +1263,7 @@ void clang::getOpenMPCaptureRegions( case OMPD_cancel: case OMPD_flush: case OMPD_depobj: + case OMPD_scan: case OMPD_declare_reduction: case OMPD_declare_mapper: case OMPD_declare_simd: diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index c4e4578c4b04..b00027586767 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -6992,6 +6992,7 @@ emitNumTeamsForTargetDirective(CodeGenFunction &CGF, case OMPD_atomic: case OMPD_flush: case OMPD_depobj: + case OMPD_scan: case OMPD_teams: case OMPD_target_data: case OMPD_target_exit_data: @@ -7304,6 +7305,7 @@ emitNumThreadsForTargetDirective(CodeGenFunction &CGF, case OMPD_atomic: case OMPD_flush: case OMPD_depobj: + case OMPD_scan: case OMPD_teams: case OMPD_target_data: case OMPD_target_exit_data: @@ -9089,6 +9091,7 @@ getNestedDistributeDirective(ASTContext &Ctx, const OMPExecutableDirective &D) { case OMPD_atomic: case OMPD_flush: case OMPD_depobj: + case OMPD_scan: case OMPD_teams: case OMPD_target_data: case OMPD_target_exit_data: @@ -9867,6 +9870,7 @@ void CGOpenMPRuntime::scanForTargetRegionsFunctions(const Stmt *S, case OMPD_atomic: case OMPD_flush: case OMPD_depobj: + case OMPD_scan: case OMPD_teams: case OMPD_target_data: case OMPD_target_exit_data: @@ -10508,6 +10512,7 @@ void CGOpenMPRuntime::emitTargetDataStandAloneCall( case OMPD_atomic: case OMPD_flush: case OMPD_depobj: + case OMPD_scan: case OMPD_teams: case OMPD_target_data: case OMPD_distribute: diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp index b139529d8eb3..4b5c85541a7a 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp @@ -787,6 +787,7 @@ static bool hasNestedSPMDDirective(ASTContext &Ctx, case OMPD_atomic: case OMPD_flush: case OMPD_depobj: + case OMPD_scan: case OMPD_teams: case OMPD_target_data: case OMPD_target_exit_data: @@ -864,6 +865,7 @@ static bool supportsSPMDExecutionMode(ASTContext &Ctx, case OMPD_atomic: case OMPD_flush: case OMPD_depobj: + case OMPD_scan: case OMPD_teams: case OMPD_target_data: case OMPD_target_exit_data: @@ -1034,6 +1036,7 @@ static bool hasNestedLightweightDirective(ASTContext &Ctx, case OMPD_atomic: case OMPD_flush: case OMPD_depobj: + case OMPD_scan: case OMPD_teams: case OMPD_target_data: case OMPD_target_exit_data: @@ -1117,6 +1120,7 @@ static bool supportsLightweightRuntime(ASTContext &Ctx, case OMPD_atomic: case OMPD_flush: case OMPD_depobj: + case OMPD_scan: case OMPD_teams: case OMPD_target_data: case OMPD_target_exit_data: diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 49f1725ed470..85c3bcca0647 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -250,6 +250,9 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs) { case Stmt::OMPDepobjDirectiveClass: EmitOMPDepobjDirective(cast<OMPDepobjDirective>(*S)); break; + case Stmt::OMPScanDirectiveClass: + llvm_unreachable("Scan directive not supported yet."); + break; case Stmt::OMPOrderedDirectiveClass: EmitOMPOrderedDirective(cast<OMPOrderedDirective>(*S)); break; diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 6f6de47aa0bb..c5026f7eda14 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -1843,6 +1843,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( case OMPD_taskgroup: case OMPD_flush: case OMPD_depobj: + case OMPD_scan: case OMPD_for: case OMPD_for_simd: case OMPD_sections: @@ -2066,6 +2067,7 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { } case OMPD_flush: case OMPD_depobj: + case OMPD_scan: case OMPD_taskyield: case OMPD_barrier: case OMPD_taskwait: diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index 5c9844e1cd28..6eb5b71248ab 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -1439,6 +1439,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) { case Stmt::OMPDistributeSimdDirectiveClass: case Stmt::OMPFlushDirectiveClass: case Stmt::OMPDepobjDirectiveClass: + case Stmt::OMPScanDirectiveClass: case Stmt::OMPForDirectiveClass: case Stmt::OMPForSimdDirectiveClass: case Stmt::OMPMasterDirectiveClass: diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 7d0821829daa..777cc5447545 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -3858,6 +3858,7 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { case OMPD_cancel: case OMPD_flush: case OMPD_depobj: + case OMPD_scan: case OMPD_declare_reduction: case OMPD_declare_mapper: case OMPD_declare_simd: @@ -4202,12 +4203,14 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, ShouldBeInParallelRegion, ShouldBeInOrderedRegion, ShouldBeInTargetRegion, - ShouldBeInTeamsRegion + ShouldBeInTeamsRegion, + ShouldBeInLoopSimdRegion, } Recommend = NoRecommend; if (isOpenMPSimdDirective(ParentRegion) && ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && - CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic))) { + CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic && + CurrentRegion != OMPD_scan))) { // OpenMP [2.16, Nesting of Regions] // OpenMP constructs may not be nested inside a simd region. // OpenMP [2.8.1,simd Construct, Restrictions] @@ -4366,6 +4369,16 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, ParentRegion != OMPD_target); OrphanSeen = ParentRegion == OMPD_unknown; Recommend = ShouldBeInTargetRegion; + } else if (CurrentRegion == OMPD_scan) { + // OpenMP [2.16, Nesting of Regions] + // If specified, a teams construct must be contained within a target + // construct. + NestingProhibited = + SemaRef.LangOpts.OpenMP < 50 || + (ParentRegion != OMPD_simd && ParentRegion != OMPD_for && + ParentRegion != OMPD_for_simd); + OrphanSeen = ParentRegion == OMPD_unknown; + Recommend = ShouldBeInLoopSimdRegion; } if (!NestingProhibited && !isOpenMPTargetExecutionDirective(CurrentRegion) && @@ -4874,6 +4887,11 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( "No associated statement allowed for 'omp depobj' directive"); Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc); break; + case OMPD_scan: + assert(AStmt == nullptr && + "No associated statement allowed for 'omp scan' directive"); + Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc); + break; case OMPD_ordered: Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); @@ -8773,6 +8791,12 @@ StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); } +StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, + SourceLocation StartLoc, + SourceLocation EndLoc) { + return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); +} + StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, @@ -11251,6 +11275,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_cancellation_point: case OMPD_flush: case OMPD_depobj: + case OMPD_scan: case OMPD_declare_reduction: case OMPD_declare_mapper: case OMPD_declare_simd: @@ -11322,6 +11347,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_cancellation_point: case OMPD_flush: case OMPD_depobj: + case OMPD_scan: case OMPD_declare_reduction: case OMPD_declare_mapper: case OMPD_declare_simd: @@ -11398,6 +11424,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_cancellation_point: case OMPD_flush: case OMPD_depobj: + case OMPD_scan: case OMPD_declare_reduction: case OMPD_declare_mapper: case OMPD_declare_simd: @@ -11471,6 +11498,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_cancellation_point: case OMPD_flush: case OMPD_depobj: + case OMPD_scan: case OMPD_declare_reduction: case OMPD_declare_mapper: case OMPD_declare_simd: @@ -11545,6 +11573,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_cancellation_point: case OMPD_flush: case OMPD_depobj: + case OMPD_scan: case OMPD_declare_reduction: case OMPD_declare_mapper: case OMPD_declare_simd: @@ -11618,6 +11647,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_cancellation_point: case OMPD_flush: case OMPD_depobj: + case OMPD_scan: case OMPD_declare_reduction: case OMPD_declare_mapper: case OMPD_declare_simd: @@ -11690,6 +11720,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_cancellation_point: case OMPD_flush: case OMPD_depobj: + case OMPD_scan: case OMPD_declare_reduction: case OMPD_declare_mapper: case OMPD_declare_simd: @@ -11765,6 +11796,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_cancellation_point: case OMPD_flush: case OMPD_depobj: + case OMPD_scan: case OMPD_declare_reduction: case OMPD_declare_mapper: case OMPD_declare_simd: diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 9186ef0deb2a..8d0c466edec3 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -8303,6 +8303,17 @@ TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) { return Res; } +template <typename Derived> +StmtResult +TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) { + DeclarationNameInfo DirName; + getDerived().getSema().StartOpenMPDSABlock(OMPD_scan, DirName, nullptr, + D->getBeginLoc()); + StmtResult Res = getDerived().TransformOMPExecutableDirective(D); + getDerived().getSema().EndOpenMPDSABlock(Res.get()); + return Res; +} + template <typename Derived> StmtResult TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) { diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 1fbcab209303..c0ed123826eb 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -2377,6 +2377,13 @@ void ASTStmtReader::VisitOMPDepobjDirective(OMPDepobjDirective *D) { VisitOMPExecutableDirective(D); } +void ASTStmtReader::VisitOMPScanDirective(OMPScanDirective *D) { + VisitStmt(D); + // The NumClauses field was read in ReadStmtFromStream. + Record.skipInts(1); + VisitOMPExecutableDirective(D); +} + void ASTStmtReader::VisitOMPOrderedDirective(OMPOrderedDirective *D) { VisitStmt(D); // The NumClauses field was read in ReadStmtFromStream. @@ -3213,6 +3220,11 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { Context, Record[ASTStmtReader::NumStmtFields], Empty); break; + case STMT_OMP_SCAN_DIRECTIVE: + S = OMPScanDirective::CreateEmpty( + Context, Record[ASTStmtReader::NumStmtFields], Empty); + break; + case STMT_OMP_ORDERED_DIRECTIVE: S = OMPOrderedDirective::CreateEmpty( Context, Record[ASTStmtReader::NumStmtFields], Empty); diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index b25b2df8783a..41f8bb8c4d36 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -2330,6 +2330,13 @@ void ASTStmtWriter::VisitOMPDepobjDirective(OMPDepobjDirective *D) { Code = serialization::STMT_OMP_DEPOBJ_DIRECTIVE; } +void ASTStmtWriter::VisitOMPScanDirective(OMPScanDirective *D) { + VisitStmt(D); + Record.push_back(D->getNumClauses()); + VisitOMPExecutableDirective(D); + Code = serialization::STMT_OMP_SCAN_DIRECTIVE; +} + void ASTStmtWriter::VisitOMPOrderedDirective(OMPOrderedDirective *D) { VisitStmt(D); Record.push_back(D->getNumClauses()); diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 1b13c49713ba..1bdf7f170f8b 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1258,6 +1258,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::OMPTaskgroupDirectiveClass: case Stmt::OMPFlushDirectiveClass: case Stmt::OMPDepobjDirectiveClass: + case Stmt::OMPScanDirectiveClass: case Stmt::OMPOrderedDirectiveClass: case Stmt::OMPAtomicDirectiveClass: case Stmt::OMPTargetDirectiveClass: diff --git a/clang/test/OpenMP/nesting_of_regions.cpp b/clang/test/OpenMP/nesting_of_regions.cpp index 53656a2e669f..4ecfac6f0777 100644 --- a/clang/test/OpenMP/nesting_of_regions.cpp +++ b/clang/test/OpenMP/nesting_of_regions.cpp @@ -84,6 +84,11 @@ void foo() { } #pragma omp parallel { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp parallel + { #pragma omp taskwait bar(); } @@ -230,7 +235,7 @@ void foo() { // SIMD DIRECTIVE #pragma omp simd for (int i = 0; i < 10; ++i) { -#pragma omp for // expected-error {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp for // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{OpenMP constructs may not be nested inside a simd region except for ordered simd, simd, scan, or atomic directive}} for (int i = 0; i < 10; ++i) ; } @@ -332,6 +337,11 @@ 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}} + bar(); + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} bar(); } @@ -608,6 +618,11 @@ 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?}} + bar(); + } +#pragma omp for + for (int i = 0; i < 10; ++i) { #pragma omp taskwait bar(); } @@ -861,6 +876,11 @@ 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}} + bar(); + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} bar(); } @@ -1152,6 +1172,10 @@ void foo() { } #pragma omp sections { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'sections' region}} + } +#pragma omp sections + { #pragma omp taskwait } #pragma omp sections @@ -1455,6 +1479,14 @@ void foo() { { #pragma omp section { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'section' region}} + bar(); + } + } +#pragma omp sections + { +#pragma omp section + { #pragma omp taskwait bar(); } @@ -1755,6 +1787,11 @@ void foo() { } #pragma omp single { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'single' region}} + bar(); + } +#pragma omp single + { #pragma omp taskwait bar(); } @@ -2030,6 +2067,11 @@ void foo() { } #pragma omp master { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'master' region}} + bar(); + } +#pragma omp master + { #pragma omp taskwait bar(); } @@ -2292,6 +2334,11 @@ void foo() { } #pragma omp critical { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'critical' region}} + bar(); + } +#pragma omp critical + { #pragma omp taskwait bar(); } @@ -2571,6 +2618,11 @@ void foo() { } #pragma omp parallel for for (int i = 0; i < 10; ++i) { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'parallel for' region}} + bar(); + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { #pragma omp taskwait bar(); } @@ -2840,6 +2892,11 @@ void foo() { } #pragma omp parallel for simd for (int i = 0; i < 10; ++i) { +#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{region cannot be closely nested inside 'parallel for simd' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} bar(); } @@ -3120,6 +3177,11 @@ void foo() { } #pragma omp parallel master { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'parallel master' region}} + bar(); + } +#pragma omp parallel master + { #pragma omp taskwait bar(); } @@ -3383,6 +3445,10 @@ void foo() { } #pragma omp parallel sections { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'parallel sections' region}} + } +#pragma omp parallel sections + { #pragma omp taskwait } #pragma omp parallel sections @@ -3585,6 +3651,11 @@ void foo() { } #pragma omp task { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'task' region}} + bar(); + } +#pragma omp task + { #pragma omp taskwait bar(); } @@ -3848,6 +3919,11 @@ void foo() { } #pragma omp ordered { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'ordered' region}} + bar(); + } +#pragma omp ordered + { #pragma omp taskwait bar(); } @@ -4142,6 +4218,13 @@ void foo() { // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} // expected-note@+1 {{expected an expression statement}} { +#pragma omp scan // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + bar(); + } +#pragma omp atomic + // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + { #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside an atomic region}} bar(); } @@ -4406,6 +4489,11 @@ void foo() { } #pragma omp target { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'target' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target + { #pragma omp taskwait bar(); } @@ -4640,6 +4728,11 @@ void foo() { } #pragma omp target parallel { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target parallel + { #pragma omp taskwait bar(); } @@ -4906,6 +4999,11 @@ void foo() { } #pragma omp target parallel for for (int i = 0; i < 10; ++i) { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'target parallel for' region}} + bar(); + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { #pragma omp taskwait bar(); } @@ -5140,6 +5238,12 @@ void foo() { bar(); } #pragma omp target +#pragma omp teams + { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target #pragma omp teams { #pragma omp taskwait // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp taskwait' directive into a parallel region?}} @@ -5439,6 +5543,11 @@ void foo() { } #pragma omp taskloop for (int i = 0; i < 10; ++i) { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'taskloop' region}} + bar(); + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { #pragma omp taskwait bar(); } @@ -5761,6 +5870,13 @@ void foo() { } #pragma omp target #pragma omp teams +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'distribute' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target +#pragma omp teams #pragma omp distribute for (int i = 0; i < 10; ++i) { #pragma omp taskwait @@ -6073,6 +6189,13 @@ void foo() { } #pragma omp target #pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'distribute parallel for' region}} + bar(); + } +#pragma omp target +#pragma omp teams #pragma omp distribute parallel for for (int i = 0; i < 10; ++i) { #pragma omp taskwait @@ -6385,6 +6508,13 @@ void foo() { } #pragma omp target #pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{region cannot be closely nested inside 'distribute parallel for simd' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target +#pragma omp teams #pragma omp distribute parallel for simd for (int i = 0; i < 10; ++i) { #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} @@ -6669,6 +6799,11 @@ void foo() { } #pragma omp target simd for (int i = 0; i < 10; ++i) { +#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{region cannot be closely nested inside 'target simd' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target simd + for (int i = 0; i < 10; ++i) { #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} bar(); } @@ -6912,6 +7047,12 @@ void foo() { bar(); } #pragma omp target +#pragma omp teams distribute + for (int i = 0; i < 10; ++i) { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'teams distribute' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target #pragma omp teams distribute for (int i = 0; i < 10; ++i) { #pragma omp taskwait // OK @@ -7175,6 +7316,12 @@ void foo() { bar(); } #pragma omp target +#pragma omp teams distribute + for (int i = 0; i < 10; ++i) { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'teams distribute' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target #pragma omp teams distribute for (int i = 0; i < 10; ++i) { #pragma omp taskwait // OK @@ -7458,6 +7605,12 @@ void foo() { bar(); } #pragma omp target +#pragma omp teams distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{region cannot be closely nested inside 'teams distribute simd' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target #pragma omp teams distribute simd for (int i = 0; i < 10; ++i) { #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} @@ -7741,6 +7894,12 @@ void foo() { bar(); } #pragma omp target +#pragma omp teams distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{region cannot be closely nested inside 'teams distribute parallel for simd' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target #pragma omp teams distribute parallel for simd for (int i = 0; i < 10; ++i) { #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} @@ -8024,6 +8183,12 @@ void foo() { bar(); } #pragma omp target +#pragma omp teams distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'teams distribute parallel for' region}} + bar(); + } +#pragma omp target #pragma omp teams distribute parallel for for (int i = 0; i < 10; ++i) { #pragma omp taskwait // OK @@ -8237,6 +8402,11 @@ void foo() { } #pragma omp target teams { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target teams + { #pragma omp taskwait // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp taskwait' directive into a parallel region?}} bar(); } @@ -8511,6 +8681,11 @@ void foo() { } #pragma omp target teams distribute for (int i = 0; i < 10; ++i) { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'target teams distribute' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target teams distribute + for (int i = 0; i < 10; ++i) { #pragma omp taskwait // OK bar(); } @@ -8754,6 +8929,11 @@ void foo() { } #pragma omp target teams distribute parallel for for (int i = 0; i < 10; ++i) { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region}} + bar(); + } +#pragma omp target teams distribute parallel for + for (int i = 0; i < 10; ++i) { #pragma omp taskwait // OK bar(); } @@ -8997,6 +9177,11 @@ void foo() { } #pragma omp target teams distribute parallel for simd for (int i = 0; i < 10; ++i) { +#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{region cannot be closely nested inside 'target teams distribute parallel for simd' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target teams distribute parallel for simd + for (int i = 0; i < 10; ++i) { #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} bar(); } @@ -9240,6 +9425,11 @@ void foo() { } #pragma omp target teams distribute simd for (int i = 0; i < 10; ++i) { +#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{region cannot be closely nested inside 'target teams distribute simd' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target teams distribute simd + for (int i = 0; i < 10; ++i) { #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} bar(); } @@ -9433,6 +9623,11 @@ void foo() { } #pragma omp parallel { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp parallel + { #pragma omp taskwait bar(); } @@ -9666,6 +9861,11 @@ 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}} + bar(); + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} bar(); } @@ -9916,6 +10116,11 @@ 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}} + bar(); + } +#pragma omp for + for (int i = 0; i < 10; ++i) { #pragma omp taskwait bar(); } @@ -10156,6 +10361,11 @@ 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}} + bar(); + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} bar(); } @@ -10405,6 +10615,11 @@ void foo() { } #pragma omp sections { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'sections' region}} + bar(); + } +#pragma omp sections + { #pragma omp taskwait } #pragma omp sections @@ -10698,6 +10913,14 @@ void foo() { { #pragma omp section { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'section' region}} + bar(); + } + } +#pragma omp sections + { +#pragma omp section + { #pragma omp taskwait bar(); } @@ -10991,6 +11214,11 @@ void foo() { } #pragma omp single { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'single' region}} + bar(); + } +#pragma omp single + { #pragma omp taskwait bar(); } @@ -11258,6 +11486,11 @@ void foo() { } #pragma omp master { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'master' region}} + bar(); + } +#pragma omp master + { #pragma omp taskwait bar(); } @@ -11513,6 +11746,11 @@ void foo() { } #pragma omp critical { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'critical' region}} + bar(); + } +#pragma omp critical + { #pragma omp taskwait bar(); } @@ -11797,6 +12035,11 @@ void foo() { } #pragma omp parallel for for (int i = 0; i < 10; ++i) { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'parallel for' region}} + bar(); + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { #pragma omp taskwait bar(); } @@ -12067,6 +12310,11 @@ void foo() { } #pragma omp parallel for simd for (int i = 0; i < 10; ++i) { +#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{region cannot be closely nested inside 'parallel for simd' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} bar(); } @@ -12331,6 +12579,10 @@ void foo() { } #pragma omp parallel sections { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'parallel sections' region}} + } +#pragma omp parallel sections + { #pragma omp taskwait } #pragma omp parallel sections @@ -12532,6 +12784,11 @@ void foo() { } #pragma omp task { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'task' region}} + bar(); + } +#pragma omp task + { #pragma omp taskwait bar(); } @@ -12804,6 +13061,13 @@ void foo() { // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} // expected-note@+1 {{expected an expression statement}} { +#pragma omp scan // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + bar(); + } +#pragma omp atomic + // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + { #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside an atomic region}} bar(); } @@ -13067,6 +13331,11 @@ void foo() { } #pragma omp target { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'target' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target + { #pragma omp taskwait bar(); } @@ -13292,6 +13561,11 @@ void foo() { } #pragma omp target parallel { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target parallel + { #pragma omp taskwait bar(); } @@ -13558,6 +13832,11 @@ void foo() { } #pragma omp target parallel for for (int i = 0; i < 10; ++i) { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'target parallel for' region}} + bar(); + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { #pragma omp taskwait bar(); } @@ -13791,6 +14070,12 @@ void foo() { bar(); } #pragma omp target +#pragma omp teams + { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target #pragma omp teams { #pragma omp taskwait // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp taskwait' directive into a parallel region?}} @@ -14094,6 +14379,11 @@ void foo() { } #pragma omp taskloop for (int i = 0; i < 10; ++i) { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'taskloop' region}} + bar(); + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { #pragma omp taskwait bar(); } @@ -14386,6 +14676,13 @@ void foo() { } #pragma omp target #pragma omp teams +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'distribute' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target +#pragma omp teams #pragma omp distribute for (int i = 0; i < 10; ++i) { #pragma omp taskwait @@ -14708,6 +15005,13 @@ void foo() { } #pragma omp target #pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'distribute parallel for' region}} + bar(); + } +#pragma omp target +#pragma omp teams #pragma omp distribute parallel for for (int i = 0; i < 10; ++i) { #pragma omp taskwait @@ -15028,6 +15332,13 @@ void foo() { } #pragma omp target #pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{region cannot be closely nested inside 'distribute parallel for simd' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target +#pragma omp teams #pragma omp distribute parallel for simd for (int i = 0; i < 10; ++i) { #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} @@ -15340,6 +15651,13 @@ void foo() { } #pragma omp target #pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{region cannot be closely nested inside 'distribute simd' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target +#pragma omp teams #pragma omp distribute simd for (int i = 0; i < 10; ++i) { #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} @@ -15616,6 +15934,11 @@ void foo() { } #pragma omp target simd for (int i = 0; i < 10; ++i) { +#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{region cannot be closely nested inside 'target simd' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target simd + for (int i = 0; i < 10; ++i) { #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} bar(); } @@ -15870,6 +16193,12 @@ void foo() { bar(); } #pragma omp target +#pragma omp teams distribute + for (int i = 0; i < 10; ++i) { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'teams distribute' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target #pragma omp teams distribute for (int i = 0; i < 10; ++i) { #pragma omp taskwait // OK @@ -16153,6 +16482,12 @@ void foo() { bar(); } #pragma omp target +#pragma omp teams distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{region cannot be closely nested inside 'teams distribute simd' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target #pragma omp teams distribute simd for (int i = 0; i < 10; ++i) { #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} @@ -16436,6 +16771,12 @@ void foo() { bar(); } #pragma omp target +#pragma omp teams distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{region cannot be closely nested inside 'teams distribute parallel for simd' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target #pragma omp teams distribute parallel for simd for (int i = 0; i < 10; ++i) { #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} @@ -16719,6 +17060,12 @@ void foo() { bar(); } #pragma omp target +#pragma omp teams distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'teams distribute parallel for' region}} + bar(); + } +#pragma omp target #pragma omp teams distribute parallel for for (int i = 0; i < 10; ++i) { #pragma omp taskwait // OK @@ -16932,6 +17279,11 @@ void foo() { } #pragma omp target teams { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target teams + { #pragma omp taskwait // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp taskwait' directive into a parallel region?}} bar(); } @@ -17206,6 +17558,11 @@ void foo() { } #pragma omp target teams distribute for (int i = 0; i < 10; ++i) { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'target teams distribute' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target teams distribute + for (int i = 0; i < 10; ++i) { #pragma omp taskwait // OK bar(); } @@ -17449,6 +17806,11 @@ void foo() { } #pragma omp target teams distribute parallel for for (int i = 0; i < 10; ++i) { +#pragma omp scan // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region}} + bar(); + } +#pragma omp target teams distribute parallel for + for (int i = 0; i < 10; ++i) { #pragma omp taskwait // OK bar(); } @@ -17692,6 +18054,11 @@ void foo() { } #pragma omp target teams distribute parallel for simd for (int i = 0; i < 10; ++i) { +#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{region cannot be closely nested inside 'target teams distribute parallel for simd' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target teams distribute parallel for simd + for (int i = 0; i < 10; ++i) { #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} bar(); } @@ -17935,6 +18302,11 @@ void foo() { } #pragma omp target teams distribute simd for (int i = 0; i < 10; ++i) { +#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{region cannot be closely nested inside 'target teams distribute simd' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, or for simd region?}} + bar(); + } +#pragma omp target teams distribute simd + for (int i = 0; i < 10; ++i) { #pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} bar(); } diff --git a/clang/test/OpenMP/scan_ast_print.cpp b/clang/test/OpenMP/scan_ast_print.cpp new file mode 100644 index 000000000000..042605d8a508 --- /dev/null +++ b/clang/test/OpenMP/scan_ast_print.cpp @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +void foo() {} + +template <class T> +T tmain(T argc) { + static T a; +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp scan + } + 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: static int a; +// CHECK-NEXT: #pragma omp for +// CHECK-NEXT: for (int i = 0; i < 10; ++i) { +// CHECK-NEXT: #pragma omp scan +// CHECK: static char a; +// CHECK-NEXT: #pragma omp for +// CHECK-NEXT: for (int i = 0; i < 10; ++i) { +// CHECK-NEXT: #pragma omp scan + +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 + } +// CHECK-NEXT: #pragma omp for simd +// CHECK-NEXT: for (int i = 0; i < 10; ++i) { +// CHECK-NEXT: #pragma omp scan{{$}} + return tmain(argc) + tmain(argv[0][0]) + a; +} + +#endif diff --git a/clang/test/OpenMP/scan_messages.cpp b/clang/test/OpenMP/scan_messages.cpp new file mode 100644 index 000000000000..4533b9aed10d --- /dev/null +++ b/clang/test/OpenMP/scan_messages.cpp @@ -0,0 +1,164 @@ +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -ferror-limit 100 %s + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 -ferror-limit 100 %s + +template <class T> +T tmain(T argc) { +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp scan + ; + } +#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 for simd + for (int i = 0; i < 10; ++i) + if (argc) +#pragma omp scan // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} + if (argc) { +#pragma omp scan + } +#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}} + while (argc) { +#pragma omp scan + } +#pragma omp simd + for (int i = 0; i < 10; ++i) + do +#pragma omp scan // 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 + } 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}} + switch (argc) + case 1: +#pragma omp scan // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} + switch (argc) + case 1: { +#pragma omp scan + } +#pragma omp simd + for (int i = 0; i < 10; ++i) + switch (argc) { +#pragma omp scan + case 1: +#pragma omp scan + break; + default: { +#pragma omp scan + } 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}} + for (;;) { +#pragma omp scan + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +label: +#pragma omp scan + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +label1 : { +#pragma omp scan +}} + + return T(); +} + +int main(int argc, char **argv) { +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp scan + ; + } +#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 simd + for (int i = 0; i < 10; ++i) + if (argc) +#pragma omp scan // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} + if (argc) { +#pragma omp scan + } +#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}} + while (argc) { +#pragma omp scan + } +#pragma omp simd + for (int i = 0; i < 10; ++i) + do +#pragma omp scan // 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 + } 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}} + switch (argc) + case 1: +#pragma omp scan // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} + switch (argc) + case 1: { +#pragma omp scan + } +#pragma omp simd + for (int i = 0; i < 10; ++i) + switch (argc) { +#pragma omp scan + case 1: +#pragma omp scan + break; + default: { +#pragma omp scan + } 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}} + for (;;) { +#pragma omp scan + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +label: +#pragma omp scan + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +label1 : { +#pragma omp scan +} +} + + return tmain(argc); +} diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index df5530c73c6d..e4727c86fafe 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -2048,6 +2048,7 @@ class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> { void VisitOMPCancelDirective(const OMPCancelDirective *D); void VisitOMPFlushDirective(const OMPFlushDirective *D); void VisitOMPDepobjDirective(const OMPDepobjDirective *D); + void VisitOMPScanDirective(const OMPScanDirective *D); void VisitOMPOrderedDirective(const OMPOrderedDirective *D); void VisitOMPAtomicDirective(const OMPAtomicDirective *D); void VisitOMPTargetDirective(const OMPTargetDirective *D); @@ -2885,6 +2886,10 @@ void EnqueueVisitor::VisitOMPDepobjDirective(const OMPDepobjDirective *D) { VisitOMPExecutableDirective(D); } +void EnqueueVisitor::VisitOMPScanDirective(const OMPScanDirective *D) { + VisitOMPExecutableDirective(D); +} + void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) { VisitOMPExecutableDirective(D); } @@ -5519,6 +5524,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { return cxstring::createRef("OMPFlushDirective"); case CXCursor_OMPDepobjDirective: return cxstring::createRef("OMPDepobjDirective"); + case CXCursor_OMPScanDirective: + return cxstring::createRef("OMPScanDirective"); case CXCursor_OMPOrderedDirective: return cxstring::createRef("OMPOrderedDirective"); case CXCursor_OMPAtomicDirective: diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp index e10c742c65ea..5e857def4c91 100644 --- a/clang/tools/libclang/CXCursor.cpp +++ b/clang/tools/libclang/CXCursor.cpp @@ -638,6 +638,9 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent, case Stmt::OMPDepobjDirectiveClass: K = CXCursor_OMPDepobjDirective; break; + case Stmt::OMPScanDirectiveClass: + K = CXCursor_OMPScanDirective; + break; case Stmt::OMPOrderedDirectiveClass: K = CXCursor_OMPOrderedDirective; break; diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def index 20e5b95a827a..d37c3911edf2 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def +++ b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def @@ -92,6 +92,7 @@ __OMP_DIRECTIVE_EXT(master_taskloop_simd, "master taskloop simd") __OMP_DIRECTIVE_EXT(parallel_master_taskloop_simd, "parallel master taskloop simd") __OMP_DIRECTIVE(depobj) +__OMP_DIRECTIVE(scan) // Has to be the last because Clang implicitly expects it to be. __OMP_DIRECTIVE(unknown) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits