[clang] c615927 - [OPENMP51]Initial support for the use clause.
Mike Rice via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 17 16:09:33 PDT 2021
Author: Mike Rice
Date: 2021-03-17T15:46:14-07:00
New Revision: c615927c8e38d8608d7b5fa294a25dc44df0eb68
URL: https://github.com/llvm/llvm-project/commit/c615927c8e38d8608d7b5fa294a25dc44df0eb68
DIFF: https://github.com/llvm/llvm-project/commit/c615927c8e38d8608d7b5fa294a25dc44df0eb68.diff
LOG: [OPENMP51]Initial support for the use clause.
Added basic parsing/sema/serialization support for the 'use' clause.
Differential Revision: https://reviews.llvm.org/D98815
Added:
Modified:
clang/include/clang/AST/OpenMPClause.h
clang/include/clang/AST/RecursiveASTVisitor.h
clang/include/clang/Sema/Sema.h
clang/lib/AST/OpenMPClause.cpp
clang/lib/AST/StmtProfile.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/interop_ast_print.cpp
clang/test/OpenMP/interop_messages.cpp
clang/tools/libclang/CIndex.cpp
flang/lib/Semantics/check-omp-structure.cpp
llvm/include/llvm/Frontend/OpenMP/OMP.td
Removed:
################################################################################
diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h
index 4e4e719ff184..b342ffb93256 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -7489,6 +7489,77 @@ class OMPInitClause final
}
};
+/// This represents the 'use' clause in '#pragma omp ...' directives.
+///
+/// \code
+/// #pragma omp interop use(obj)
+/// \endcode
+class OMPUseClause final : public OMPClause {
+ friend class OMPClauseReader;
+
+ /// Location of '('.
+ SourceLocation LParenLoc;
+
+ /// Location of interop variable.
+ SourceLocation VarLoc;
+
+ /// The interop variable.
+ Stmt *InteropVar = nullptr;
+
+ /// Set the interop variable.
+ void setInteropVar(Expr *E) { InteropVar = E; }
+
+ /// Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+ /// Sets the location of the interop variable.
+ void setVarLoc(SourceLocation Loc) { VarLoc = Loc; }
+
+public:
+ /// Build 'use' clause with and interop variable expression \a InteropVar.
+ ///
+ /// \param InteropVar The interop variable.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param VarLoc Location of the interop variable.
+ /// \param EndLoc Ending location of the clause.
+ OMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation VarLoc,
+ SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_use, StartLoc, EndLoc), LParenLoc(LParenLoc),
+ VarLoc(VarLoc), InteropVar(InteropVar) {}
+
+ /// Build an empty clause.
+ OMPUseClause()
+ : OMPClause(llvm::omp::OMPC_use, SourceLocation(), SourceLocation()) {}
+
+ /// Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// Returns the location of the interop variable.
+ SourceLocation getVarLoc() const { return VarLoc; }
+
+ /// Returns the interop variable.
+ Expr *getInteropVar() const { return cast<Expr>(InteropVar); }
+
+ child_range children() { return child_range(&InteropVar, &InteropVar + 1); }
+
+ const_child_range children() const {
+ return const_child_range(&InteropVar, &InteropVar + 1);
+ }
+
+ 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() == llvm::omp::OMPC_use;
+ }
+};
+
/// This represents 'destroy' clause in the '#pragma omp depobj'
/// directive.
///
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 3983e47d4f77..4a7c234e374b 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -3203,6 +3203,12 @@ bool RecursiveASTVisitor<Derived>::VisitOMPInitClause(OMPInitClause *C) {
return true;
}
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPUseClause(OMPUseClause *C) {
+ TRY_TO(TraverseStmt(C->getInteropVar()));
+ return true;
+}
+
template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPDestroyClause(OMPDestroyClause *) {
return true;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 21ea3b492d48..978c5de57646 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -10992,6 +10992,11 @@ class Sema final {
SourceLocation VarLoc,
SourceLocation EndLoc);
+ /// Called on well-formed 'use' clause.
+ OMPClause *ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation VarLoc, SourceLocation EndLoc);
+
/// Called on well-formed 'destroy' clause.
OMPClause *ActOnOpenMPDestroyClause(SourceLocation StartLoc,
SourceLocation EndLoc);
diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index 8631de8c0d6a..1014c8e3a95e 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -1801,6 +1801,12 @@ void OMPClausePrinter::VisitOMPInitClause(OMPInitClause *Node) {
OS << ")";
}
+void OMPClausePrinter::VisitOMPUseClause(OMPUseClause *Node) {
+ OS << "use(";
+ Node->getInteropVar()->printPretty(OS, nullptr, Policy);
+ OS << ")";
+}
+
void OMPClausePrinter::VisitOMPDestroyClause(OMPDestroyClause *) {
OS << "destroy";
}
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 836a79b0990d..c1ffa069d267 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -547,6 +547,11 @@ void OMPClauseProfiler::VisitOMPInitClause(const OMPInitClause *C) {
VisitOMPClauseList(C);
}
+void OMPClauseProfiler::VisitOMPUseClause(const OMPUseClause *C) {
+ if (C->getInteropVar())
+ Profiler->VisitStmt(C->getInteropVar());
+}
+
void OMPClauseProfiler::VisitOMPDestroyClause(const OMPDestroyClause *) {}
template<typename T>
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index a79fa7bc165f..fe7998f6bfc8 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -2930,6 +2930,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
Clause = ParseOpenMPUsesAllocatorClause(DKind);
break;
case OMPC_init:
+ case OMPC_use:
Clause = ParseOpenMPInteropClause(CKind, WrongDirective);
break;
case OMPC_device_type:
@@ -3155,6 +3156,9 @@ OMPClause *Parser::ParseOpenMPInteropClause(OpenMPClauseKind Kind,
return Actions.ActOnOpenMPInitClause(InteropVarExpr.get(), Prefs, IsTarget,
IsTargetSync, Loc, T.getOpenLocation(),
VarLoc, RLoc);
+ if (Kind == OMPC_use)
+ return Actions.ActOnOpenMPUseClause(InteropVarExpr.get(), Loc,
+ T.getOpenLocation(), VarLoc, RLoc);
llvm_unreachable("Unexpected interop variable clause.");
}
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 9e956c8a294a..c4da3e58f58c 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -14610,8 +14610,8 @@ StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses,
// OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
// At least one action-clause must appear on a directive.
- // TODO: also add 'use' and 'destroy' here.
- if (!hasClauses(Clauses, OMPC_init, OMPC_nowait)) {
+ // TODO: also add 'destroy' here.
+ if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_nowait)) {
StringRef Expected = "'init', 'use', 'destroy', or 'nowait'";
Diag(StartLoc, diag::err_omp_no_clause_for_directive)
<< Expected << getOpenMPDirectiveName(OMPD_interop);
@@ -14627,16 +14627,20 @@ StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses,
// interop-type of 'targetsync'. Cases involving other directives cannot be
// diagnosed.
const OMPDependClause *DependClause = nullptr;
+ bool HasInitClause = false;
bool IsTargetSync = false;
for (const OMPClause *C : Clauses) {
if (IsTargetSync)
break;
- if (const auto *InitClause = dyn_cast<OMPInitClause>(C))
- IsTargetSync = InitClause->getIsTargetSync();
- else if (const auto *DC = dyn_cast<OMPDependClause>(C))
+ if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) {
+ HasInitClause = true;
+ if (InitClause->getIsTargetSync())
+ IsTargetSync = true;
+ } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) {
DependClause = DC;
+ }
}
- if (DependClause && !IsTargetSync) {
+ if (DependClause && HasInitClause && !IsTargetSync) {
Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause);
return StmtError();
}
@@ -14654,8 +14658,12 @@ StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses,
const auto *IC = cast<OMPInitClause>(C);
VarLoc = IC->getVarLoc();
DRE = dyn_cast_or_null<DeclRefExpr>(IC->getInteropVar());
+ } else if (ClauseKind == OMPC_use) {
+ const auto *UC = cast<OMPUseClause>(C);
+ VarLoc = UC->getVarLoc();
+ DRE = dyn_cast_or_null<DeclRefExpr>(UC->getInteropVar());
}
- // TODO: 'use' and 'destroy' clauses to be added here.
+ // TODO: 'destroy' clause to be added here.
if (!DRE)
continue;
@@ -14753,6 +14761,18 @@ Sema::ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef<Expr *> PrefExprs,
EndLoc);
}
+OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation VarLoc,
+ SourceLocation EndLoc) {
+
+ if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use))
+ return nullptr;
+
+ return new (Context)
+ OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
+}
+
OMPClause *Sema::ActOnOpenMPVarListClause(
OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr,
const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 115e4b151b7f..7f6432d83821 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -2185,6 +2185,17 @@ class TreeTransform {
VarLoc, EndLoc);
}
+ /// Build a new OpenMP 'use' clause.
+ ///
+ /// By default, performs semantic analysis to build the new OpenMP clause.
+ /// Subclasses may override this routine to provide
diff erent behavior.
+ OMPClause *RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation VarLoc, SourceLocation EndLoc) {
+ return getSema().ActOnOpenMPUseClause(InteropVar, StartLoc, LParenLoc,
+ VarLoc, EndLoc);
+ }
+
/// Rebuild the operand to an Objective-C \@synchronized statement.
///
/// By default, performs semantic analysis to build the new statement.
@@ -9319,6 +9330,16 @@ OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
C->getBeginLoc(), C->getLParenLoc(), C->getVarLoc(), C->getEndLoc());
}
+template <typename Derived>
+OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
+ ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
+ if (ER.isInvalid())
+ return nullptr;
+ return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
+ C->getLParenLoc(), C->getVarLoc(),
+ C->getEndLoc());
+}
+
template <typename Derived>
OMPClause *
TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 1c2626667229..5dd30017113c 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -11971,6 +11971,9 @@ OMPClause *OMPClauseReader::readClause() {
case llvm::omp::OMPC_init:
C = OMPInitClause::CreateEmpty(Context, Record.readInt());
break;
+ case llvm::omp::OMPC_use:
+ C = new (Context) OMPUseClause();
+ break;
case llvm::omp::OMPC_destroy:
C = new (Context) OMPDestroyClause();
break;
@@ -12147,6 +12150,12 @@ void OMPClauseReader::VisitOMPInitClause(OMPInitClause *C) {
C->setVarLoc(Record.readSourceLocation());
}
+void OMPClauseReader::VisitOMPUseClause(OMPUseClause *C) {
+ C->setInteropVar(Record.readSubExpr());
+ C->setLParenLoc(Record.readSourceLocation());
+ C->setVarLoc(Record.readSourceLocation());
+}
+
void OMPClauseReader::VisitOMPDestroyClause(OMPDestroyClause *) {}
void OMPClauseReader::VisitOMPUnifiedAddressClause(OMPUnifiedAddressClause *) {}
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index dd5c863ef2f9..11deaf65254f 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -6225,6 +6225,12 @@ void OMPClauseWriter::VisitOMPInitClause(OMPInitClause *C) {
Record.AddSourceLocation(C->getVarLoc());
}
+void OMPClauseWriter::VisitOMPUseClause(OMPUseClause *C) {
+ Record.AddStmt(C->getInteropVar());
+ Record.AddSourceLocation(C->getLParenLoc());
+ Record.AddSourceLocation(C->getVarLoc());
+}
+
void OMPClauseWriter::VisitOMPDestroyClause(OMPDestroyClause *) {}
void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) {
diff --git a/clang/test/OpenMP/interop_ast_print.cpp b/clang/test/OpenMP/interop_ast_print.cpp
index c95b191b2a5c..24d95268c653 100644
--- a/clang/test/OpenMP/interop_ast_print.cpp
+++ b/clang/test/OpenMP/interop_ast_print.cpp
@@ -35,12 +35,31 @@ void foo1(int *ap, int dev) {
//DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'I'
#pragma omp interop init(target:I)
+ //PRINT: #pragma omp interop use(I)
+ //DUMP: OMPInteropDirective
+ //DUMP: OMPUseClause
+ //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'I'
+ #pragma omp interop use(I)
+
//PRINT: #pragma omp interop init(target : IRef)
//DUMP: OMPInteropDirective
//DUMP: OMPInitClause
//DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'IRef'
#pragma omp interop init(target:IRef)
+ //PRINT: #pragma omp interop use(IRef)
+ //DUMP: OMPInteropDirective
+ //DUMP: OMPUseClause
+ //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'IRef'
+ #pragma omp interop use(IRef)
+
+ const omp_interop_t CI = (omp_interop_t)0;
+ //PRINT: #pragma omp interop use(CI)
+ //DUMP: OMPInteropDirective
+ //DUMP: OMPUseClause
+ //DUMP: DeclRefExpr{{.*}}'const omp_interop_t'{{.*}}Var{{.*}}'CI'
+ #pragma omp interop use(CI)
+
//PRINT: #pragma omp interop device(dev) depend(inout : ap) init(targetsync : I)
//DUMP: OMPInteropDirective
//DUMP: OMPDeviceClause
@@ -51,6 +70,16 @@ void foo1(int *ap, int dev) {
//DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'I'
#pragma omp interop device(dev) depend(inout:ap) init(targetsync:I)
+ //PRINT: #pragma omp interop device(dev) depend(inout : ap) use(I)
+ //DUMP: OMPInteropDirective
+ //DUMP: OMPDeviceClause
+ //DUMP: DeclRefExpr{{.*}}'dev' 'int'
+ //DUMP: OMPDependClause
+ //DUMP: DeclRefExpr{{.*}}'ap' 'int *'
+ //DUMP: OMPUseClause
+ //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'I'
+ #pragma omp interop device(dev) depend(inout:ap) use(I)
+
//PRINT: #pragma omp interop init(prefer_type(1,2,3,4,5,6), targetsync : I)
//DUMP: OMPInteropDirective
//DUMP: OMPInitClause
@@ -106,6 +135,21 @@ void foo1(int *ap, int dev) {
//DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'J'
#pragma omp interop init(target:I) init(targetsync:J)
+ //PRINT: #pragma omp interop init(target : I) use(J)
+ //DUMP: OMPInteropDirective
+ //DUMP: OMPInitClause
+ //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'I'
+ //DUMP: OMPUseClause
+ //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'J'
+ #pragma omp interop init(target:I) use(J)
+
+ //PRINT: #pragma omp interop use(I) use(J)
+ //DUMP: OMPInteropDirective
+ //DUMP: OMPUseClause
+ //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'I'
+ //DUMP: OMPUseClause
+ //DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}Var{{.*}}'J'
+ #pragma omp interop use(I) use(J)
}
//DUMP: FunctionTemplateDecl{{.*}}fooTemp
@@ -150,6 +194,12 @@ void barTemp(T t) {
//DUMP: StringLiteral{{.*}}"level_one"
#pragma omp interop init(prefer_type(4,"level_one"), target: t)
+ //PRINT: #pragma omp interop use(t)
+ //DUMP: OMPInteropDirective
+ //DUMP: OMPUseClause
+ //DUMP: DeclRefExpr{{.*}}ParmVar{{.*}}'t' 'T'
+ #pragma omp interop use(t)
+
//DUMP: FunctionDecl{{.*}}barTemp 'void (void *)'
//DUMP: TemplateArgument type 'void *'
//DUMP: ParmVarDecl{{.*}}t 'void *'
@@ -157,6 +207,10 @@ void barTemp(T t) {
//DUMP: OMPInitClause
//DUMP: DeclRefExpr{{.*}}ParmVar{{.*}}'t' 'void *'
//PRINT: #pragma omp interop init(prefer_type(4,"level_one"), target : t)
+ //DUMP: OMPInteropDirective
+ //DUMP: OMPUseClause
+ //DUMP: DeclRefExpr{{.*}}ParmVar{{.*}}'t' 'void *'
+ //PRINT: #pragma omp interop use(t)
}
void bar()
diff --git a/clang/test/OpenMP/interop_messages.cpp b/clang/test/OpenMP/interop_messages.cpp
index 0fba35d4bc9d..550cf81b5370 100644
--- a/clang/test/OpenMP/interop_messages.cpp
+++ b/clang/test/OpenMP/interop_messages.cpp
@@ -14,6 +14,9 @@ void foo(int *Ap) {
//expected-error at +1 {{use of undeclared identifier 'NoDeclVar'}}
#pragma omp interop init(target:NoDeclVar) init(target:Another)
+ //expected-error at +1 {{use of undeclared identifier 'NoDeclVar'}}
+ #pragma omp interop use(NoDeclVar) use(Another)
+
//expected-error at +2 {{expected interop type: 'target' and/or 'targetsync'}}
//expected-error at +1 {{expected expression}}
#pragma omp interop init(InteropVar) init(target:Another)
@@ -32,14 +35,23 @@ void foo(int *Ap) {
#pragma omp interop init(prefer_type(1,"sycl",3),target:IntVar) \
init(target:Another)
+ //expected-error at +1 {{interop variable must be of type 'omp_interop_t'}}
+ #pragma omp interop use(IntVar) use(Another)
+
//expected-error at +1 {{interop variable must be of type 'omp_interop_t'}}
#pragma omp interop init(prefer_type(1,"sycl",3),target:SVar) \
init(target:Another)
+ //expected-error at +1 {{interop variable must be of type 'omp_interop_t'}}
+ #pragma omp interop use(SVar) use(Another)
+
int a, b;
//expected-error at +1 {{expected variable of type 'omp_interop_t'}}
#pragma omp interop init(target:a+b) init(target:Another)
+ //expected-error at +1 {{expected variable of type 'omp_interop_t'}}
+ #pragma omp interop use(a+b) use(Another)
+
const omp_interop_t C = (omp_interop_t)5;
//expected-error at +1 {{expected non-const variable of type 'omp_interop_t'}}
#pragma omp interop init(target:C) init(target:Another)
@@ -64,6 +76,12 @@ void foo(int *Ap) {
//expected-error at +1 {{interop variable 'InteropVar' used in multiple action clauses}}
#pragma omp interop init(target:InteropVar) init(target:InteropVar)
+ //expected-error at +1 {{interop variable 'InteropVar' used in multiple action clauses}}
+ #pragma omp interop use(InteropVar) use(InteropVar)
+
+ //expected-error at +1 {{interop variable 'InteropVar' used in multiple action clauses}}
+ #pragma omp interop init(target:InteropVar) use(InteropVar)
+
//expected-error at +1 {{directive '#pragma omp interop' cannot contain more than one 'device' clause}}
#pragma omp interop init(target:InteropVar) device(0) device(1)
@@ -79,5 +97,7 @@ void foo() {
int InteropVar;
//expected-error at +1 {{'omp_interop_t' type not found; include <omp.h>}}
#pragma omp interop init(prefer_type(1,"sycl",3),target:InteropVar) nowait
+ //expected-error at +1 {{'omp_interop_t' type not found; include <omp.h>}}
+ #pragma omp interop use(InteropVar) nowait
}
#endif
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index ff922ade0fc9..235f5db2bfee 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -2282,6 +2282,10 @@ void OMPClauseEnqueue::VisitOMPInitClause(const OMPInitClause *C) {
VisitOMPClauseList(C);
}
+void OMPClauseEnqueue::VisitOMPUseClause(const OMPUseClause *C) {
+ Visitor->AddStmt(C->getInteropVar());
+}
+
void OMPClauseEnqueue::VisitOMPDestroyClause(const OMPDestroyClause *) {}
void OMPClauseEnqueue::VisitOMPUnifiedAddressClause(
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 6ebd58043163..269e64919a6a 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -718,6 +718,7 @@ CHECK_SIMPLE_CLAUSE(Update, OMPC_update)
CHECK_SIMPLE_CLAUSE(UseDeviceAddr, OMPC_use_device_addr)
CHECK_SIMPLE_CLAUSE(Write, OMPC_write)
CHECK_SIMPLE_CLAUSE(Init, OMPC_init)
+CHECK_SIMPLE_CLAUSE(Use, OMPC_use)
CHECK_REQ_SCALAR_INT_CLAUSE(Allocator, OMPC_allocator)
CHECK_REQ_SCALAR_INT_CLAUSE(Grainsize, OMPC_grainsize)
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index a343506e8b53..685732140eee 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -271,6 +271,9 @@ def OMPC_Order : Clause<"order"> {
def OMPC_Init : Clause<"init"> {
let clangClass = "OMPInitClause";
}
+def OMPC_Use : Clause<"use"> {
+ let clangClass = "OMPUseClause";
+}
def OMPC_Destroy : Clause<"destroy"> {
let clangClass = "OMPDestroyClause";
}
@@ -1649,6 +1652,7 @@ def OMP_interop : Directive<"interop"> {
VersionedClause<OMPC_Depend>,
VersionedClause<OMPC_Init>,
VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_Use>,
];
}
def OMP_Unknown : Directive<"unknown"> {
More information about the cfe-commits
mailing list