[clang] [OpenMP][Clang] Support transparent clause with no argument provided. (PR #177684)
Zahira Ammarguellat via cfe-commits
cfe-commits at lists.llvm.org
Mon Jan 26 06:54:13 PST 2026
https://github.com/zahiraam updated https://github.com/llvm/llvm-project/pull/177684
>From a8c26d3a4fc030742349d8785259347f76f7978e Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Fri, 23 Jan 2026 13:38:50 -0800
Subject: [PATCH 1/2] [OpenMP][Clang] Support transparent clause with implicit
omp_impex when no argument is provided
---
clang/lib/AST/OpenMPClause.cpp | 5 ++++-
clang/lib/Parse/ParseOpenMP.cpp | 9 ++++++++-
clang/lib/Sema/SemaOpenMP.cpp | 4 ++++
clang/test/OpenMP/task_ast_print.cpp | 9 +++------
clang/test/OpenMP/task_codegen.cpp | 8 ++++++++
clang/test/OpenMP/taskloop_ast_print.cpp | 12 ++++++++----
clang/test/OpenMP/taskloop_codegen.cpp | 3 +++
7 files changed, 38 insertions(+), 12 deletions(-)
diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index 62d78660570de..9e7a8a48372c7 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -2057,7 +2057,10 @@ void OMPClausePrinter::VisitOMPThreadsetClause(OMPThreadsetClause *Node) {
void OMPClausePrinter::VisitOMPTransparentClause(OMPTransparentClause *Node) {
OS << "transparent(";
- Node->getImpexType()->printPretty(OS, nullptr, Policy, 0);
+ if (Node->getImpexType())
+ Node->getImpexType()->printPretty(OS, nullptr, Policy, 0);
+ else
+ OS << "omp_impex";
OS << ")";
}
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index ec62df83a203e..b7f2af9ca7b1f 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -3213,7 +3213,14 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
<< getOpenMPClauseName(CKind) << 0;
ErrorFound = true;
}
-
+ const Token CurTok = PP.LookAhead(0);
+ if (CKind == OMPC_transparent && CurTok.is(tok::annot_pragma_openmp_end)) {
+ SourceLocation Loc = ConsumeToken();
+ SourceLocation LLoc = Tok.getLocation();
+ Clause = Actions.OpenMP().ActOnOpenMPTransparentClause(nullptr, LLoc,
+ LLoc, Loc);
+ break;
+ }
if ((CKind == OMPC_ordered || CKind == OMPC_partial) &&
PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
Clause = ParseOpenMPClause(CKind, WrongDirective);
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 084abaf487bb8..55ebcb69cc8c7 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -17476,6 +17476,10 @@ OMPClause *SemaOpenMP::ActOnOpenMPTransparentClause(Expr *ImpexTypeArg,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc) {
+ if (!ImpexTypeArg) {
+ return new (getASTContext())
+ OMPTransparentClause(ImpexTypeArg, StartLoc, LParenLoc, EndLoc);
+ }
QualType Ty = ImpexTypeArg->getType();
if (const auto *TT = Ty->getAs<TypedefType>()) {
diff --git a/clang/test/OpenMP/task_ast_print.cpp b/clang/test/OpenMP/task_ast_print.cpp
index 4c59a7c7fafa1..d7c1da3db537c 100644
--- a/clang/test/OpenMP/task_ast_print.cpp
+++ b/clang/test/OpenMP/task_ast_print.cpp
@@ -16,12 +16,6 @@
typedef void *omp_depend_t;
typedef unsigned long omp_event_handle_t;
-typedef void **omp_impex_t;
-extern const omp_impex_t omp_not_impex;
-extern const omp_impex_t omp_import;
-extern const omp_impex_t omp_export;
-extern const omp_impex_t omp_impex;
-
void foo() {}
struct S1 {
@@ -250,6 +244,7 @@ int main(int argc, char **argv) {
#pragma omp task threadset(omp_team)
foo();
+#pragma omp task transparent
#pragma omp task transparent(omp_not_impex)
#pragma omp task transparent(omp_import)
#pragma omp task transparent(omp_export)
@@ -273,9 +268,11 @@ int main(int argc, char **argv) {
// CHECK60: #pragma omp task transparent(omp_import)
// CHECK60: #pragma omp taskloop transparent(omp_impex)
// CHECK60: #pragma omp task transparent(omp_import)
+ // CHECK60: #pragma omp taskloop transparent(omp_impex)
// CHECK60: #pragma omp task threadset(omp_pool)
// CHECK60: #pragma omp task threadset(omp_team)
// CHECK60-NEXT: foo();
+ // CHECK60: #pragma omp task transparent(omp_impex)
// CHECK60: #pragma omp task transparent(omp_not_impex)
// CHECK60-NEXT: #pragma omp task transparent(omp_import)
// CHECK60-NEXT: #pragma omp task transparent(omp_export)
diff --git a/clang/test/OpenMP/task_codegen.cpp b/clang/test/OpenMP/task_codegen.cpp
index faa9c3dfbcf61..5483d690e50a2 100644
--- a/clang/test/OpenMP/task_codegen.cpp
+++ b/clang/test/OpenMP/task_codegen.cpp
@@ -240,6 +240,8 @@ void test_threadset()
void test_transparent()
{
+#pragma omp task transparent
+ {}
#pragma omp task transparent(omp_not_impex)
{}
#pragma omp task transparent(omp_import)
@@ -10308,6 +10310,7 @@ void test_transparent()
// 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: [[AGG_CAPTURED11:%.*]] = alloca [[STRUCT_ANON_35:%.*]], align 1
// CHECK6-NEXT: [[V:%.*]] = alloca ptr, align 8
// CHECK6-NEXT: [[AGG_CAPTURED11:%.*]] = alloca [[STRUCT_ANON_35:%.*]], align 1
//CHECK6-NEXT: [[AGG_CAPTURED14:%.*]] = alloca [[STRUCT_ANON_37:%.*]], align 1
@@ -10348,5 +10351,10 @@ void test_transparent()
// CHECK6-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP18]], i32 0, i32 0
// CHECK6-NEXT: [[OMP_GLOBAL_THREAD_NUM19:%.*]] = call i32 @__kmpc_global_thread_num(ptr @43)
// CHECK6-NEXT: [[TMP20:%.*]] = call i32 @__kmpc_omp_task(ptr @1, i32 [[OMP_GLOBAL_THREAD_NUM19]], ptr [[TMP18]])
+// CHECK6-NEXT: [[OMP_GLOBAL_THREAD_NUM21:%.*]] = call i32 @__kmpc_global_thread_num(ptr @45)
+// CHECK6-NEXT: [[TMP21:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 [[OMP_GLOBAL_THREAD_NUM21]], i32 257, i64 40, i64 1, ptr @.omp_task_entry..[[ENTRY43:[0-9]+]])
+// CHECK6-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP21]], i32 0, i32 0
+// CHECK6-NEXT: [[OMP_GLOBAL_THREAD_NUM22:%.*]] = call i32 @__kmpc_global_thread_num(ptr @45)
+// CHECK6-NEXT: [[TMP23:%.*]] = call i32 @__kmpc_omp_task(ptr @1, i32 [[OMP_GLOBAL_THREAD_NUM22]], ptr [[TMP21]])
// CHECK6-NEXT: ret void
// CHECK6-NEXT:}
diff --git a/clang/test/OpenMP/taskloop_ast_print.cpp b/clang/test/OpenMP/taskloop_ast_print.cpp
index 9bca586937347..e1d978cbd00d2 100644
--- a/clang/test/OpenMP/taskloop_ast_print.cpp
+++ b/clang/test/OpenMP/taskloop_ast_print.cpp
@@ -104,14 +104,17 @@ int main(int argc, char **argv) {
}
}
-#pragma omp taskloop transparent(omp_not_impex)
+#pragma omp taskloop transparent
for (int i = 0; i < 10; ++i) {
-#pragma omp task transparent(omp_import)
+#pragma omp taskloop transparent(omp_not_impex)
for (int i = 0; i < 10; ++i) {
-#pragma omp task transparent(omp_export)
+#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();
+ foo();
+ }
}
}
}
@@ -122,6 +125,7 @@ int main(int argc, char **argv) {
// CHECK60-NEXT: for (int j = 0; j < 10; ++j) {
// CHECK60-NEXT: foo();
+// CHECK60: #pragma omp taskloop transparent(omp_impex)
// 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)
diff --git a/clang/test/OpenMP/taskloop_codegen.cpp b/clang/test/OpenMP/taskloop_codegen.cpp
index 9073a2376f5b4..a9e7da82bec48 100644
--- a/clang/test/OpenMP/taskloop_codegen.cpp
+++ b/clang/test/OpenMP/taskloop_codegen.cpp
@@ -265,6 +265,9 @@ void test_threadset()
void test_transparent()
{
+#pragma omp taskloop transparent
+ for (int i = 0; i < 10; ++i) {
+ }
#pragma omp taskloop transparent(omp_not_impex)
for (int i = 0; i < 10; ++i) {
}
>From 1186849f5199fafae88fab83d6e6bc25a2570446 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Mon, 26 Jan 2026 06:54:01 -0800
Subject: [PATCH 2/2] Fix build error
---
clang/lib/Parse/ParseOpenMP.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index b7f2af9ca7b1f..d12c53ac82d45 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -3213,8 +3213,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
<< getOpenMPClauseName(CKind) << 0;
ErrorFound = true;
}
- const Token CurTok = PP.LookAhead(0);
- if (CKind == OMPC_transparent && CurTok.is(tok::annot_pragma_openmp_end)) {
+ if (CKind == OMPC_transparent &&
+ PP.LookAhead(0).is(tok::annot_pragma_openmp_end)) {
SourceLocation Loc = ConsumeToken();
SourceLocation LLoc = Tok.getLocation();
Clause = Actions.OpenMP().ActOnOpenMPTransparentClause(nullptr, LLoc,
More information about the cfe-commits
mailing list