[clang] fcba7c3 - [OPENMP50]Initial support for scan directive.
Alexey Bataev via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 20 05:28:49 PDT 2020
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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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)
More information about the cfe-commits
mailing list