https://github.com/zahiraam updated 
https://github.com/llvm/llvm-project/pull/166810

>From ec999cb001304680af55b79591c8b998dbcfd925 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <[email protected]>
Date: Thu, 6 Nov 2025 09:17:08 -0800
Subject: [PATCH 1/5] [CLANG][OpenMP] Add support for OpenMP6.0 transparent
 clause

---
 clang/docs/OpenMPSupport.rst                  |  2 +-
 clang/docs/ReleaseNotes.rst                   |  1 +
 clang/include/clang/AST/OpenMPClause.h        | 86 ++++++++++++++++
 clang/include/clang/AST/RecursiveASTVisitor.h |  6 ++
 clang/include/clang/Basic/OpenMPKinds.def     |  9 ++
 clang/include/clang/Basic/OpenMPKinds.h       |  7 ++
 clang/include/clang/Sema/SemaOpenMP.h         |  6 ++
 clang/lib/AST/OpenMPClause.cpp                |  8 ++
 clang/lib/AST/StmtProfile.cpp                 |  2 +
 clang/lib/Basic/OpenMPKinds.cpp               | 19 ++++
 clang/lib/CodeGen/CGOpenMPRuntime.cpp         |  4 +
 clang/lib/Parse/ParseOpenMP.cpp               |  1 +
 clang/lib/Sema/SemaOpenMP.cpp                 | 22 +++++
 clang/lib/Sema/TreeTransform.h                |  7 ++
 clang/lib/Serialization/ASTReader.cpp         | 12 +++
 clang/lib/Serialization/ASTWriter.cpp         |  6 ++
 clang/test/OpenMP/task_ast_print.cpp          | 11 +++
 clang/test/OpenMP/task_codegen.cpp            | 45 +++++++++
 .../test/OpenMP/task_transparent_messages.cpp | 98 +++++++++++++++++++
 clang/test/OpenMP/taskloop_ast_print.cpp      | 22 +++++
 clang/test/OpenMP/taskloop_codegen.cpp        | 87 ++++++++++++++++
 clang/tools/libclang/CIndex.cpp               |  2 +
 llvm/include/llvm/Frontend/OpenMP/ClauseT.h   | 10 +-
 llvm/include/llvm/Frontend/OpenMP/OMP.td      |  1 +
 24 files changed, 472 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/OpenMP/task_transparent_messages.cpp

diff --git a/clang/docs/OpenMPSupport.rst b/clang/docs/OpenMPSupport.rst
index 10a8d095fede3..18b5b60ac6cdf 100644
--- a/clang/docs/OpenMPSupport.rst
+++ b/clang/docs/OpenMPSupport.rst
@@ -490,7 +490,7 @@ implementation.
 
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
 | memscope clause for atomic and flush                        | 
:none:`unclaimed`         | :none:`unclaimed`         |                         
                                                 |
 
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
-| transparent clause (hull tasks)                             | 
:none:`unclaimed`         | :none:`unclaimed`         |                         
                                                 |
+| transparent clause (hull tasks)                             | 
:part:`partial`           | :none:`unclaimed`         |  To Add the PR#         
                                                               |
 
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
 | rule-based compound directives                              | :part:`In 
Progress`       | :part:`In Progress`       | kparzysz                          
                                       |
 |                                                             |                
           |                           | Testing for Fortran missing            
                                  |
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 32f669f8d70d8..1a55b73e1013a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -687,6 +687,7 @@ OpenMP Support
 - Allow array length to be omitted in array section subscript expression.
 - Fixed non-contiguous strided update in the ``omp target update`` directive 
with the ``from`` clause.
 - Added support for threadset clause in task and taskloop directives.
+- Added support for ``transparent`` clause in task and taskloop directives.
 - Properly handle array section/assumed-size array privatization in C/C++.
 - Added support to handle new syntax of the ``uses_allocators`` clause.
 - Added support for ``variable-category`` modifier in ``default clause``.
diff --git a/clang/include/clang/AST/OpenMPClause.h 
b/clang/include/clang/AST/OpenMPClause.h
index 4f507485968cd..a56b69fa39754 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -1504,6 +1504,92 @@ class OMPThreadsetClause final : public OMPClause {
   }
 };
 
+/// This class represents the 'transparent' clause in the '#pragma omp task'
+/// directive.
+///
+/// \code
+/// #pragma omp task transparent(omp_not_impex)
+/// \endcode
+///
+/// In this example, the directive '#pragma omp task' has a 'transparent'
+/// clause with OpenMP keyword 'omp_not_impex`. Other valid keywords that may
+/// appear in this clause are 'omp_import', 'omp_export' and 'omp_impex'.
+///
+class OMPTransparentClause final : public OMPClause {
+  friend class OMPClauseReader;
+
+  /// Location of '('.
+  SourceLocation LParenLoc;
+
+  /// A kind of the 'transparent' clause.
+  OpenMPTransparentKind Kind = OMPC_TRANSPARENT_unknown;
+
+  /// Start location of the kind in source code.
+  SourceLocation KindLoc;
+
+  /// Set kind of the clauses.
+  ///
+  /// \param K Argument of clause.
+  void setTransparentKind(OpenMPTransparentKind K) { Kind = K; }
+
+  /// Set argument location.
+  ///
+  /// \param KLoc Argument location.
+  void setTransparentKindLoc(SourceLocation KLoc) { KindLoc = KLoc; }
+
+public:
+  /// Build 'transparent' clause with argument \a A ('omp_not_impex',
+  /// 'omp_import', 'omp_export' or 'omp_impex')
+  ///
+  /// \param A Argument of the clause ('omp_not_impex', 'omp_import',
+  /// 'omp_export' or 'omp_impex')
+  /// \param ALoc Starting location of the argument.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  OMPTransparentClause(OpenMPTransparentKind A, SourceLocation ALoc,
+                     SourceLocation StartLoc, SourceLocation LParenLoc,
+                     SourceLocation EndLoc)
+      : OMPClause(llvm::omp::OMPC_transparent, StartLoc, EndLoc),
+        LParenLoc(LParenLoc), Kind(A), KindLoc(ALoc) {}
+
+  /// Build an empty clause.
+  OMPTransparentClause()
+      : OMPClause(llvm::omp::OMPC_transparent, SourceLocation(),
+                  SourceLocation()) {}
+
+  /// Sets the location of '('.
+  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+  /// Returns the location of '('.
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+
+  /// Returns kind of the clause.
+  OpenMPTransparentKind getTransparentKind() const { return Kind; }
+
+  /// Returns location of clause kind.
+  SourceLocation getTransparentKindLoc() const { return KindLoc; }
+
+  child_range children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+
+  const_child_range children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
+  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_transparent;
+  }
+};
+
 /// This represents 'proc_bind' clause in the '#pragma omp ...'
 /// directive.
 ///
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h 
b/clang/include/clang/AST/RecursiveASTVisitor.h
index 8cb0a657023b4..5650d7411c4d1 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -3529,6 +3529,12 @@ bool 
RecursiveASTVisitor<Derived>::VisitOMPThreadsetClause(
   return true;
 }
 
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPTransparentClause(
+    OMPTransparentClause *) {
+  return true;
+}
+
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *) 
{
   return true;
diff --git a/clang/include/clang/Basic/OpenMPKinds.def 
b/clang/include/clang/Basic/OpenMPKinds.def
index 328a0747a82a8..8bac23dd1a06b 100644
--- a/clang/include/clang/Basic/OpenMPKinds.def
+++ b/clang/include/clang/Basic/OpenMPKinds.def
@@ -101,6 +101,9 @@
 #ifndef OPENMP_THREADSET_KIND
 #define OPENMP_THREADSET_KIND(Name)
 #endif
+#ifndef OPENMP_TRANSPARENT_KIND
+#define OPENMP_TRANSPARENT_KIND(Name)
+#endif
 
 // Static attributes for 'schedule' clause.
 OPENMP_SCHEDULE_KIND(static)
@@ -261,6 +264,11 @@ OPENMP_DOACROSS_MODIFIER(source_omp_cur_iteration)
 OPENMP_THREADSET_KIND(omp_pool)
 OPENMP_THREADSET_KIND(omp_team)
 
+OPENMP_TRANSPARENT_KIND(omp_not_impex)
+OPENMP_TRANSPARENT_KIND(omp_import)
+OPENMP_TRANSPARENT_KIND(omp_export)
+OPENMP_TRANSPARENT_KIND(omp_impex)
+
 #undef OPENMP_NUMTASKS_MODIFIER
 #undef OPENMP_NUMTHREADS_MODIFIER
 #undef OPENMP_GRAINSIZE_MODIFIER
@@ -291,3 +299,4 @@ OPENMP_THREADSET_KIND(omp_team)
 #undef OPENMP_DOACROSS_MODIFIER
 #undef OPENMP_ALLOCATE_MODIFIER
 #undef OPENMP_THREADSET_KIND
+#undef OPENMP_TRANSPARENT_KIND
diff --git a/clang/include/clang/Basic/OpenMPKinds.h 
b/clang/include/clang/Basic/OpenMPKinds.h
index c9ddbcd6d46c1..9bb841396a3b3 100644
--- a/clang/include/clang/Basic/OpenMPKinds.h
+++ b/clang/include/clang/Basic/OpenMPKinds.h
@@ -257,6 +257,13 @@ enum OpenMPThreadsetKind {
   OMPC_THREADSET_unknown
 };
 
+/// OpenMP modifiers for 'transparent' clause.
+enum OpenMPTransparentKind {
+#define OPENMP_TRANSPARENT_KIND(Name) OMPC_TRANSPARENT_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+  OMPC_TRANSPARENT_unknown
+};
+
 /// Number of allowed allocate-modifiers.
 static constexpr unsigned NumberOfOMPAllocateClauseModifiers =
     OMPC_ALLOCATE_unknown;
diff --git a/clang/include/clang/Sema/SemaOpenMP.h 
b/clang/include/clang/Sema/SemaOpenMP.h
index ba12b403d9b9a..7bdb2fd94bbd6 100644
--- a/clang/include/clang/Sema/SemaOpenMP.h
+++ b/clang/include/clang/Sema/SemaOpenMP.h
@@ -981,6 +981,12 @@ class SemaOpenMP : public SemaBase {
                                         SourceLocation StartLoc,
                                         SourceLocation LParenLoc,
                                         SourceLocation EndLoc);
+  /// Called on well-formed 'transparent' clause.
+  OMPClause *ActOnOpenMPTransparentClause(OpenMPTransparentKind Kind,
+                                          SourceLocation KindLoc,
+                                          SourceLocation StartLoc,
+                                          SourceLocation LParenLoc,
+                                          SourceLocation EndLoc);
   /// Called on well-formed 'proc_bind' clause.
   OMPClause *ActOnOpenMPProcBindClause(llvm::omp::ProcBindKind Kind,
                                        SourceLocation KindLoc,
diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index 59d94590e04d1..ba7e3f82f71e4 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -125,6 +125,7 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const 
OMPClause *C) {
   case OMPC_untied:
   case OMPC_mergeable:
   case OMPC_threadset:
+  case OMPC_transparent:
   case OMPC_threadprivate:
   case OMPC_groupprivate:
   case OMPC_flush:
@@ -2043,6 +2044,13 @@ void 
OMPClausePrinter::VisitOMPThreadsetClause(OMPThreadsetClause *Node) {
      << ")";
 }
 
+void OMPClausePrinter::VisitOMPTransparentClause(OMPTransparentClause *Node) {
+  OS << "transparent("
+     << getOpenMPSimpleClauseTypeName(OMPC_transparent,
+                                      unsigned(Node->getTransparentKind()))
+     << ")";
+}
+
 void OMPClausePrinter::VisitOMPProcBindClause(OMPProcBindClause *Node) {
   OS << "proc_bind("
      << getOpenMPSimpleClauseTypeName(OMPC_proc_bind,
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index c909e1bcecd38..e05d3bec98d5c 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -548,6 +548,8 @@ void OMPClauseProfiler::VisitOMPDefaultClause(const 
OMPDefaultClause *C) { }
 
 void OMPClauseProfiler::VisitOMPThreadsetClause(const OMPThreadsetClause *C) {}
 
+void OMPClauseProfiler::VisitOMPTransparentClause(const OMPTransparentClause 
*C) {}
+
 void OMPClauseProfiler::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
 
 void OMPClauseProfiler::VisitOMPUnifiedAddressClause(
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 3d41f2d197b81..ee0d5194d0116 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -219,6 +219,15 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind 
Kind, StringRef Str,
       return OMPC_THREADSET_unknown;
     return Type;
   }
+  case OMPC_transparent: {
+    unsigned Type = llvm::StringSwitch<unsigned>(Str)
+#define OPENMP_TRANSPARENT_KIND(Name) .Case(#Name, OMPC_TRANSPARENT_##Name)
+#include "clang/Basic/OpenMPKinds.def"
+                        .Default(OMPC_TRANSPARENT_unknown);
+    if (LangOpts.OpenMP < 60)
+      return OMPC_TRANSPARENT_unknown;
+    return Type;
+  }
   case OMPC_num_threads: {
     unsigned Type = llvm::StringSwitch<unsigned>(Str)
 #define OPENMP_NUMTHREADS_MODIFIER(Name) .Case(#Name, OMPC_NUMTHREADS_##Name)
@@ -584,6 +593,16 @@ const char 
*clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
 #include "clang/Basic/OpenMPKinds.def"
     }
     llvm_unreachable("Invalid OpenMP 'threadset' clause modifier");
+  case OMPC_transparent:
+    switch (Type) {
+    case OMPC_TRANSPARENT_unknown:
+      return "unknown";
+#define OPENMP_TRANSPARENT_KIND(Name)                                          
  \
+  case OMPC_TRANSPARENT_##Name:                                                
  \
+    return #Name;
+#include "clang/Basic/OpenMPKinds.def"
+    }
+    llvm_unreachable("Invalid OpenMP 'transparent' clause modifier");
   case OMPC_unknown:
   case OMPC_threadprivate:
   case OMPC_groupprivate:
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp 
b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 121de42248e3b..9e74c1420d228 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -3732,6 +3732,7 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, 
SourceLocation Loc,
     PriorityFlag = 0x20,
     DetachableFlag = 0x40,
     FreeAgentFlag = 0x80,
+    TransparentFlag = 0x100,
   };
   unsigned Flags = Data.Tied ? TiedFlag : 0;
   bool NeedsCleanup = false;
@@ -3746,6 +3747,9 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, 
SourceLocation Loc,
     if (Kind == OMPC_THREADSET_omp_pool)
       Flags = Flags | FreeAgentFlag;
   }
+  if (const auto *Clause = D.getSingleClause<OMPTransparentClause>()) {
+    Flags |= TransparentFlag;
+  }
   if (Data.Priority.getInt())
     Flags = Flags | PriorityFlag;
   if (D.hasClausesOfKind<OMPDetachClause>())
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 31bc941e6a015..60e463ba3f8a2 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -3222,6 +3222,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind 
DKind,
       Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
     break;
   case OMPC_threadset:
+  case OMPC_transparent:
   case OMPC_fail:
   case OMPC_proc_bind:
   case OMPC_atomic_default_mem_order:
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 256f9521b3a7e..fca76bfb232a0 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -17220,6 +17220,11 @@ OMPClause *SemaOpenMP::ActOnOpenMPSimpleClause(
     Res = 
ActOnOpenMPThreadsetClause(static_cast<OpenMPThreadsetKind>(Argument),
                                      ArgumentLoc, StartLoc, LParenLoc, EndLoc);
     break;
+  case OMPC_transparent:
+    Res = ActOnOpenMPTransparentClause(
+        static_cast<OpenMPTransparentKind>(Argument), ArgumentLoc, StartLoc,
+        LParenLoc, EndLoc);
+    break;
   case OMPC_if:
   case OMPC_final:
   case OMPC_num_threads:
@@ -17376,6 +17381,23 @@ OMPClause 
*SemaOpenMP::ActOnOpenMPThreadsetClause(OpenMPThreadsetKind Kind,
       OMPThreadsetClause(Kind, KindLoc, StartLoc, LParenLoc, EndLoc);
 }
 
+OMPClause *SemaOpenMP::ActOnOpenMPTransparentClause(OpenMPTransparentKind Kind,
+                                                    SourceLocation KindLoc,
+                                                    SourceLocation StartLoc,
+                                                    SourceLocation LParenLoc,
+                                                    SourceLocation EndLoc) {
+  if (Kind == OMPC_TRANSPARENT_unknown) {
+    Diag(KindLoc, diag::err_omp_unexpected_clause_value)
+        << getListOfPossibleValues(OMPC_transparent, /*First=*/0,
+                                   /*Last=*/unsigned(OMPC_TRANSPARENT_unknown))
+        << getOpenMPClauseName(OMPC_transparent);
+    return nullptr;
+  }
+
+  return new (getASTContext())
+      OMPTransparentClause(Kind, KindLoc, StartLoc, LParenLoc, EndLoc);
+}
+
 OMPClause *SemaOpenMP::ActOnOpenMPProcBindClause(ProcBindKind Kind,
                                                  SourceLocation KindKwLoc,
                                                  SourceLocation StartLoc,
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index dffd7c1def8e2..352079e13071b 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -10625,6 +10625,13 @@ 
TreeTransform<Derived>::TransformOMPThreadsetClause(OMPThreadsetClause *C) {
   return C;
 }
 
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPTransparentClause(OMPTransparentClause *C) 
{
+  // No need to rebuild this clause, no template-dependent parameters.
+  return C;
+}
+
 template <typename Derived>
 OMPClause *
 TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
diff --git a/clang/lib/Serialization/ASTReader.cpp 
b/clang/lib/Serialization/ASTReader.cpp
index d5528219bb7d5..9a415aab71be6 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -11258,6 +11258,9 @@ OMPClause *OMPClauseReader::readClause() {
   case llvm::omp::OMPC_threadset:
     C = new (Context) OMPThreadsetClause();
     break;
+  case llvm::omp::OMPC_transparent:
+    C = new (Context) OMPTransparentClause();
+    break;
   case llvm::omp::OMPC_read:
     C = new (Context) OMPReadClause();
     break;
@@ -11672,6 +11675,15 @@ void 
OMPClauseReader::VisitOMPThreadsetClause(OMPThreadsetClause *C) {
   C->setThreadsetKind(TKind);
 }
 
+void OMPClauseReader::VisitOMPTransparentClause(OMPTransparentClause *C) {
+  C->setLParenLoc(Record.readSourceLocation());
+  SourceLocation TransparentKindLoc = Record.readSourceLocation();
+  C->setTransparentKindLoc(TransparentKindLoc);
+  OpenMPTransparentKind TKind =
+      static_cast<OpenMPTransparentKind>(Record.readInt());
+  C->setTransparentKind(TKind);
+}
+
 void OMPClauseReader::VisitOMPProcBindClause(OMPProcBindClause *C) {
   C->setProcBindKind(static_cast<llvm::omp::ProcBindKind>(Record.readInt()));
   C->setLParenLoc(Record.readSourceLocation());
diff --git a/clang/lib/Serialization/ASTWriter.cpp 
b/clang/lib/Serialization/ASTWriter.cpp
index b1fd151790d96..34ee0599c33c5 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -7918,6 +7918,12 @@ void 
OMPClauseWriter::VisitOMPThreadsetClause(OMPThreadsetClause *C) {
   Record.writeEnum(C->getThreadsetKind());
 }
 
+void OMPClauseWriter::VisitOMPTransparentClause(OMPTransparentClause *C) {
+  Record.AddSourceLocation(C->getLParenLoc());
+  Record.AddSourceLocation(C->getTransparentKindLoc());
+  Record.writeEnum(C->getTransparentKind());
+}
+
 void OMPClauseWriter::VisitOMPProcBindClause(OMPProcBindClause *C) {
   Record.push_back(unsigned(C->getProcBindKind()));
   Record.AddSourceLocation(C->getLParenLoc());
diff --git a/clang/test/OpenMP/task_ast_print.cpp 
b/clang/test/OpenMP/task_ast_print.cpp
index b059f187156ee..d3108236b40df 100644
--- a/clang/test/OpenMP/task_ast_print.cpp
+++ b/clang/test/OpenMP/task_ast_print.cpp
@@ -205,10 +205,21 @@ int main(int argc, char **argv) {
 #pragma omp task threadset(omp_pool)
 #pragma omp task threadset(omp_team)
   foo();
+
+#pragma omp task transparent(omp_not_impex)
+#pragma omp task transparent(omp_import)
+#pragma omp task transparent(omp_export)
+#pragma omp task transparent(omp_impex)
+  foo();
 #endif
   // CHECK60: #pragma omp task threadset(omp_pool)
   // CHECK60: #pragma omp task threadset(omp_team)
   // CHECK60-NEXT: foo();
+  // CHECK60: #pragma omp task transparent(omp_not_impex)
+  // CHECK60: #pragma omp task transparent(omp_import)
+  // CHECK60: #pragma omp task transparent(omp_export)
+  // CHECK60: #pragma omp task transparent(omp_impex)
+  // CHECK60-NEXT: foo();
   return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x);
 }
 
diff --git a/clang/test/OpenMP/task_codegen.cpp 
b/clang/test/OpenMP/task_codegen.cpp
index ba8e6945de9d0..6c3bad672e4ba 100644
--- a/clang/test/OpenMP/task_codegen.cpp
+++ b/clang/test/OpenMP/task_codegen.cpp
@@ -231,6 +231,22 @@ void test_threadset()
   {
   }
 }
+
+void test_transparent()
+{
+#pragma omp task transparent(omp_not_impex)
+  {
+  }
+#pragma omp task transparent(omp_import)
+  {
+  }
+#pragma omp task transparent(omp_export)
+  {
+  }
+#pragma omp task transparent(omp_impex)
+  {
+  }
+}
 #endif // OMP60
 
 #endif
@@ -10276,3 +10292,32 @@ void test_threadset()
 // CHECK6-NEXT:       call i32 @__kmpc_global_thread_num(ptr 
@[[GLOB_PTR2:[0-9]+]])
 // CHECK6-NEXT:       call i32 @__kmpc_omp_task(ptr @1, i32 
%omp_global_thread_num4, ptr %3)
 // CHECK6-NEXT:       ret void
+
+// CHECK6-LABEL: define void @_Z16test_transparentv() #1 {
+// CHECK6-NEXT:  entry:
+// CHECK6-NEXT:       [[AGG_CAPTURED:%.*]] = alloca [[STRUCT_ANON_27:%.*]], 
align 1
+// CHECK6-NEXT:       [[AGG_CAPTURED2:%.*]] = alloca [[STRUCT_ANON_29:%.*]], 
align 1
+// CHECK6-NEXT:       [[AGG_CAPTURED5:%.*]] = alloca [[STRUCT_ANON_31:%.*]], 
align 1
+// CHECK6-NEXT:       [[AGG_CAPTURED8:%.*]] = alloca [[STRUCT_ANON_33:%.*]], 
align 1
+// CHECK6-NEXT:       [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 
@__kmpc_global_thread_num(ptr @31)
+// CHECK6-NEXT:       [[TMP0:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, 
i32 [[OMP_GLOBAL_THREAD_NUM]], i32 257, i64 40, i64 1, ptr 
@.omp_task_entry..[[ENTRY1:[0-9]+]])
+// CHECK6-NEXT:       [[TMP1:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP0]], i32 0, i32 0
+// CHECK6-NEXT:       [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 
@__kmpc_global_thread_num(ptr @31)
+// CHECK6-NEXT:       [[TMP2:%.*]] = call i32 @__kmpc_omp_task(ptr @1, i32 
[[OMP_GLOBAL_THREAD_NUM1]], ptr [[TMP0]])
+// CHECK6-NEXT:       [[OMP_GLOBAL_THREAD_NUM3:%.*]] = call i32 
@__kmpc_global_thread_num(ptr @33)
+// CHECK6-NEXT:       [[TMP3:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, 
i32 [[OMP_GLOBAL_THREAD_NUM3]], i32 257, i64 40, i64 1, ptr 
@.omp_task_entry..[[ENTRY2:[0-9]+]])
+// CHECK6-NEXT:       [[TMP4:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP3]], i32 0, i32 0
+// CHECK6-NEXT:       [[OMP_GLOBAL_THREAD_NUM4:%.*]] = call i32 
@__kmpc_global_thread_num(ptr @33)
+// CHECK6-NEXT:       [[TMP5:%.*]] = call i32 @__kmpc_omp_task(ptr @1, i32 
[[OMP_GLOBAL_THREAD_NUM4]], ptr [[TMP3]])
+// CHECK6-NEXT:       [[OMP_GLOBAL_THREAD_NUM6:%.*]] = call i32 
@__kmpc_global_thread_num(ptr @35)
+// CHECK6-NEXT:       [[TMP6:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, 
i32 [[OMP_GLOBAL_THREAD_NUM6]], i32 257, i64 40, i64 1, ptr 
@.omp_task_entry..[[ENTRY3:[0-9]+]])
+// CHECK6-NEXT:       [[TMP7:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP6]], i32 0, i32 0
+// CHECK6-NEXT:       [[OMP_GLOBAL_THREAD_NUM7:%.*]] = call i32 
@__kmpc_global_thread_num(ptr @35)
+// CHECK6-NEXT:       [[TMP8:%.*]] = call i32 @__kmpc_omp_task(ptr @1, i32 
[[OMP_GLOBAL_THREAD_NUM7]], ptr [[TMP6]])
+// CHECK6-NEXT:       [[OMP_GLOBAL_THREAD_NUM9:%.*]] = call i32 
@__kmpc_global_thread_num(ptr @37)
+// CHECK6-NEXT:       [[TMP9:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, 
i32 [[OMP_GLOBAL_THREAD_NUM9]], i32 257, i64 40, i64 1, ptr 
@.omp_task_entry..[[ENTRY4:[0-9]+]])
+// CHECK6-NEXT:       [[TMP10:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP9]], i32 0, i32 0
+// CHECK6-NEXT:       [[OMP_GLOBAL_THREAD_NUM10:%.*]] = call i32 
@__kmpc_global_thread_num(ptr @37)
+// CHECK6-NEXT:       [[TMP11:%.*]] = call i32 @__kmpc_omp_task(ptr @1, i32 
[[OMP_GLOBAL_THREAD_NUM10]], ptr [[TMP9]])
+// CHECK6-NEXT:  ret void
+// CHECK6-NEXT:}
diff --git a/clang/test/OpenMP/task_transparent_messages.cpp 
b/clang/test/OpenMP/task_transparent_messages.cpp
new file mode 100644
index 0000000000000..465b8008701f5
--- /dev/null
+++ b/clang/test/OpenMP/task_transparent_messages.cpp
@@ -0,0 +1,98 @@
+// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp -fopenmp-version=45 
-std=c++11 -ferror-limit 200 -o - %s
+// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp -fopenmp-version=50 
-std=c++11 -ferror-limit 200 -o - %s
+// RUN: %clang_cc1 -verify=expected,omp51 -fopenmp -fopenmp-version=51 
-std=c++11 -ferror-limit 200 -o - %s
+// RUN: %clang_cc1 -verify=expected -DOMP60 -fopenmp -fopenmp-version=60 
-std=c++11 -ferror-limit 200 -o - %s
+
+// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp-simd -fopenmp-version=45 
-std=c++11 -ferror-limit 200 -o - %s
+// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp-simd -fopenmp-version=50 
-std=c++11 -ferror-limit 200 -o - %s
+// RUN: %clang_cc1 -verify=expected,omp51 -fopenmp-simd -fopenmp-version=51 
-std=c++11 -ferror-limit 200 -o - %s
+// RUN: %clang_cc1 -verify=expected -DOMP60 -fopenmp-simd -fopenmp-version=60 
-std=c++11 -ferror-limit 200 -o - %s
+
+#ifdef OMP60
+struct ComplexStruct {
+  int data[10];
+  struct InnerStruct {
+    float value;
+  } inner;
+};
+
+template <typename T>
+class TransparentTemplate {
+public:
+  void TestTaskImport() {
+    #pragma omp task transparent(omp_import)
+    {
+      T temp;
+    }
+  }
+  void TestTaskLoopImpex() {
+    #pragma omp taskloop transparent(omp_impex)
+    for (int i = 0; i < 10; ++i) {}
+  }
+};
+
+void TestTaskTransparent() {
+  int a;
+#pragma omp task transparent(omp_not_impex)
+#pragma omp task transparent(omp_import)
+#pragma omp task transparent(omp_export)
+#pragma omp task transparent(omp_impex)
+
+#pragma omp task transparent(omp_import) if(1)
+#pragma omp task transparent(omp_impex) priority(5)
+#pragma omp task transparent(omp_not_impex) depend(out: a)
+#pragma omp parallel
+  {
+#pragma omp task transparent(omp_export)
+    {
+#pragma omp taskloop transparent(omp_not_impex)
+      for (int i = 0; i < 5; ++i) {}
+    }
+  }
+
+  TransparentTemplate<int> obj;
+  obj.TestTaskImport();
+  obj.TestTaskLoopImpex();
+}
+
+void TestTaskTransparentInvalidArgs() {
+  #pragma omp task transparent(invalid_arg) // expected-error {{expected 
'omp_not_impex', 'omp_import', 'omp_export' or 'omp_impex' in OpenMP clause 
'transparent'}}
+  #pragma omp task transparent(123) // expected-error {{expected 
'omp_not_impex', 'omp_import', 'omp_export' or 'omp_impex' in OpenMP clause 
'transparent'}}
+#pragma omp task transparent(omp_import, omp_not_import) // expected-error 
{{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp task transparent() // expected-error {{expected 'omp_not_impex', 
'omp_import', 'omp_export' or 'omp_impex' in OpenMP clause 'transparent'}}
+  {}
+}
+
+void TestTaskloopTransparent() {
+  #pragma omp taskloop transparent(omp_import)
+  for (int i = 0; i < 10; ++i) {}
+  #pragma omp taskloop transparent(omp_export)
+  for (int i = 0; i < 10; ++i) {}
+  #pragma omp taskloop transparent(omp_not_impex) grainsize(5)
+  for (int i = 0; i < 10; ++i) {}
+  #pragma omp taskloop transparent(omp_impex) num_tasks(2)
+  for (int i = 0; i < 10; ++i) {}
+}
+
+
+void TestTaskLoopTransparentInvalidArgs() {
+  #pragma omp taskloop transparent(invalid_arg) // expected-error {{expected 
'omp_not_impex', 'omp_import', 'omp_export' or 'omp_impex' in OpenMP clause 
'transparent'}}
+  for (int i = 0; i < 10; ++i) {}
+  #pragma omp taskloop transparent(123) // expected-error {{expected 
'omp_not_impex', 'omp_import', 'omp_export' or 'omp_impex' in OpenMP clause 
'transparent'}}
+  for (int i = 0; i < 10; ++i) {}
+#pragma omp taskloop transparent(omp_not_import, omp_import) // 
expected-error{{expected ')'}} // expected-note{{to match this '('}}  // 
expected-error{{expected 'omp_not_impex', 'omp_import', 'omp_export' or 
'omp_impex' in OpenMP clause 'transparent'}}
+  for (int i = 0; i < 10; ++i) {}
+  #pragma omp taskloop transparent() // expected-error {{expected 
'omp_not_impex', 'omp_import', 'omp_export' or 'omp_impex' in OpenMP clause 
'transparent'}}
+  for (int i = 0; i < 10; ++i) {}
+}
+
+#else
+void TransparentClauseNotSupported() {
+  #pragma omp task transparent(omp_pool) // omp45-error {{unexpected OpenMP 
clause 'transparent' in directive '#pragma omp task'}} omp50-error {{unexpected 
OpenMP clause 'transparent' in directive '#pragma omp task'}} omp51-error 
{{unexpected OpenMP clause 'transparent' in directive '#pragma omp task'}}
+  #pragma omp task transparent(omp_team) // omp45-error {{unexpected OpenMP 
clause 'transparent' in directive '#pragma omp task'}} omp50-error {{unexpected 
OpenMP clause 'transparent' in directive '#pragma omp task'}} omp51-error 
{{unexpected OpenMP clause 'transparent' in directive '#pragma omp task'}}
+  #pragma omp taskloop transparent(omp_team) // omp45-error {{unexpected 
OpenMP clause 'transparent' in directive '#pragma omp taskloop'}} omp50-error 
{{unexpected OpenMP clause 'transparent' in directive '#pragma omp taskloop'}} 
omp51-error {{unexpected OpenMP clause 'transparent' in directive '#pragma omp 
taskloop'}}
+  for (int i = 0; i < 10; ++i) {}
+  #pragma omp taskloop transparent(omp_pool) // omp45-error {{unexpected 
OpenMP clause 'transparent' in directive '#pragma omp taskloop'}} omp50-error 
{{unexpected OpenMP clause 'transparent' in directive '#pragma omp taskloop'}} 
omp51-error {{unexpected OpenMP clause 'transparent' in directive '#pragma omp 
taskloop'}}
+  for (int i = 0; i < 10; ++i) {}
+}
+#endif
diff --git a/clang/test/OpenMP/taskloop_ast_print.cpp 
b/clang/test/OpenMP/taskloop_ast_print.cpp
index e4bf20af5d78e..dedbcf4c66bec 100644
--- a/clang/test/OpenMP/taskloop_ast_print.cpp
+++ b/clang/test/OpenMP/taskloop_ast_print.cpp
@@ -97,12 +97,34 @@ int main(int argc, char **argv) {
     foo();
   }
 }
+
+#pragma omp taskloop transparent(omp_not_impex)
+  for (int i = 0; i < 10; ++i) {
+#pragma omp task transparent(omp_import)
+    for (int i = 0; i < 10; ++i) {
+#pragma omp task transparent(omp_export)
+      for (int i = 0; i < 10; ++i) {
+#pragma omp task transparent(omp_impex)
+       foo();
+      }
+    }
+  }
 #endif
  // CHECK60: #pragma omp taskloop threadset(omp_team)
  // CHECK60-NEXT: for (int i = 0; i < 10; ++i) {
  // CHECK60: #pragma omp taskloop threadset(omp_pool)
  // CHECK60-NEXT: for (int j = 0; j < 10; ++j) {
  // CHECK60-NEXT: foo();
+
+// CHECK60: #pragma omp taskloop transparent(omp_not_impex)
+// CHECK60-NEXT: for (int i = 0; i < 10; ++i) {
+// CHECK60-NEXT: #pragma omp task transparent(omp_import)
+// CHECK60-NEXT: for (int i = 0; i < 10; ++i) {
+// CHECK60-NEXT: #pragma omp task transparent(omp_export)
+// CHECK60-NEXT: for (int i = 0; i < 10; ++i) {
+// CHECK60-NEXT: #pragma omp task transparent(omp_impex)
+// CHECK60-NEXT: foo();
+
   return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0]));
 }
 
diff --git a/clang/test/OpenMP/taskloop_codegen.cpp 
b/clang/test/OpenMP/taskloop_codegen.cpp
index d1197607a2684..2a1af769fb8b2 100644
--- a/clang/test/OpenMP/taskloop_codegen.cpp
+++ b/clang/test/OpenMP/taskloop_codegen.cpp
@@ -256,6 +256,23 @@ void test_threadset()
   for (int i = 0; i < 10; ++i) {
   }
 }
+
+void test_transparent()
+{
+#pragma omp taskloop transparent(omp_not_impex)
+  for (int i = 0; i < 10; ++i) {
+  }
+#pragma omp taskloop transparent(omp_import)
+  for (int i = 0; i < 10; ++i) {
+  }
+#pragma omp taskloop transparent(omp_export)
+  for (int i = 0; i < 10; ++i) {
+  }
+#pragma omp taskloop transparent(omp_impex)
+  for (int i = 0; i < 10; ++i) {
+  }
+}
+
 #endif // OMP60
 // CHECK6-LABEL: define void @_Z14test_threadsetv()
 // CHECK6-NEXT:  entry:
@@ -294,4 +311,74 @@ void test_threadset()
 // CHECK6-NEXT:       call void @__kmpc_end_taskgroup(ptr @1, i32 %[[TID0:.*]])
 // CHECK6-NEXT:       ret void
 
+// CHECK6: define void @_Z16test_transparentv
+// CHECK6: entry:
+// CHECK6:  [[AGG_CAPTURED:%.*]] = alloca [[STRUCT_ANON_18:%.*]], align 1
+// CHECK6:  [[TMP:%.*]] = alloca i32, align 4
+// CHECK6:  [[AGG_CAPTURED1:%.*]] = alloca [[STRUCT_ANON_20:%.*]], align 1
+// CHECK6:  [[TMP2:%.*]] = alloca i32, align 4
+// CHECK6:  [[AGG_CAPTURED3:%.*]] = alloca [[STRUCT_ANON_22:%.*]], align 1
+// CHECK6:  [[TMP4:%.*]] = alloca i32, align 4
+// CHECK6:  [[AGG_CAPTURED5:%.*]] = alloca [[STRUCT_ANON_24:%.*]], align 1
+// CHECK6:  [[TMP6:%.*]] = alloca i32, align 4
+// CHECK6:  [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @1)
+// CHECK6:  call void @__kmpc_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6:  [[TMP1:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 
[[TMP0]], i32 257, i64 80, i64 1, ptr @.omp_task_entry..[[ENTRY1:[0-9]+]])
+// CHECK6:  [[TMP2:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP1]], i32 0, i32 0
+// CHECK6:  [[TMP3:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP2]], i32 0, i32 5
+// CHECK6:  store i64 0, ptr [[TMP3]], align 8
+// CHECK6:  [[TMP4:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP2]], i32 0, i32 6
+// CHECK6:  store i64 9, ptr [[TMP4]], align 8
+// CHECK6:  [[TMP5:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP2]], i32 0, i32 7
+// CHECK6:  store i64 1, ptr [[TMP5]], align 8
+// CHECK6:  [[TMP6:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP2]], i32 0, i32 9
+// CHECK6:  call void @llvm.memset.p0.i64(ptr align 8 [[TMP6]], i8 0, i64 8, 
i1 false)
+// CHECK6:  [[TMP7:%.*]] = load i64, ptr [[TMP5]], align 8
+// CHECK6:  call void @__kmpc_taskloop(ptr @1, i32 [[TMP0]], ptr [[TMP1]], i32 
1, ptr [[TMP3]], ptr [[TMP4]], i64 [[TMP7]], i32 1, i32 0, i64 0, ptr null)
+// CHECK6:  call void @__kmpc_end_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6:  call void @__kmpc_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6:  [[TMP8:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 
[[TMP0]], i32 257, i64 80, i64 1, ptr @.omp_task_entry..[[ENTRY2:[0-9]+]])
+// CHECK6:  [[TMP9:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP8]], i32 0, i32 0
+// CHECK6:  [[TMP10:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP9]], i32 0, i32 5
+// CHECK6:  store i64 0, ptr [[TMP10]], align 8
+// CHECK6:  [[TMP11:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP9]], i32 0, i32 6
+// CHECK6:  store i64 9, ptr [[TMP11]], align 8
+// CHECK6:  [[TMP12:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP9]], i32 0, i32 7
+// CHECK6:  store i64 1, ptr [[TMP12]], align 8
+// CHECK6:  [[TMP13:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP9]], i32 0, i32 9
+// CHECK6:  call void @llvm.memset.p0.i64(ptr align 8 [[TMP13]], i8 0, i64 8, 
i1 false)
+// CHECK6:  [[TMP14:%.*]] = load i64, ptr [[TMP12]], align 8
+// CHECK6:  call void @__kmpc_taskloop(ptr @1, i32 [[TMP0]], ptr [[TMP8]], i32 
1, ptr [[TMP10]], ptr [[TMP11]], i64 [[TMP14]], i32 1, i32 0, i64 0, ptr null)
+// CHECK6:  call void @__kmpc_end_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6:  call void @__kmpc_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6:  [[TMP15:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 
[[TMP0]], i32 257, i64 80, i64 1, ptr @.omp_task_entry..22)
+// CHECK6:  [[TMP16:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP15]], i32 0, i32 0
+// CHECK6:  [[TMP17:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP16]], i32 0, i32 5
+// CHECK6:  store i64 0, ptr [[TMP17]], align 8
+// CHECK6:  [[TMP18:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP16]], i32 0, i32 6
+// CHECK6:  store i64 9, ptr [[TMP18]], align 8
+// CHECK6:  [[TMP19:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP16]], i32 0, i32 7
+// CHECK6:  store i64 1, ptr [[TMP19]], align 8
+// CHECK6:  [[TMP20:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP16]], i32 0, i32 9
+// CHECK6:  call void @llvm.memset.p0.i64(ptr align 8 [[TMP20]], i8 0, i64 8, 
i1 false)
+// CHECK6:  [[TMP21:%.*]] = load i64, ptr [[TMP19]], align 8
+// CHECK6:  call void @__kmpc_taskloop(ptr @1, i32 [[TMP0]], ptr [[TMP15]], 
i32 1, ptr [[TMP17]], ptr [[TMP18]], i64 [[TMP21]], i32 1, i32 0, i64 0, ptr 
null)
+// CHECK6:  call void @__kmpc_end_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6:  call void @__kmpc_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6:  [[TMP22:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 
[[TMP0]], i32 257, i64 80, i64 1, ptr @.omp_task_entry..24)
+// CHECK6:  [[TMP23:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP22]], i32 0, i32 0
+// CHECK6:  [[TMP24:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP23]], i32 0, i32 5
+// CHECK6:  store i64 0, ptr [[TMP24]], align 8
+// CHECK6:  [[TMP25:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP23]], i32 0, i32 6
+// CHECK6:  store i64 9, ptr [[TMP25]], align 8
+// CHECK6:  [[TMP26:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP23]], i32 0, i32 7
+// CHECK6:  store i64 1, ptr [[TMP26]], align 8
+// CHECK6:  [[TMP27:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP23]], i32 0, i32 9
+// CHECK6:  call void @llvm.memset.p0.i64(ptr align 8 [[TMP27]], i8 0, i64 8, 
i1 false)
+// CHECK6:  [[TMP28:%.*]] = load i64, ptr [[TMP26]], align 8
+// CHECK6:  call void @__kmpc_taskloop(ptr @1, i32 [[TMP0]], ptr [[TMP22]], 
i32 1, ptr [[TMP24]], ptr [[TMP25]], i64 [[TMP28]], i32 1, i32 0, i64 0, ptr 
null)
+// CHECK6:  call void @__kmpc_end_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6:  ret void
+// CHECK6:}
+
 #endif
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 08776d9bcabfc..6230bab9ff5d8 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -2408,6 +2408,8 @@ void OMPClauseEnqueue::VisitOMPFailClause(const 
OMPFailClause *) {}
 
 void OMPClauseEnqueue::VisitOMPThreadsetClause(const OMPThreadsetClause *) {}
 
+void OMPClauseEnqueue::VisitOMPTransparentClause(const OMPTransparentClause *) 
{}
+
 void OMPClauseEnqueue::VisitOMPAbsentClause(const OMPAbsentClause *) {}
 
 void OMPClauseEnqueue::VisitOMPHoldsClause(const OMPHoldsClause *) {}
diff --git a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h 
b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
index d7f0e3a3d49da..ccdc8e1f744c0 100644
--- a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
+++ b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
@@ -1175,6 +1175,14 @@ struct ThreadsetT {
   ThreadsetPolicy v;
 };
 
+// V6.0: [17.9.6] `transparent` clause
+template <typename T, typename I, typename E> //
+struct TransparentT {
+  ENUM(TransparentPolicy, Omp_not_impex, Omp_import, Omp_export, Omp_impex);
+  using WrapperTrait = std::true_type;
+  TransparentPolicy v;
+};
+
 // V5.2: [5.9.1] `to` clause
 template <typename T, typename I, typename E> //
 struct ToT {
@@ -1360,7 +1368,7 @@ using WrapperClausesT = std::variant<
     ProcBindT<T, I, E>, ReverseOffloadT<T, I, E>, SafelenT<T, I, E>,
     SelfMapsT<T, I, E>, SeverityT<T, I, E>, SharedT<T, I, E>, SimdlenT<T, I, 
E>,
     SizesT<T, I, E>, PermutationT<T, I, E>, ThreadLimitT<T, I, E>,
-    ThreadsetT<T, I, E>, UnifiedAddressT<T, I, E>,
+    ThreadsetT<T, I, E>, TransparentT<T, I, E>, UnifiedAddressT<T, I, E>,
     UnifiedSharedMemoryT<T, I, E>, UniformT<T, I, E>, UpdateT<T, I, E>,
     UseDeviceAddrT<T, I, E>, UseDevicePtrT<T, I, E>, UsesAllocatorsT<T, I, E>>;
 
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td 
b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index 208609f64f418..26254bc9f3cfa 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -548,6 +548,7 @@ def OMPC_To : Clause<[Spelling<"to">]> {
   let flangClass = "OmpToClause";
 }
 def OMPC_Transparent : Clause<[Spelling<"transparent">]> {
+  let clangClass = "OMPTransparentClause";
   let flangClass = "OmpTransparentClause";
   let isValueOptional = true;
 }

>From a2413000f3782636ff366df178ee3366d9eabc7b Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <[email protected]>
Date: Thu, 6 Nov 2025 09:25:45 -0800
Subject: [PATCH 2/5] Fix format

---
 clang/include/clang/AST/OpenMPClause.h | 4 ++--
 clang/lib/AST/StmtProfile.cpp          | 3 ++-
 clang/lib/Basic/OpenMPKinds.cpp        | 4 ++--
 clang/tools/libclang/CIndex.cpp        | 3 ++-
 4 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/clang/include/clang/AST/OpenMPClause.h 
b/clang/include/clang/AST/OpenMPClause.h
index a56b69fa39754..ddfde86e18789 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -1548,8 +1548,8 @@ class OMPTransparentClause final : public OMPClause {
   /// \param LParenLoc Location of '('.
   /// \param EndLoc Ending location of the clause.
   OMPTransparentClause(OpenMPTransparentKind A, SourceLocation ALoc,
-                     SourceLocation StartLoc, SourceLocation LParenLoc,
-                     SourceLocation EndLoc)
+                       SourceLocation StartLoc, SourceLocation LParenLoc,
+                       SourceLocation EndLoc)
       : OMPClause(llvm::omp::OMPC_transparent, StartLoc, EndLoc),
         LParenLoc(LParenLoc), Kind(A), KindLoc(ALoc) {}
 
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index e05d3bec98d5c..cd1657525cceb 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -548,7 +548,8 @@ void OMPClauseProfiler::VisitOMPDefaultClause(const 
OMPDefaultClause *C) { }
 
 void OMPClauseProfiler::VisitOMPThreadsetClause(const OMPThreadsetClause *C) {}
 
-void OMPClauseProfiler::VisitOMPTransparentClause(const OMPTransparentClause 
*C) {}
+void OMPClauseProfiler::VisitOMPTransparentClause(
+    const OMPTransparentClause *C) {}
 
 void OMPClauseProfiler::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
 
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index ee0d5194d0116..e19f0c27c8ab3 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -597,8 +597,8 @@ const char 
*clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
     switch (Type) {
     case OMPC_TRANSPARENT_unknown:
       return "unknown";
-#define OPENMP_TRANSPARENT_KIND(Name)                                          
  \
-  case OMPC_TRANSPARENT_##Name:                                                
  \
+#define OPENMP_TRANSPARENT_KIND(Name)                                          
 \
+  case OMPC_TRANSPARENT_##Name:                                                
 \
     return #Name;
 #include "clang/Basic/OpenMPKinds.def"
     }
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 6230bab9ff5d8..faebf50488f8c 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -2408,7 +2408,8 @@ void OMPClauseEnqueue::VisitOMPFailClause(const 
OMPFailClause *) {}
 
 void OMPClauseEnqueue::VisitOMPThreadsetClause(const OMPThreadsetClause *) {}
 
-void OMPClauseEnqueue::VisitOMPTransparentClause(const OMPTransparentClause *) 
{}
+void OMPClauseEnqueue::VisitOMPTransparentClause(const OMPTransparentClause *) 
{
+}
 
 void OMPClauseEnqueue::VisitOMPAbsentClause(const OMPAbsentClause *) {}
 

>From c8fe05b0781b61cdd43ffff3390aea1e4c083fd7 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <[email protected]>
Date: Thu, 6 Nov 2025 09:33:00 -0800
Subject: [PATCH 3/5] Fix format and add PR # to doc

---
 clang/docs/OpenMPSupport.rst    | 2 +-
 clang/lib/Basic/OpenMPKinds.cpp | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/docs/OpenMPSupport.rst b/clang/docs/OpenMPSupport.rst
index 18b5b60ac6cdf..01c834d9ca7b3 100644
--- a/clang/docs/OpenMPSupport.rst
+++ b/clang/docs/OpenMPSupport.rst
@@ -490,7 +490,7 @@ implementation.
 
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
 | memscope clause for atomic and flush                        | 
:none:`unclaimed`         | :none:`unclaimed`         |                         
                                                 |
 
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
-| transparent clause (hull tasks)                             | 
:part:`partial`           | :none:`unclaimed`         |  To Add the PR#         
                                                               |
+| transparent clause (hull tasks)                             | 
:part:`partial`           | :none:`unclaimed`         |  
https://github.com/llvm/llvm-project/pull/166810                                
                                        |
 
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
 | rule-based compound directives                              | :part:`In 
Progress`       | :part:`In Progress`       | kparzysz                          
                                       |
 |                                                             |                
           |                           | Testing for Fortran missing            
                                  |
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index e19f0c27c8ab3..e7d8f646009da 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -597,8 +597,8 @@ const char 
*clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
     switch (Type) {
     case OMPC_TRANSPARENT_unknown:
       return "unknown";
-#define OPENMP_TRANSPARENT_KIND(Name)                                          
 \
-  case OMPC_TRANSPARENT_##Name:                                                
 \
+#define OPENMP_TRANSPARENT_KIND(Name)                                          
\
+  case OMPC_TRANSPARENT_##Name:                                                
\
     return #Name;
 #include "clang/Basic/OpenMPKinds.def"
     }

>From cc36c518437487cd202ea37d2830b9cfbd1e4246 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <[email protected]>
Date: Thu, 6 Nov 2025 09:40:18 -0800
Subject: [PATCH 4/5] Remove redundant comment

---
 clang/lib/Sema/TreeTransform.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 352079e13071b..33df9e934ecb3 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -10628,7 +10628,6 @@ 
TreeTransform<Derived>::TransformOMPThreadsetClause(OMPThreadsetClause *C) {
 template <typename Derived>
 OMPClause *
 TreeTransform<Derived>::TransformOMPTransparentClause(OMPTransparentClause *C) 
{
-  // No need to rebuild this clause, no template-dependent parameters.
   return C;
 }
 

>From bdb4b913240639137331f08fee550f48330b1ba5 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <[email protected]>
Date: Thu, 6 Nov 2025 09:52:17 -0800
Subject: [PATCH 5/5] Fix doc

---
 clang/docs/OpenMPSupport.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/docs/OpenMPSupport.rst b/clang/docs/OpenMPSupport.rst
index 01c834d9ca7b3..32aac6fbeb9c4 100644
--- a/clang/docs/OpenMPSupport.rst
+++ b/clang/docs/OpenMPSupport.rst
@@ -490,7 +490,7 @@ implementation.
 
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
 | memscope clause for atomic and flush                        | 
:none:`unclaimed`         | :none:`unclaimed`         |                         
                                                 |
 
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
-| transparent clause (hull tasks)                             | 
:part:`partial`           | :none:`unclaimed`         |  
https://github.com/llvm/llvm-project/pull/166810                                
                                        |
+| transparent clause (hull tasks)                             | 
:part:`partial`           | :none:`unclaimed`         |  
https://github.com/llvm/llvm-project/pull/166810                        |
 
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
 | rule-based compound directives                              | :part:`In 
Progress`       | :part:`In Progress`       | kparzysz                          
                                       |
 |                                                             |                
           |                           | Testing for Fortran missing            
                                  |

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to