[llvm] c615927 - [OPENMP51]Initial support for the use clause.

Mike Rice via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 17 16:09:34 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 llvm-commits mailing list