summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/AST/DataRecursiveASTVisitor.h5
-rw-r--r--clang/include/clang/AST/OpenMPClause.h30
-rw-r--r--clang/include/clang/AST/RecursiveASTVisitor.h5
-rw-r--r--clang/include/clang/Basic/OpenMPKinds.def2
-rw-r--r--clang/include/clang/Sema/Sema.h5
-rw-r--r--clang/lib/AST/StmtPrinter.cpp2
-rw-r--r--clang/lib/AST/StmtProfile.cpp2
-rw-r--r--clang/lib/Basic/OpenMPKinds.cpp2
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp1
-rw-r--r--clang/lib/Parse/ParseOpenMP.cpp6
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp39
-rw-r--r--clang/lib/Sema/TreeTransform.h6
-rw-r--r--clang/lib/Serialization/ASTReaderStmt.cpp5
-rw-r--r--clang/lib/Serialization/ASTWriterStmt.cpp2
-rw-r--r--clang/test/OpenMP/ordered_ast_print.cpp90
-rw-r--r--clang/test/OpenMP/ordered_messages.cpp92
-rw-r--r--clang/tools/libclang/CIndex.cpp2
17 files changed, 289 insertions, 7 deletions
diff --git a/clang/include/clang/AST/DataRecursiveASTVisitor.h b/clang/include/clang/AST/DataRecursiveASTVisitor.h
index 79203b9117a..12ba21645a2 100644
--- a/clang/include/clang/AST/DataRecursiveASTVisitor.h
+++ b/clang/include/clang/AST/DataRecursiveASTVisitor.h
@@ -2540,6 +2540,11 @@ bool RecursiveASTVisitor<Derived>::VisitOMPThreadsClause(OMPThreadsClause *) {
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPSIMDClause(OMPSIMDClause *) {
+ return true;
+}
+
+template <typename Derived>
template <typename T>
bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
for (auto *E : Node->varlists()) {
diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h
index a0736db8b7c..1f807a5bb94 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -2561,6 +2561,36 @@ public:
}
};
+/// \brief This represents 'simd' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp ordered simd
+/// \endcode
+/// In this example directive '#pragma omp ordered' has simple 'simd' clause.
+///
+class OMPSIMDClause : public OMPClause {
+public:
+ /// \brief Build 'simd' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_simd, StartLoc, EndLoc) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPSIMDClause() : OMPClause(OMPC_simd, SourceLocation(), SourceLocation()) {}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_simd;
+ }
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+};
+
} // end namespace clang
#endif
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index e8125f20e43..e632536ee14 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -2572,6 +2572,11 @@ bool RecursiveASTVisitor<Derived>::VisitOMPThreadsClause(OMPThreadsClause *) {
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPSIMDClause(OMPSIMDClause *) {
+ return true;
+}
+
+template <typename Derived>
template <typename T>
bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
for (auto *E : Node->varlists()) {
diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def
index efc0d42a813..ee99b42ded4 100644
--- a/clang/include/clang/Basic/OpenMPKinds.def
+++ b/clang/include/clang/Basic/OpenMPKinds.def
@@ -145,6 +145,7 @@ OPENMP_CLAUSE(seq_cst, OMPSeqCstClause)
OPENMP_CLAUSE(depend, OMPDependClause)
OPENMP_CLAUSE(device, OMPDeviceClause)
OPENMP_CLAUSE(threads, OMPThreadsClause)
+OPENMP_CLAUSE(simd, OMPSIMDClause)
// Clauses allowed for OpenMP directive 'parallel'.
OPENMP_PARALLEL_CLAUSE(if)
@@ -318,6 +319,7 @@ OPENMP_TEAMS_CLAUSE(reduction)
// Clauses allowed for OpenMP directive 'ordered'.
// TODO More clauses for 'ordered' directive.
OPENMP_ORDERED_CLAUSE(threads)
+OPENMP_ORDERED_CLAUSE(simd)
#undef OPENMP_LINEAR_KIND
#undef OPENMP_DEPEND_KIND
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f166402efa0..09b46ce77b6 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -7997,7 +7997,10 @@ public:
SourceLocation EndLoc);
/// \brief Called on well-formed 'threads' clause.
OMPClause *ActOnOpenMPThreadsClause(SourceLocation StartLoc,
- SourceLocation EndLoc);
+ SourceLocation EndLoc);
+ /// \brief Called on well-formed 'simd' clause.
+ OMPClause *ActOnOpenMPSIMDClause(SourceLocation StartLoc,
+ SourceLocation EndLoc);
OMPClause *ActOnOpenMPVarListClause(
OpenMPClauseKind Kind, ArrayRef<Expr *> Vars, Expr *TailExpr,
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 3ab8acbb1e1..d0603478e6a 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -701,6 +701,8 @@ void OMPClausePrinter::VisitOMPThreadsClause(OMPThreadsClause *) {
OS << "threads";
}
+void OMPClausePrinter::VisitOMPSIMDClause(OMPSIMDClause *) { OS << "simd"; }
+
void OMPClausePrinter::VisitOMPDeviceClause(OMPDeviceClause *Node) {
OS << "device(";
Node->getDevice()->printPretty(OS, nullptr, Policy, 0);
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 874aee1ebec..c807f5e2f9c 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -335,6 +335,8 @@ void OMPClauseProfiler::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
void OMPClauseProfiler::VisitOMPThreadsClause(const OMPThreadsClause *) {}
+void OMPClauseProfiler::VisitOMPSIMDClause(const OMPSIMDClause *) {}
+
template<typename T>
void OMPClauseProfiler::VisitOMPClauseList(T *Node) {
for (auto *E : Node->varlists()) {
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index ea99387cb94..28194680b23 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -129,6 +129,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
case OMPC_seq_cst:
case OMPC_device:
case OMPC_threads:
+ case OMPC_simd:
break;
}
llvm_unreachable("Invalid OpenMP simple clause kind");
@@ -214,6 +215,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
case OMPC_seq_cst:
case OMPC_device:
case OMPC_threads:
+ case OMPC_simd:
break;
}
llvm_unreachable("Invalid OpenMP simple clause kind");
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 341ccaad542..a06b0a24925 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -2210,6 +2210,7 @@ static void EmitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
case OMPC_mergeable:
case OMPC_device:
case OMPC_threads:
+ case OMPC_simd:
llvm_unreachable("Clause is not allowed in 'omp atomic'.");
}
}
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 5f32c63cf30..37eeabae10a 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -394,7 +394,7 @@ bool Parser::ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind,
/// schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
/// mergeable-clause | flush-clause | read-clause | write-clause |
/// update-clause | capture-clause | seq_cst-clause | device-clause |
-/// simdlen-clause | threads-clause
+/// simdlen-clause | threads-clause | simd-clause
///
OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
OpenMPClauseKind CKind, bool FirstClause) {
@@ -473,6 +473,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
case OMPC_capture:
case OMPC_seq_cst:
case OMPC_threads:
+ case OMPC_simd:
// OpenMP [2.7.1, Restrictions, p. 9]
// Only one ordered clause can appear on a loop directive.
// OpenMP [2.7.1, Restrictions, C/C++, p. 4]
@@ -605,6 +606,9 @@ OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) {
/// threads-clause:
/// 'threads'
///
+/// simd-clause:
+/// 'simd'
+///
OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind) {
SourceLocation Loc = Tok.getLocation();
ConsumeAnyToken();
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 9045724aa2b..44096860d6d 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -1547,7 +1547,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | simd | taskwait | |
// | simd | taskgroup | |
// | simd | flush | |
- // | simd | ordered | |
+ // | simd | ordered | + (with simd clause) |
// | simd | atomic | |
// | simd | target | |
// | simd | teams | |
@@ -1573,7 +1573,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | for simd | taskwait | |
// | for simd | taskgroup | |
// | for simd | flush | |
- // | for simd | ordered | |
+ // | for simd | ordered | + (with simd clause) |
// | for simd | atomic | |
// | for simd | target | |
// | for simd | teams | |
@@ -1599,7 +1599,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | parallel for simd| taskwait | |
// | parallel for simd| taskgroup | |
// | parallel for simd| flush | |
- // | parallel for simd| ordered | |
+ // | parallel for simd| ordered | + (with simd clause) |
// | parallel for simd| atomic | |
// | parallel for simd| target | |
// | parallel for simd| teams | |
@@ -1877,9 +1877,12 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
ShouldBeInOrderedRegion,
ShouldBeInTargetRegion
} Recommend = NoRecommend;
- if (isOpenMPSimdDirective(ParentRegion)) {
+ if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) {
// OpenMP [2.16, Nesting of Regions]
// OpenMP constructs may not be nested inside a simd region.
+ // OpenMP [2.8.1,simd Construct, Restrictions]
+ // An ordered construct with the simd clause is the only OpenMP construct
+ // that can appear in the simd region.
SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_simd);
return true;
}
@@ -1987,9 +1990,13 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// atomic, or explicit task region.
// An ordered region must be closely nested inside a loop region (or
// parallel loop region) with an ordered clause.
+ // OpenMP [2.8.1,simd Construct, Restrictions]
+ // An ordered construct with the simd clause is the only OpenMP construct
+ // that can appear in the simd region.
NestingProhibited = ParentRegion == OMPD_critical ||
ParentRegion == OMPD_task ||
- !Stack->isParentOrderedRegion();
+ !(isOpenMPSimdDirective(ParentRegion) ||
+ Stack->isParentOrderedRegion());
Recommend = ShouldBeInOrderedRegion;
} else if (isOpenMPTeamsDirective(CurrentRegion)) {
// OpenMP [2.16, Nesting of Regions]
@@ -4146,9 +4153,12 @@ StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
getCurFunction()->setHasBranchProtectedScope();
OMPThreadsClause *TC = nullptr;
+ OMPSIMDClause *SC = nullptr;
for (auto *C: Clauses) {
if (C->getClauseKind() == OMPC_threads)
TC = cast<OMPThreadsClause>(C);
+ else if (C->getClauseKind() == OMPC_simd)
+ SC = cast<OMPSIMDClause>(C);
}
// TODO: this must happen only if 'threads' clause specified or if no clauses
@@ -4159,6 +4169,13 @@ StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
Diag(Param->getLocStart(), diag::note_omp_ordered_param);
return StmtError();
}
+ if (!SC && isOpenMPSimdDirective(DSAStack->getParentDirective())) {
+ // OpenMP [2.8.1,simd Construct, Restrictions]
+ // An ordered construct with the simd clause is the only OpenMP construct
+ // that can appear in the simd region.
+ Diag(StartLoc, diag::err_omp_prohibited_region_simd);
+ return StmtError();
+ }
return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
}
@@ -5009,6 +5026,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
case OMPC_seq_cst:
case OMPC_depend:
case OMPC_threads:
+ case OMPC_simd:
case OMPC_unknown:
llvm_unreachable("Clause is not allowed.");
}
@@ -5270,6 +5288,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
case OMPC_depend:
case OMPC_device:
case OMPC_threads:
+ case OMPC_simd:
case OMPC_unknown:
llvm_unreachable("Clause is not allowed.");
}
@@ -5398,6 +5417,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
case OMPC_depend:
case OMPC_device:
case OMPC_threads:
+ case OMPC_simd:
case OMPC_unknown:
llvm_unreachable("Clause is not allowed.");
}
@@ -5504,6 +5524,9 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
case OMPC_threads:
Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
break;
+ case OMPC_simd:
+ Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
+ break;
case OMPC_if:
case OMPC_final:
case OMPC_num_threads:
@@ -5578,6 +5601,11 @@ OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
return new (Context) OMPThreadsClause(StartLoc, EndLoc);
}
+OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
+ SourceLocation EndLoc) {
+ return new (Context) OMPSIMDClause(StartLoc, EndLoc);
+}
+
OMPClause *Sema::ActOnOpenMPVarListClause(
OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
@@ -5644,6 +5672,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
case OMPC_seq_cst:
case OMPC_device:
case OMPC_threads:
+ case OMPC_simd:
case OMPC_unknown:
llvm_unreachable("Clause is not allowed.");
}
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index df998a06fb5..de368ea90ca 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -7373,6 +7373,12 @@ TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
}
template <typename Derived>
+OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
+ // No need to rebuild this clause, no template-dependent parameters.
+ return C;
+}
+
+template <typename Derived>
OMPClause *
TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
llvm::SmallVector<Expr *, 16> Vars;
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 6969823030d..4d55deeaa50 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -1780,6 +1780,9 @@ OMPClause *OMPClauseReader::readClause() {
case OMPC_threads:
C = new (Context) OMPThreadsClause();
break;
+ case OMPC_simd:
+ C = new (Context) OMPSIMDClause();
+ break;
case OMPC_private:
C = OMPPrivateClause::CreateEmpty(Context, Record[Idx++]);
break;
@@ -1904,6 +1907,8 @@ void OMPClauseReader::VisitOMPSeqCstClause(OMPSeqCstClause *) {}
void OMPClauseReader::VisitOMPThreadsClause(OMPThreadsClause *) {}
+void OMPClauseReader::VisitOMPSIMDClause(OMPSIMDClause *) {}
+
void OMPClauseReader::VisitOMPPrivateClause(OMPPrivateClause *C) {
C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
unsigned NumVars = C->varlist_size();
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index 5c86dc1b4f5..33cffaf115e 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -1812,6 +1812,8 @@ void OMPClauseWriter::VisitOMPSeqCstClause(OMPSeqCstClause *) {}
void OMPClauseWriter::VisitOMPThreadsClause(OMPThreadsClause *) {}
+void OMPClauseWriter::VisitOMPSIMDClause(OMPSIMDClause *) {}
+
void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) {
Record.push_back(C->varlist_size());
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
diff --git a/clang/test/OpenMP/ordered_ast_print.cpp b/clang/test/OpenMP/ordered_ast_print.cpp
index f8601c51bad..6328ec0d766 100644
--- a/clang/test/OpenMP/ordered_ast_print.cpp
+++ b/clang/test/OpenMP/ordered_ast_print.cpp
@@ -24,6 +24,24 @@ T tmain (T argc) {
{
a=2;
}
+ #pragma omp simd
+ for (int i =0 ; i < argc; ++i)
+ #pragma omp ordered simd
+ {
+ a=2;
+ }
+ #pragma omp for simd
+ for (int i =0 ; i < argc; ++i)
+ #pragma omp ordered simd
+ {
+ a=2;
+ }
+ #pragma omp parallel for simd
+ for (int i =0 ; i < argc; ++i)
+ #pragma omp ordered simd
+ {
+ a=2;
+ }
return (0);
}
@@ -40,6 +58,24 @@ T tmain (T argc) {
// CHECK-NEXT: {
// CHECK-NEXT: a = 2;
// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp simd
+// CHECK-NEXT: for (int i = 0; i < argc; ++i)
+// CHECK-NEXT: #pragma omp ordered simd
+// CHECK-NEXT: {
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp for simd
+// CHECK-NEXT: for (int i = 0; i < argc; ++i)
+// CHECK-NEXT: #pragma omp ordered simd
+// CHECK-NEXT: {
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp parallel for simd
+// CHECK-NEXT: for (int i = 0; i < argc; ++i)
+// CHECK-NEXT: #pragma omp ordered simd
+// CHECK-NEXT: {
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: }
// CHECK: static T a;
// CHECK-NEXT: #pragma omp for ordered
@@ -54,6 +90,24 @@ T tmain (T argc) {
// CHECK-NEXT: {
// CHECK-NEXT: a = 2;
// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp simd
+// CHECK-NEXT: for (int i = 0; i < argc; ++i)
+// CHECK-NEXT: #pragma omp ordered simd
+// CHECK-NEXT: {
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp for simd
+// CHECK-NEXT: for (int i = 0; i < argc; ++i)
+// CHECK-NEXT: #pragma omp ordered simd
+// CHECK-NEXT: {
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp parallel for simd
+// CHECK-NEXT: for (int i = 0; i < argc; ++i)
+// CHECK-NEXT: #pragma omp ordered simd
+// CHECK-NEXT: {
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: }
int main (int argc, char **argv) {
int b = argc, c, d, e, f, g;
@@ -71,6 +125,24 @@ int main (int argc, char **argv) {
{
a=2;
}
+ #pragma omp simd
+ for (int i =0 ; i < argc; ++i)
+ #pragma omp ordered simd
+ {
+ a=2;
+ }
+ #pragma omp for simd
+ for (int i =0 ; i < argc; ++i)
+ #pragma omp ordered simd
+ {
+ a=2;
+ }
+ #pragma omp parallel for simd
+ for (int i =0 ; i < argc; ++i)
+ #pragma omp ordered simd
+ {
+ a=2;
+ }
// CHECK-NEXT: #pragma omp for ordered
// CHECK-NEXT: for (int i = 0; i < argc; ++i)
// CHECK-NEXT: #pragma omp ordered
@@ -83,6 +155,24 @@ int main (int argc, char **argv) {
// CHECK-NEXT: {
// CHECK-NEXT: a = 2;
// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp simd
+// CHECK-NEXT: for (int i = 0; i < argc; ++i)
+// CHECK-NEXT: #pragma omp ordered simd
+// CHECK-NEXT: {
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp for simd
+// CHECK-NEXT: for (int i = 0; i < argc; ++i)
+// CHECK-NEXT: #pragma omp ordered simd
+// CHECK-NEXT: {
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp parallel for simd
+// CHECK-NEXT: for (int i = 0; i < argc; ++i)
+// CHECK-NEXT: #pragma omp ordered simd
+// CHECK-NEXT: {
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: }
return tmain(argc);
}
diff --git a/clang/test/OpenMP/ordered_messages.cpp b/clang/test/OpenMP/ordered_messages.cpp
index 039a2b5fbf5..559a6b06f22 100644
--- a/clang/test/OpenMP/ordered_messages.cpp
+++ b/clang/test/OpenMP/ordered_messages.cpp
@@ -45,6 +45,52 @@ T foo() {
foo();
}
}
+ #pragma omp ordered simd simd // expected-error {{directive '#pragma omp ordered' cannot contain more than one 'simd' clause}}
+ {
+ foo();
+ }
+ #pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+ #pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ foo();
+ }
+ }
+ #pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+ #pragma omp ordered threads // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ foo();
+ }
+ }
+ #pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
+ #pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ foo();
+ }
+ }
+ #pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
+ #pragma omp ordered threads // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ foo();
+ }
+ }
+ #pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i) {
+ #pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ foo();
+ }
+ }
+ #pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i) {
+ #pragma omp ordered threads // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ foo();
+ }
+ }
return T();
}
@@ -91,6 +137,52 @@ int foo() {
foo();
}
}
+ #pragma omp ordered simd simd // expected-error {{directive '#pragma omp ordered' cannot contain more than one 'simd' clause}}
+ {
+ foo();
+ }
+ #pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+ #pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ foo();
+ }
+ }
+ #pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+ #pragma omp ordered threads // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ foo();
+ }
+ }
+ #pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
+ #pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ foo();
+ }
+ }
+ #pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
+ #pragma omp ordered threads // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ foo();
+ }
+ }
+ #pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i) {
+ #pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ foo();
+ }
+ }
+ #pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i) {
+ #pragma omp ordered threads // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ foo();
+ }
+ }
return foo<int>();
}
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 829cab736d7..c3bac878df9 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -2068,6 +2068,8 @@ void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
+void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
+
void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
Visitor->AddStmt(C->getDevice());
}
OpenPOWER on IntegriCloud