[clang] 63828a3 - [OPENMP50]Bassic support for exclusive clause.
Alexey Bataev via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 23 10:13:13 PDT 2020
Author: Alexey Bataev
Date: 2020-03-23T13:12:52-04:00
New Revision: 63828a35da6f790f448b87b3eec61d294df31ccc
URL: https://github.com/llvm/llvm-project/commit/63828a35da6f790f448b87b3eec61d294df31ccc
DIFF: https://github.com/llvm/llvm-project/commit/63828a35da6f790f448b87b3eec61d294df31ccc.diff
LOG: [OPENMP50]Bassic support for exclusive clause.
Added basic support (parsing/sema/serialization) for exclusive clause in
scan directives.
Added:
Modified:
clang/include/clang/AST/OpenMPClause.h
clang/include/clang/AST/RecursiveASTVisitor.h
clang/include/clang/Basic/OpenMPKinds.def
clang/include/clang/Sema/Sema.h
clang/lib/AST/OpenMPClause.cpp
clang/lib/AST/StmtProfile.cpp
clang/lib/Basic/OpenMPKinds.cpp
clang/lib/CodeGen/CGStmtOpenMP.cpp
clang/lib/Parse/ParseOpenMP.cpp
clang/lib/Sema/SemaOpenMP.cpp
clang/lib/Sema/TreeTransform.h
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTWriter.cpp
clang/test/OpenMP/scan_ast_print.cpp
clang/test/OpenMP/scan_messages.cpp
clang/tools/libclang/CIndex.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h
index a781797c2d56..acf450f07e66 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -6985,6 +6985,80 @@ class OMPInclusiveClause final
}
};
+/// This represents clause 'exclusive' in the '#pragma omp scan' directive.
+///
+/// \code
+/// #pragma omp scan exclusive(a,b)
+/// \endcode
+/// In this example directive '#pragma omp scan' has clause 'exclusive'
+/// with the variables 'a' and 'b'.
+class OMPExclusiveClause final
+ : public OMPVarListClause<OMPExclusiveClause>,
+ private llvm::TrailingObjects<OMPExclusiveClause, Expr *> {
+ friend class OMPClauseReader;
+ friend OMPVarListClause;
+ friend TrailingObjects;
+
+ /// Build clause with number of variables \a N.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param N Number of the variables in the clause.
+ OMPExclusiveClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, unsigned N)
+ : OMPVarListClause<OMPExclusiveClause>(OMPC_exclusive, StartLoc,
+ LParenLoc, EndLoc, N) {}
+
+ /// Build an empty clause.
+ ///
+ /// \param N Number of variables.
+ explicit OMPExclusiveClause(unsigned N)
+ : OMPVarListClause<OMPExclusiveClause>(OMPC_exclusive, SourceLocation(),
+ SourceLocation(), SourceLocation(),
+ N) {}
+
+public:
+ /// Creates clause with a list of variables \a VL.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param VL List of references to the original variables.
+ static OMPExclusiveClause *Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL);
+
+ /// Creates an empty clause with the place for \a N variables.
+ ///
+ /// \param C AST context.
+ /// \param N The number of variables.
+ static OMPExclusiveClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+ child_range children() {
+ return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ const_child_range children() const {
+ auto Children = const_cast<OMPExclusiveClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_exclusive;
+ }
+};
+
/// This class implements a simple visitor for OMPClause
/// subclasses.
template<class ImplClass, template <typename> class Ptr, typename RetTy>
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 94f68f555fdf..4bd489f4ba6d 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -3190,6 +3190,13 @@ bool RecursiveASTVisitor<Derived>::VisitOMPInclusiveClause(
return true;
}
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPExclusiveClause(
+ OMPExclusiveClause *C) {
+ TRY_TO(VisitOMPClauseList(C));
+ return true;
+}
+
template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
TRY_TO(VisitOMPClauseList(C));
diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def
index 1e4b2b116a98..ffffed50ef86 100644
--- a/clang/include/clang/Basic/OpenMPKinds.def
+++ b/clang/include/clang/Basic/OpenMPKinds.def
@@ -285,9 +285,11 @@ OPENMP_CLAUSE(depobj, OMPDepobjClause)
OPENMP_CLAUSE(destroy, OMPDestroyClause)
OPENMP_CLAUSE(detach, OMPDetachClause)
OPENMP_CLAUSE(inclusive, OMPInclusiveClause)
+OPENMP_CLAUSE(exclusive, OMPExclusiveClause)
// Clauses allowed for OpenMP directive 'scan'.
OPENMP_SCAN_CLAUSE(inclusive)
+OPENMP_SCAN_CLAUSE(exclusive)
// Clauses allowed for OpenMP directive 'parallel'.
OPENMP_PARALLEL_CLAUSE(if)
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 03f3a1b4bdc9..90ba85638f0b 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -10506,6 +10506,11 @@ class Sema final {
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
+ /// Called on well-formed 'exclusive' clause.
+ OMPClause *ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
/// Called on well-formed 'allocate' clause.
OMPClause *
ActOnOpenMPAllocateClause(Expr *Allocator, ArrayRef<Expr *> VarList,
diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index de8fd67a0250..5f9da85a9f07 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -147,6 +147,7 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
case OMPC_destroy:
case OMPC_detach:
case OMPC_inclusive:
+ case OMPC_exclusive:
break;
}
@@ -235,6 +236,7 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
case OMPC_destroy:
case OMPC_detach:
case OMPC_inclusive:
+ case OMPC_exclusive:
break;
}
@@ -1268,6 +1270,24 @@ OMPInclusiveClause *OMPInclusiveClause::CreateEmpty(const ASTContext &C,
return new (Mem) OMPInclusiveClause(N);
}
+OMPExclusiveClause *OMPExclusiveClause::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc,
+ ArrayRef<Expr *> VL) {
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
+ auto *Clause =
+ new (Mem) OMPExclusiveClause(StartLoc, LParenLoc, EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ return Clause;
+}
+
+OMPExclusiveClause *OMPExclusiveClause::CreateEmpty(const ASTContext &C,
+ unsigned N) {
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
+ return new (Mem) OMPExclusiveClause(N);
+}
+
//===----------------------------------------------------------------------===//
// OpenMP clauses printing methods
//===----------------------------------------------------------------------===//
@@ -1833,6 +1853,14 @@ void OMPClausePrinter::VisitOMPInclusiveClause(OMPInclusiveClause *Node) {
}
}
+void OMPClausePrinter::VisitOMPExclusiveClause(OMPExclusiveClause *Node) {
+ if (!Node->varlist_empty()) {
+ OS << "exclusive";
+ VisitOMPClauseList(Node, '(');
+ OS << ")";
+ }
+}
+
void OMPTraitInfo::getAsVariantMatchInfo(
ASTContext &ASTCtx, llvm::omp::VariantMatchInfo &VMI) const {
for (const OMPTraitSet &Set : Sets) {
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index a31a65fad35f..cd39024cd838 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -798,6 +798,9 @@ void OMPClauseProfiler::VisitOMPNontemporalClause(
void OMPClauseProfiler::VisitOMPInclusiveClause(const OMPInclusiveClause *C) {
VisitOMPClauseList(C);
}
+void OMPClauseProfiler::VisitOMPExclusiveClause(const OMPExclusiveClause *C) {
+ VisitOMPClauseList(C);
+}
void OMPClauseProfiler::VisitOMPOrderClause(const OMPOrderClause *C) {}
} // namespace
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index a905dff440d7..36e7f4583468 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -213,6 +213,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
case OMPC_destroy:
case OMPC_detach:
case OMPC_inclusive:
+ case OMPC_exclusive:
break;
}
llvm_unreachable("Invalid OpenMP simple clause kind");
@@ -449,6 +450,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
case OMPC_destroy:
case OMPC_detach:
case OMPC_inclusive:
+ case OMPC_exclusive:
break;
}
llvm_unreachable("Invalid OpenMP simple clause kind");
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index e05829f0a890..bef36bf4693b 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -4617,6 +4617,7 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
case OMPC_destroy:
case OMPC_detach:
case OMPC_inclusive:
+ case OMPC_exclusive:
llvm_unreachable("Clause is not allowed in 'omp atomic'.");
}
}
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index bb239c833b82..acc1e55eb721 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -2344,7 +2344,8 @@ bool Parser::ParseOpenMPSimpleVarList(
/// from-clause | is_device_ptr-clause | task_reduction-clause |
/// in_reduction-clause | allocator-clause | allocate-clause |
/// acq_rel-clause | acquire-clause | release-clause | relaxed-clause |
-/// depobj-clause | destroy-clause | detach-clause | inclusive-clause
+/// depobj-clause | destroy-clause | detach-clause | inclusive-clause |
+/// exclusive-clause
///
OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
OpenMPClauseKind CKind, bool FirstClause) {
@@ -2514,6 +2515,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
case OMPC_allocate:
case OMPC_nontemporal:
case OMPC_inclusive:
+ case OMPC_exclusive:
Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
break;
case OMPC_device_type:
@@ -3239,7 +3241,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
/// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
/// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction',
-/// 'in_reduction', 'nontemporal' or 'inclusive'.
+/// 'in_reduction', 'nontemporal', 'exclusive' or 'inclusive'.
///
/// private-clause:
/// 'private' '(' list ')'
@@ -3283,6 +3285,8 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
/// 'nontemporal' '(' list ')'
/// inclusive-clause:
/// 'inclusive' '(' list ')'
+/// exclusive-clause:
+/// 'exclusive' '(' list ')'
///
/// For 'linear' clause linear-list may have the following forms:
/// list
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 8c488da6cf0f..d9a4a17f1866 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -5100,6 +5100,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
case OMPC_order:
case OMPC_destroy:
case OMPC_inclusive:
+ case OMPC_exclusive:
continue;
case OMPC_allocator:
case OMPC_flush:
@@ -11084,6 +11085,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
case OMPC_order:
case OMPC_destroy:
case OMPC_inclusive:
+ case OMPC_exclusive:
llvm_unreachable("Clause is not allowed.");
}
return Res;
@@ -11820,6 +11822,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPC_destroy:
case OMPC_detach:
case OMPC_inclusive:
+ case OMPC_exclusive:
llvm_unreachable("Unexpected OpenMP clause.");
}
return CaptureRegion;
@@ -12258,6 +12261,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
case OMPC_destroy:
case OMPC_detach:
case OMPC_inclusive:
+ case OMPC_exclusive:
llvm_unreachable("Clause is not allowed.");
}
return Res;
@@ -12482,6 +12486,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
case OMPC_destroy:
case OMPC_detach:
case OMPC_inclusive:
+ case OMPC_exclusive:
llvm_unreachable("Clause is not allowed.");
}
return Res;
@@ -12713,6 +12718,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
case OMPC_order:
case OMPC_detach:
case OMPC_inclusive:
+ case OMPC_exclusive:
llvm_unreachable("Clause is not allowed.");
}
return Res;
@@ -12923,6 +12929,9 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
case OMPC_inclusive:
Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
break;
+ case OMPC_exclusive:
+ Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
+ break;
case OMPC_if:
case OMPC_depobj:
case OMPC_final:
@@ -18008,3 +18017,31 @@ OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
}
+
+OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ SmallVector<Expr *, 8> Vars;
+ for (Expr *RefExpr : VarList) {
+ assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
+ SourceLocation ELoc;
+ SourceRange ERange;
+ Expr *SimpleRefExpr = RefExpr;
+ auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
+ /*AllowArraySection=*/true);
+ if (Res.second)
+ // It will be analyzed later.
+ Vars.push_back(RefExpr);
+ ValueDecl *D = Res.first;
+ if (!D)
+ continue;
+
+ Vars.push_back(RefExpr);
+ }
+
+ if (Vars.empty())
+ return nullptr;
+
+ return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
+}
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 8a22eb89d806..3e6d67d67845 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -2065,6 +2065,18 @@ class TreeTransform {
EndLoc);
}
+ /// Build a new OpenMP 'exclusive' clause.
+ ///
+ /// By default, performs semantic analysis to build the new OpenMP clause.
+ /// Subclasses may override this routine to provide
diff erent behavior.
+ OMPClause *RebuildOMPExclusiveClause(ArrayRef<Expr *> VarList,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ return getSema().ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc,
+ EndLoc);
+ }
+
/// Build a new OpenMP 'order' clause.
///
/// By default, performs semantic analysis to build the new OpenMP clause.
@@ -9548,6 +9560,21 @@ TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
}
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
+ llvm::SmallVector<Expr *, 16> Vars;
+ Vars.reserve(C->varlist_size());
+ for (auto *VE : C->varlists()) {
+ ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
+ if (EVar.isInvalid())
+ return nullptr;
+ Vars.push_back(EVar.get());
+ }
+ return getDerived().RebuildOMPExclusiveClause(
+ Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
+}
+
template <typename Derived>
OMPClause *
TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index ac111776fe76..77f15bcd910a 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -11845,6 +11845,9 @@ OMPClause *OMPClauseReader::readClause() {
case OMPC_inclusive:
C = OMPInclusiveClause::CreateEmpty(Context, Record.readInt());
break;
+ case OMPC_exclusive:
+ C = OMPExclusiveClause::CreateEmpty(Context, Record.readInt());
+ break;
case OMPC_order:
C = new (Context) OMPOrderClause();
break;
@@ -12665,6 +12668,16 @@ void OMPClauseReader::VisitOMPInclusiveClause(OMPInclusiveClause *C) {
C->setVarRefs(Vars);
}
+void OMPClauseReader::VisitOMPExclusiveClause(OMPExclusiveClause *C) {
+ C->setLParenLoc(Record.readSourceLocation());
+ unsigned NumVars = C->varlist_size();
+ SmallVector<Expr *, 16> Vars;
+ Vars.reserve(NumVars);
+ for (unsigned i = 0; i != NumVars; ++i)
+ Vars.push_back(Record.readSubExpr());
+ C->setVarRefs(Vars);
+}
+
void OMPClauseReader::VisitOMPOrderClause(OMPOrderClause *C) {
C->setKind(Record.readEnum<OpenMPOrderClauseKind>());
C->setLParenLoc(Record.readSourceLocation());
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index a5d5b0f47144..9ccebae9567d 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -6611,6 +6611,13 @@ void OMPClauseWriter::VisitOMPInclusiveClause(OMPInclusiveClause *C) {
Record.AddStmt(VE);
}
+void OMPClauseWriter::VisitOMPExclusiveClause(OMPExclusiveClause *C) {
+ Record.push_back(C->varlist_size());
+ Record.AddSourceLocation(C->getLParenLoc());
+ for (auto *VE : C->varlists())
+ Record.AddStmt(VE);
+}
+
void OMPClauseWriter::VisitOMPOrderClause(OMPOrderClause *C) {
Record.writeEnum(C->getKind());
Record.AddSourceLocation(C->getLParenLoc());
diff --git a/clang/test/OpenMP/scan_ast_print.cpp b/clang/test/OpenMP/scan_ast_print.cpp
index efcaa2da138a..4b9eca6f7ec9 100644
--- a/clang/test/OpenMP/scan_ast_print.cpp
+++ b/clang/test/OpenMP/scan_ast_print.cpp
@@ -39,11 +39,11 @@ int main(int argc, char **argv) {
// CHECK: static int a;
#pragma omp for simd
for (int i = 0; i < 10; ++i) {
-#pragma omp scan inclusive(a)
+#pragma omp scan exclusive(a, argc)
}
// CHECK-NEXT: #pragma omp for simd
// CHECK-NEXT: for (int i = 0; i < 10; ++i) {
-// CHECK-NEXT: #pragma omp scan inclusive(a){{$}}
+// CHECK-NEXT: #pragma omp scan exclusive(a,argc){{$}}
return tmain(argc) + tmain(argv[0][0]) + a;
}
diff --git a/clang/test/OpenMP/scan_messages.cpp b/clang/test/OpenMP/scan_messages.cpp
index 3be998d0f96e..9f093858c249 100644
--- a/clang/test/OpenMP/scan_messages.cpp
+++ b/clang/test/OpenMP/scan_messages.cpp
@@ -54,25 +54,25 @@ T tmain(T argc) {
#pragma omp simd
for (int i = 0; i < 10; ++i)
switch (argc) {
-#pragma omp scan inclusive(argc) // expected-note 2 {{previous 'scan' directive used here}}
+#pragma omp scan exclusive(argc) // expected-note 2 {{previous 'scan' directive used here}}
case 1:
-#pragma omp scan inclusive(argc) // expected-error {{exactly one 'scan' directive must appear in the loop body of an enclosing directive}}
+#pragma omp scan exclusive(argc) // expected-error {{exactly one 'scan' directive must appear in the loop body of an enclosing directive}}
break;
default: {
-#pragma omp scan inclusive(argc) // expected-error {{exactly one 'scan' directive must appear in the loop body of an enclosing directive}}
+#pragma omp scan exclusive(argc) // expected-error {{exactly one 'scan' directive must appear in the loop body of an enclosing directive}}
} break;
}
#pragma omp simd
for (int i = 0; i < 10; ++i)
for (;;)
-#pragma omp scan inclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}}
+#pragma omp scan exclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}}
for (;;) {
-#pragma omp scan inclusive(argc)
+#pragma omp scan exclusive(argc)
}
#pragma omp simd
for (int i = 0; i < 10; ++i) {
label:
-#pragma omp scan inclusive(argc)
+#pragma omp scan exclusive(argc)
}
#pragma omp simd
for (int i = 0; i < 10; ++i) {
@@ -91,6 +91,16 @@ int main(int argc, char **argv) {
}
#pragma omp simd
for (int i = 0; i < 10; ++i) {
+#pragma omp scan exclusive(argc) inclusive(argc) // expected-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}}
+ ;
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp scan exclusive(argc) exclusive(argc) // expected-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}}
+ ;
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
#pragma omp scan untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp scan'}} expected-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}}
#pragma omp scan unknown // expected-warning {{extra tokens at the end of '#pragma omp scan' are ignored}} expected-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}}
}
@@ -117,18 +127,18 @@ int main(int argc, char **argv) {
#pragma omp simd
for (int i = 0; i < 10; ++i)
do {
-#pragma omp scan inclusive(argc)
+#pragma omp scan exclusive(argc)
} while (argc);
#pragma omp simd
for (int i = 0; i < 10; ++i)
switch (argc)
-#pragma omp scan inclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}}
+#pragma omp scan exclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}}
switch (argc)
case 1:
-#pragma omp scan inclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}}
+#pragma omp scan exclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}}
switch (argc)
case 1: {
-#pragma omp scan inclusive(argc)
+#pragma omp scan exclusive(argc)
}
#pragma omp simd
for (int i = 0; i < 10; ++i)
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 31a0f364a348..ae7fd4271799 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -2312,6 +2312,9 @@ void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
void OMPClauseEnqueue::VisitOMPInclusiveClause(const OMPInclusiveClause *C) {
VisitOMPClauseList(C);
}
+void OMPClauseEnqueue::VisitOMPExclusiveClause(const OMPExclusiveClause *C) {
+ VisitOMPClauseList(C);
+}
void OMPClauseEnqueue::VisitOMPAllocateClause(const OMPAllocateClause *C) {
VisitOMPClauseList(C);
Visitor->AddStmt(C->getAllocator());
More information about the cfe-commits
mailing list