[clang] [flang] [llvm] [clang] [OpenMP] New OpenMP 6.0 self_maps clause (PR #129888)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 11 01:18:09 PDT 2025
https://github.com/Ritanya-B-Bharadwaj updated https://github.com/llvm/llvm-project/pull/129888
>From 831fb3cf165814c3a7e437a7839951ef12d51694 Mon Sep 17 00:00:00 2001
From: Ritanya B Bharadwaj <ritanya.b.bharadwaj at gmail.com>
Date: Wed, 5 Mar 2025 08:45:23 -0600
Subject: [PATCH 1/2] [OpenMP] Parsing/Sema support for self_maps
---
clang/include/clang/AST/OpenMPClause.h | 46 ++++++++++++++++++-
clang/include/clang/AST/RecursiveASTVisitor.h | 5 ++
.../clang/Basic/DiagnosticParseKinds.td | 2 +-
clang/include/clang/Basic/OpenMPKinds.def | 1 +
clang/include/clang/Sema/SemaOpenMP.h | 4 ++
clang/lib/AST/OpenMPClause.cpp | 6 +++
clang/lib/AST/StmtProfile.cpp | 2 +
clang/lib/Basic/OpenMPKinds.cpp | 2 +
clang/lib/Parse/ParseOpenMP.cpp | 33 ++++++++++++-
clang/lib/Sema/SemaOpenMP.cpp | 16 ++++++-
clang/lib/Sema/TreeTransform.h | 6 +++
clang/lib/Serialization/ASTReader.cpp | 5 ++
clang/lib/Serialization/ASTWriter.cpp | 2 +
clang/test/OpenMP/requires_ast_print.cpp | 9 ++++
clang/test/OpenMP/requires_messages.cpp | 7 +++
clang/test/OpenMP/target_data_ast_print.cpp | 36 +++++++++++++++
clang/test/OpenMP/target_map_messages.cpp | 16 +++++++
clang/tools/libclang/CIndex.cpp | 2 +
llvm/include/llvm/Frontend/OpenMP/OMP.td | 5 +-
19 files changed, 199 insertions(+), 6 deletions(-)
diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h
index 154ecfbaa4418..46f34a7302847 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -1656,6 +1656,49 @@ class OMPAtomicDefaultMemOrderClause final : public OMPClause {
}
};
+/// This represents 'self_maps' clause in the '#pragma omp requires'
+/// directive.
+///
+/// \code
+/// #pragma omp requires self_maps
+/// \endcode
+/// In this example directive '#pragma omp requires' has 'self_maps'
+/// clause.
+class OMPSelfMapsClause final : public OMPClause {
+public:
+ friend class OMPClauseReader;
+ /// Build 'self_maps' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ OMPSelfMapsClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_self_maps, StartLoc, EndLoc) {}
+
+ /// Build an empty clause.
+ OMPSelfMapsClause()
+ : OMPClause(llvm::omp::OMPC_self_maps, SourceLocation(),
+ SourceLocation()) {}
+
+ 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_self_maps;
+ }
+};
+
/// This represents 'at' clause in the '#pragma omp error' directive
///
/// \code
@@ -6349,7 +6392,8 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
OpenMPMapModifierKind MapTypeModifiers[NumberOfOMPMapClauseModifiers] = {
OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
- OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
+ OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
+ OMPC_MAP_MODIFIER_unknown};
/// Location of map-type-modifiers for the 'map' clause.
SourceLocation MapTypeModifiersLoc[NumberOfOMPMapClauseModifiers];
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 06c762c080de0..3b73be7935ff1 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -3432,6 +3432,11 @@ bool RecursiveASTVisitor<Derived>::VisitOMPAtomicDefaultMemOrderClause(
return true;
}
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPSelfMapsClause(OMPSelfMapsClause *) {
+ return true;
+}
+
template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPAtClause(OMPAtClause *) {
return true;
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index c513dab810d1f..5f9ac7d77de91 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1495,7 +1495,7 @@ def note_previous_map_type_specified_here
: Note<"map type '%0' is previous specified here">;
def err_omp_unknown_map_type_modifier : Error<
"incorrect map type modifier, expected one of: 'always', 'close', 'mapper'"
- "%select{|, 'present'|, 'present', 'iterator'}0%select{|, 'ompx_hold'}1">;
+ "%select{|, 'present'|, 'present', 'iterator'}0%select{|, 'ompx_hold'}1%select{|, 'self'}2">;
def err_omp_map_type_missing : Error<
"missing map type">;
def err_omp_map_type_modifier_missing : Error<
diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def
index 76a861f416fd5..c4a2cca731607 100644
--- a/clang/include/clang/Basic/OpenMPKinds.def
+++ b/clang/include/clang/Basic/OpenMPKinds.def
@@ -172,6 +172,7 @@ OPENMP_MAP_MODIFIER_KIND(close)
OPENMP_MAP_MODIFIER_KIND(mapper)
OPENMP_MAP_MODIFIER_KIND(iterator)
OPENMP_MAP_MODIFIER_KIND(present)
+OPENMP_MAP_MODIFIER_KIND(self)
// This is an OpenMP extension for the sake of OpenACC support.
OPENMP_MAP_MODIFIER_KIND(ompx_hold)
diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h
index fa244da36a322..92985c9581eea 100644
--- a/clang/include/clang/Sema/SemaOpenMP.h
+++ b/clang/include/clang/Sema/SemaOpenMP.h
@@ -1109,6 +1109,10 @@ class SemaOpenMP : public SemaBase {
OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindLoc,
SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc);
+ /// Called on well-formed 'self_maps' clause.
+ OMPClause *ActOnOpenMPSelfMapsClause(SourceLocation StartLoc,
+ SourceLocation EndLoc);
+
/// Called on well-formed 'at' clause.
OMPClause *ActOnOpenMPAtClause(OpenMPAtClauseKind Kind,
SourceLocation KindLoc,
diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index 424cab3a7de35..648a273c4a2c6 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -155,6 +155,7 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
case OMPC_reverse_offload:
case OMPC_dynamic_allocators:
case OMPC_atomic_default_mem_order:
+ case OMPC_self_maps:
case OMPC_at:
case OMPC_severity:
case OMPC_message:
@@ -259,6 +260,7 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
case OMPC_reverse_offload:
case OMPC_dynamic_allocators:
case OMPC_atomic_default_mem_order:
+ case OMPC_self_maps:
case OMPC_at:
case OMPC_severity:
case OMPC_message:
@@ -1941,6 +1943,10 @@ void OMPClausePrinter::VisitOMPAtomicDefaultMemOrderClause(
<< ")";
}
+void OMPClausePrinter::VisitOMPSelfMapsClause(OMPSelfMapsClause *) {
+ OS << "self_maps";
+}
+
void OMPClausePrinter::VisitOMPAtClause(OMPAtClause *Node) {
OS << "at(" << getOpenMPSimpleClauseTypeName(OMPC_at, Node->getAtKind())
<< ")";
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 8b4b8ba19f75b..8a920c1a5d50f 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -557,6 +557,8 @@ void OMPClauseProfiler::VisitOMPDynamicAllocatorsClause(
void OMPClauseProfiler::VisitOMPAtomicDefaultMemOrderClause(
const OMPAtomicDefaultMemOrderClause *C) {}
+void OMPClauseProfiler::VisitOMPSelfMapsClause(const OMPSelfMapsClause *C) {}
+
void OMPClauseProfiler::VisitOMPAtClause(const OMPAtClause *C) {}
void OMPClauseProfiler::VisitOMPSeverityClause(const OMPSeverityClause *C) {}
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 956d92a7e95f0..4be6bf3e264d8 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -235,6 +235,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
case OMPC_unified_shared_memory:
case OMPC_reverse_offload:
case OMPC_dynamic_allocators:
+ case OMPC_self_maps:
case OMPC_match:
case OMPC_nontemporal:
case OMPC_destroy:
@@ -569,6 +570,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
case OMPC_unified_shared_memory:
case OMPC_reverse_offload:
case OMPC_dynamic_allocators:
+ case OMPC_self_maps:
case OMPC_match:
case OMPC_nontemporal:
case OMPC_destroy:
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index a455659ca8f2c..aae77e5837771 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -3343,6 +3343,20 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
ErrorFound = true;
}
+ Clause = ParseOpenMPClause(CKind, WrongDirective);
+ break;
+ case OMPC_self_maps:
+ // OpenMP [6.0, self_maps clause]
+ if (getLangOpts().OpenMP < 60) {
+ Diag(Tok, diag::err_omp_expected_clause)
+ << getOpenMPDirectiveName(OMPD_requires);
+ ErrorFound = true;
+ }
+ if (!FirstClause) {
+ Diag(Tok, diag::err_omp_more_one_clause)
+ << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
+ ErrorFound = true;
+ }
Clause = ParseOpenMPClause(CKind, WrongDirective);
break;
case OMPC_update:
@@ -4323,6 +4337,20 @@ bool Parser::parseMapTypeModifiers(SemaOpenMP::OpenMPVarListDataTy &Data) {
<< PreMapName;
}
ConsumeToken();
+ } else if (TypeModifier == OMPC_MAP_MODIFIER_self) {
+ Data.MapTypeModifiers.push_back(TypeModifier);
+ Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
+ if (PP.LookAhead(0).isNot(tok::comma) &&
+ PP.LookAhead(0).isNot(tok::colon))
+ Diag(Tok.getLocation(), diag::err_omp_missing_comma)
+ << "map type modifier";
+ if (getLangOpts().OpenMP < 60)
+ Diag(Tok, diag::err_omp_unknown_map_type_modifier)
+ << (getLangOpts().OpenMP >= 51
+ ? (getLangOpts().OpenMP >= 52 ? 2 : 1)
+ : 0)
+ << getLangOpts().OpenMPExtensions << 0;
+ ConsumeToken();
} else {
// For the case of unknown map-type-modifier or a map-type.
// Map-type is followed by a colon; the function returns when it
@@ -4344,7 +4372,8 @@ bool Parser::parseMapTypeModifiers(SemaOpenMP::OpenMPVarListDataTy &Data) {
Diag(Tok, diag::err_omp_unknown_map_type_modifier)
<< (getLangOpts().OpenMP >= 51 ? (getLangOpts().OpenMP >= 52 ? 2 : 1)
: 0)
- << getLangOpts().OpenMPExtensions;
+ << getLangOpts().OpenMPExtensions
+ << (getLangOpts().OpenMP >= 60 ? 1 : 0);
ConsumeToken();
}
if (getCurToken().is(tok::comma))
@@ -4819,7 +4848,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
if (getLangOpts().OpenMP < 52) {
Diag(Tok, diag::err_omp_unknown_map_type_modifier)
<< (getLangOpts().OpenMP >= 51 ? 1 : 0)
- << getLangOpts().OpenMPExtensions;
+ << getLangOpts().OpenMPExtensions << 0;
InvalidIterator = true;
}
}
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index b060039d188a1..cb392a80431d9 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -6620,6 +6620,7 @@ StmtResult SemaOpenMP::ActOnOpenMPExecutableDirective(
case OMPC_reverse_offload:
case OMPC_dynamic_allocators:
case OMPC_atomic_default_mem_order:
+ case OMPC_self_maps:
case OMPC_device_type:
case OMPC_match:
case OMPC_when:
@@ -15273,6 +15274,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
case OMPC_reverse_offload:
case OMPC_dynamic_allocators:
case OMPC_atomic_default_mem_order:
+ case OMPC_self_maps:
case OMPC_device_type:
case OMPC_match:
case OMPC_nontemporal:
@@ -15928,6 +15930,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPSimpleClause(
case OMPC_unified_shared_memory:
case OMPC_reverse_offload:
case OMPC_dynamic_allocators:
+ case OMPC_self_maps:
case OMPC_device_type:
case OMPC_match:
case OMPC_nontemporal:
@@ -16400,6 +16403,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPSingleExprWithArgClause(
case OMPC_reverse_offload:
case OMPC_dynamic_allocators:
case OMPC_atomic_default_mem_order:
+ case OMPC_self_maps:
case OMPC_device_type:
case OMPC_match:
case OMPC_nontemporal:
@@ -16607,6 +16611,9 @@ OMPClause *SemaOpenMP::ActOnOpenMPClause(OpenMPClauseKind Kind,
case OMPC_dynamic_allocators:
Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
break;
+ case OMPC_self_maps:
+ Res = ActOnOpenMPSelfMapsClause(StartLoc, EndLoc);
+ break;
case OMPC_destroy:
Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc,
/*LParenLoc=*/SourceLocation(),
@@ -16817,6 +16824,11 @@ SemaOpenMP::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
return new (getASTContext()) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
}
+OMPClause *SemaOpenMP::ActOnOpenMPSelfMapsClause(SourceLocation StartLoc,
+ SourceLocation EndLoc) {
+ return new (getASTContext()) OMPSelfMapsClause(StartLoc, EndLoc);
+}
+
StmtResult
SemaOpenMP::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses,
SourceLocation StartLoc,
@@ -17289,6 +17301,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
case OMPC_reverse_offload:
case OMPC_dynamic_allocators:
case OMPC_atomic_default_mem_order:
+ case OMPC_self_maps:
case OMPC_device_type:
case OMPC_match:
case OMPC_order:
@@ -21697,7 +21710,8 @@ OMPClause *SemaOpenMP::ActOnOpenMPMapClause(
OpenMPMapModifierKind Modifiers[] = {
OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
- OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
+ OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
+ OMPC_MAP_MODIFIER_unknown};
SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
if (IteratorModifier && !IteratorModifier->getType()->isSpecificBuiltinType(
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 813b172c4d89e..a8b7b110d1d5a 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -10813,6 +10813,12 @@ OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
"atomic_default_mem_order clause cannot appear in dependent context");
}
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPSelfMapsClause(OMPSelfMapsClause *C) {
+ llvm_unreachable("self_maps clause cannot appear in dependent context");
+}
+
template <typename Derived>
OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index b74bd586e74d7..76e4d074105bc 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -11101,6 +11101,9 @@ OMPClause *OMPClauseReader::readClause() {
case llvm::omp::OMPC_atomic_default_mem_order:
C = new (Context) OMPAtomicDefaultMemOrderClause();
break;
+ case llvm::omp::OMPC_self_maps:
+ C = new (Context) OMPSelfMapsClause();
+ break;
case llvm::omp::OMPC_at:
C = new (Context) OMPAtClause();
break;
@@ -11582,6 +11585,8 @@ void OMPClauseReader::VisitOMPAtomicDefaultMemOrderClause(
C->setAtomicDefaultMemOrderKindKwLoc(Record.readSourceLocation());
}
+void OMPClauseReader::VisitOMPSelfMapsClause(OMPSelfMapsClause *) {}
+
void OMPClauseReader::VisitOMPAtClause(OMPAtClause *C) {
C->setAtKind(static_cast<OpenMPAtClauseKind>(Record.readInt()));
C->setLParenLoc(Record.readSourceLocation());
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 903a165ee75c6..559430b570b4c 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -8439,6 +8439,8 @@ void OMPClauseWriter::VisitOMPAtomicDefaultMemOrderClause(
Record.AddSourceLocation(C->getAtomicDefaultMemOrderKindKwLoc());
}
+void OMPClauseWriter::VisitOMPSelfMapsClause(OMPSelfMapsClause *) {}
+
void OMPClauseWriter::VisitOMPAtClause(OMPAtClause *C) {
Record.push_back(C->getAtKind());
Record.AddSourceLocation(C->getLParenLoc());
diff --git a/clang/test/OpenMP/requires_ast_print.cpp b/clang/test/OpenMP/requires_ast_print.cpp
index efa1551e75898..a602a1c41e950 100644
--- a/clang/test/OpenMP/requires_ast_print.cpp
+++ b/clang/test/OpenMP/requires_ast_print.cpp
@@ -13,6 +13,10 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=99 -DOMP99 -ast-print %s | FileCheck --check-prefixes=CHECK,REV %s
// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=99 -DOMP99 -x c++ -std=c++11 -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=99 -DOMP99 -std=c++11 -include-pch %t -verify %s -ast-print | FileCheck --check-prefixes=CHECK,REV %s
+
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -DOMP60 -ast-print %s | FileCheck --check-prefixes=CHECK,CHECK_SELF %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -DOMP60 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -DOMP60 -std=c++11 -include-pch %t -verify %s -ast-print | FileCheck --check-prefixes=CHECK,CHECK_SELF %s
// expected-no-diagnostics
#ifndef HEADER
@@ -24,6 +28,11 @@
#pragma omp requires unified_shared_memory
// CHECK:#pragma omp requires unified_shared_memory
+#ifdef OMP60
+#pragma omp requires self_maps
+// CHECK_SELF:#pragma omp requires self_maps
+#endif
+
#ifdef OMP99
#pragma omp requires reverse_offload
// REV:#pragma omp requires reverse_offload
diff --git a/clang/test/OpenMP/requires_messages.cpp b/clang/test/OpenMP/requires_messages.cpp
index dbb2b317067b7..db1805443e458 100644
--- a/clang/test/OpenMP/requires_messages.cpp
+++ b/clang/test/OpenMP/requires_messages.cpp
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized
// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=99 -DOMP99 -verify=expected,rev -ferror-limit 100 %s -Wuninitialized
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -DOMP60 -verify=self -ferror-limit 100 %s -Wuninitialized
int a;
#pragma omp requires unified_address allocate(a) // rev-note {{unified_address clause previously used here}} expected-note {{unified_address clause previously used here}} expected-note {{unified_address clause previously used here}} expected-note {{unified_address clause previously used here}} expected-note {{unified_address clause previously used here}} expected-note{{unified_address clause previously used here}} expected-error {{unexpected OpenMP clause 'allocate' in directive '#pragma omp requires'}}
@@ -22,6 +23,12 @@ int a;
#pragma omp requires dynamic_allocators, dynamic_allocators // expected-error {{only one dynamic_allocators clause can appear on a requires directive in a single translation unit}} expected-error {{directive '#pragma omp requires' cannot contain more than one 'dynamic_allocators' clause}}
+#ifdef OMP60
+#pragma omp requires self_maps // self-note {{self_maps clause previously used here}}
+
+#pragma omp requires self_maps, self_maps // self-error {{only one self_maps clause can appear on a requires directive in a single translation unit}} self-error {{directive '#pragma omp requires' cannot contain more than one 'self_maps' clause}}
+#endif
+
#pragma omp requires atomic_default_mem_order(seq_cst) // rev-note {{atomic_default_mem_order clause previously used here}} expected-note {{atomic_default_mem_order clause previously used here}} expected-note {{atomic_default_mem_order clause previously used here}} expected-note {{atomic_default_mem_order clause previously used here}} expected-note {{atomic_default_mem_order clause previously used here}}
#pragma omp requires atomic_default_mem_order(acq_rel) // expected-error {{only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}}
diff --git a/clang/test/OpenMP/target_data_ast_print.cpp b/clang/test/OpenMP/target_data_ast_print.cpp
index 9e883b25f11d4..a41c7f1a0da53 100644
--- a/clang/test/OpenMP/target_data_ast_print.cpp
+++ b/clang/test/OpenMP/target_data_ast_print.cpp
@@ -13,6 +13,14 @@
// RUN: %clang_cc1 -DOMP51 -DOMPX -verify -fopenmp-simd -fopenmp-extensions -ast-print %s | FileCheck -check-prefixes=CHECK,OMP51,OMPX %s
// RUN: %clang_cc1 -DOMP51 -DOMPX -fopenmp-simd -fopenmp-extensions -x c++ -std=c++11 -emit-pch -o %t %s
// RUN: %clang_cc1 -DOMP51 -DOMPX -fopenmp-simd -fopenmp-extensions -std=c++11 -include-pch %t -verify %s -ast-print | FileCheck -check-prefixes=CHECK,OMP51,OMPX %s
+
+// RUN: %clang_cc1 -DOMP60 -verify -fopenmp -fopenmp-version=60 -fopenmp-extensions -ast-print %s | FileCheck -check-prefixes=CHECK,OMP60 %s
+// RUN: %clang_cc1 -DOMP60 -fopenmp -fopenmp-version=60 -fopenmp-extensions -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -DOMP60 -fopenmp -fopenmp-version=60 -fopenmp-extensions -std=c++11 -include-pch %t -verify %s -ast-print | FileCheck -check-prefixes=CHECK,OMP60 %s
+
+// RUN: %clang_cc1 -DOMP60 -verify -fopenmp-simd -fopenmp -fopenmp-version=60 -fopenmp-extensions -ast-print %s | FileCheck -check-prefixes=CHECK,OMP60 %s
+// RUN: %clang_cc1 -DOMP60 -fopenmp-simd -fopenmp -fopenmp-version=60 -fopenmp-extensions -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -DOMP60 -fopenmp-simd -fopenmp -fopenmp-version=60 -fopenmp-extensions -std=c++11 -include-pch %t -verify %s -ast-print | FileCheck -check-prefixes=CHECK,OMP60 %s
// expected-no-diagnostics
#ifndef HEADER
@@ -51,6 +59,11 @@ T tmain(T argc, T *argv) {
#pragma omp target data map(close,alloc: e)
foo();
+#ifdef OMP60
+#pragma omp target data map(self,alloc: e)
+ foo();
+#endif
+
#ifdef OMP51
#pragma omp target data map(present,alloc: e)
foo();
@@ -68,6 +81,10 @@ T tmain(T argc, T *argv) {
foo();
#pragma omp target map(close, alloc: e)
foo();
+#ifdef OMP60
+ #pragma omp target map(self,alloc: e)
+ foo();
+#endif
#ifdef OMP51
#pragma omp target map(present, alloc: e)
foo();
@@ -101,6 +118,8 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: foo();
// CHECK-NEXT: #pragma omp target data map(close,alloc: e)
// CHECK-NEXT: foo();
+// OMP60-NEXT: #pragma omp target data map(self,alloc: e)
+// OMP60-NEXT: foo();
// OMP51-NEXT: #pragma omp target data map(present,alloc: e)
// OMP51-NEXT: foo();
// OMPX-NEXT: #pragma omp target data map(ompx_hold,alloc: e)
@@ -111,6 +130,8 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: foo();
// CHECK-NEXT: #pragma omp target map(close,alloc: e)
// CHECK-NEXT: foo();
+// OMP60-NEXT: #pragma omp target map(self,alloc: e)
+// OMP60-NEXT: foo();
// OMP51-NEXT: #pragma omp target map(present,alloc: e)
// OMP51-NEXT: foo();
// OMPX-NEXT: #pragma omp target map(ompx_hold,alloc: e)
@@ -135,6 +156,8 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: foo();
// CHECK-NEXT: #pragma omp target data map(close,alloc: e)
// CHECK-NEXT: foo();
+// OMP60-NEXT: #pragma omp target data map(self,alloc: e)
+// OMP60-NEXT: foo();
// OMP51-NEXT: #pragma omp target data map(present,alloc: e)
// OMP51-NEXT: foo();
// OMPX-NEXT: #pragma omp target data map(ompx_hold,alloc: e)
@@ -145,6 +168,8 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: foo();
// CHECK-NEXT: #pragma omp target map(close,alloc: e)
// CHECK-NEXT: foo();
+// OMP60-NEXT: #pragma omp target map(self,alloc: e)
+// OMP60-NEXT: foo();
// OMP51-NEXT: #pragma omp target map(present,alloc: e)
// OMP51-NEXT: foo();
// OMPX-NEXT: #pragma omp target map(ompx_hold,alloc: e)
@@ -169,6 +194,8 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: foo();
// CHECK-NEXT: #pragma omp target data map(close,alloc: e)
// CHECK-NEXT: foo();
+// OMP60-NEXT: #pragma omp target data map(self,alloc: e)
+// OMP60-NEXT: foo();
// OMP51-NEXT: #pragma omp target data map(present,alloc: e)
// OMP51-NEXT: foo();
// OMPX-NEXT: #pragma omp target data map(ompx_hold,alloc: e)
@@ -179,6 +206,8 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: foo();
// CHECK-NEXT: #pragma omp target map(close,alloc: e)
// CHECK-NEXT: foo();
+// OMP60-NEXT: #pragma omp target map(self,alloc: e)
+// OMP60-NEXT: foo();
// OMP51-NEXT: #pragma omp target map(present,alloc: e)
// OMP51-NEXT: foo();
// OMPX-NEXT: #pragma omp target map(ompx_hold,alloc: e)
@@ -235,6 +264,13 @@ int main (int argc, char **argv) {
foo();
// CHECK-NEXT: foo();
+// OMP60-NEXT: #pragma omp target data map(self,alloc: e)
+// OMP60-NEXT: foo();
+#ifdef OMP60
+#pragma omp target data map(self,alloc: e)
+ foo();
+#endif
+
// OMP51-NEXT: #pragma omp target data map(present,alloc: e)
// OMP51-NEXT: foo();
#ifdef OMP51
diff --git a/clang/test/OpenMP/target_map_messages.cpp b/clang/test/OpenMP/target_map_messages.cpp
index 10f46687d6379..911031d5412a9 100644
--- a/clang/test/OpenMP/target_map_messages.cpp
+++ b/clang/test/OpenMP/target_map_messages.cpp
@@ -128,6 +128,16 @@ struct SA {
{}
#pragma omp target map(always) // expected-error {{use of undeclared identifier 'always'}}
{}
+ #pragma omp target map(self, tofrom: c,f) // lt60-error {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper'}}
+ {}
+ #pragma omp target map(self, tofrom: c[1:2],f) // lt60-error {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper'}}
+ {}
+ #pragma omp target map(self, tofrom: c,f[1:2]) // lt60-error {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper'}}
+ {}
+ #pragma omp target map(self, tofrom: c[:],f) // lt60-error {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper'}} // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ {}
+ #pragma omp target map(self, tofrom: c,f[:]) // lt60-error {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper'}} // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ {}
#pragma omp target map(close, tofrom: c,f)
{}
#pragma omp target map(close, tofrom: c[1:2],f)
@@ -194,6 +204,8 @@ struct SA {
{}
#pragma omp target map(always, close, always, close, tofrom: a) // expected-error 2 {{same map type modifier has been specified more than once}}
{}
+ #pragma omp target map(self, self, tofrom: a) // lt60-error {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper'}} // lt60-error {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper'}} // lt60-error {{same map type modifier has been specified more than once}} // ge60-error {{same map type modifier has been specified more than once}}
+ {}
// ge60-error at +3 {{same map type modifier has been specified more than once}}
// ge51-error at +2 {{same map type modifier has been specified more than once}}
// lt51-error at +1 2 {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper'}}
@@ -725,6 +737,10 @@ T tmain(T argc) {
#pragma omp target data map(close, tofrom: close, tofrom, x)
foo();
+#pragma omp target data map(self, tofrom: x) // lt60-error {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper'}}
+#pragma omp target data map(self: x) // lt60-error {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper'}} // lt60-error {{missing map type}}
+ foo();
+
// lt51-error at +1 {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper'}}
#pragma omp target data map(present, tofrom: x)
// ge51-error at +2 {{missing map type}}
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 285ac31420007..fa1c3d63523d1 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -2534,6 +2534,8 @@ void OMPClauseEnqueue::VisitOMPDynamicAllocatorsClause(
void OMPClauseEnqueue::VisitOMPAtomicDefaultMemOrderClause(
const OMPAtomicDefaultMemOrderClause *) {}
+void OMPClauseEnqueue::VisitOMPSelfMapsClause(const OMPSelfMapsClause *) {}
+
void OMPClauseEnqueue::VisitOMPAtClause(const OMPAtClause *) {}
void OMPClauseEnqueue::VisitOMPSeverityClause(const OMPSeverityClause *) {}
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index 37b92f2339df9..c6db4fd050851 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -499,6 +499,9 @@ def OMPC_UnifiedAddress : Clause<"unified_address"> {
def OMPC_UnifiedSharedMemory : Clause<"unified_shared_memory"> {
let clangClass = "OMPUnifiedSharedMemoryClause";
}
+def OMPC_SelfMaps : Clause<"self_maps"> {
+ let clangClass = "OMPSelfMapsClause";
+}
def OMPC_Uniform : Clause<"uniform"> {
let flangClass = "Name";
let isValueList = true;
@@ -910,7 +913,7 @@ def OMP_Requires : Directive<"requires"> {
// TODO: Correct this supprted version number whenever complete
// implementation of reverse_offload is available.
VersionedClause<OMPC_AtomicDefaultMemOrder>,
- VersionedClause<OMPC_DynamicAllocators>,
+ VersionedClause<OMPC_DynamicAllocators>, VersionedClause<OMPC_SelfMaps>,
VersionedClause<OMPC_ReverseOffload, 99>,
];
let association = AS_None;
>From b674e114e6672f608867365e4e75b0c62bb74d09 Mon Sep 17 00:00:00 2001
From: Ritanya B Bharadwaj <ritanya.b.bharadwaj at gmail.com>
Date: Fri, 7 Mar 2025 12:06:36 -0600
Subject: [PATCH 2/2] Fixing flang build failure and updating release docs
---
clang/docs/OpenMPSupport.rst | 2 +-
clang/docs/ReleaseNotes.rst | 1 +
flang/lib/Lower/OpenMP/Clauses.cpp | 1 +
flang/lib/Lower/OpenMP/Clauses.h | 1 +
flang/lib/Semantics/check-omp-structure.cpp | 4 ++++
llvm/include/llvm/Frontend/OpenMP/ClauseT.h | 7 ++++++-
6 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/clang/docs/OpenMPSupport.rst b/clang/docs/OpenMPSupport.rst
index c31d6e90ecb08..1082f42b8fd85 100644
--- a/clang/docs/OpenMPSupport.rst
+++ b/clang/docs/OpenMPSupport.rst
@@ -406,7 +406,7 @@ implementation.
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
| Private reductions | :none:`unclaimed` | :none:`unclaimed` | |
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
-| Self maps | :none:`unclaimed` | :none:`unclaimed` | |
+| Self maps | :part:`partial` | :none:`unclaimed` | parsing/sema done: https://github.com/llvm/llvm-project/pull/129888 |
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
| Release map type for declare mapper | :none:`unclaimed` | :none:`unclaimed` | |
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 92f63c1503089..430b659aef22b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -280,6 +280,7 @@ Python Binding Changes
OpenMP Support
--------------
- Added support 'no_openmp_constructs' assumption clause.
+- Added support for 'self_maps' in map and requirement clause.
Improvements
^^^^^^^^^^^^
diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp
index 831ba23870360..ac4bd24c7f2fe 100644
--- a/flang/lib/Lower/OpenMP/Clauses.cpp
+++ b/flang/lib/Lower/OpenMP/Clauses.cpp
@@ -217,6 +217,7 @@ MAKE_EMPTY_CLASS(Simd, Simd);
MAKE_EMPTY_CLASS(Threads, Threads);
MAKE_EMPTY_CLASS(UnifiedAddress, UnifiedAddress);
MAKE_EMPTY_CLASS(UnifiedSharedMemory, UnifiedSharedMemory);
+MAKE_EMPTY_CLASS(SelfMaps, SelfMaps);
MAKE_EMPTY_CLASS(Unknown, Unknown);
MAKE_EMPTY_CLASS(Untied, Untied);
MAKE_EMPTY_CLASS(Weak, Weak);
diff --git a/flang/lib/Lower/OpenMP/Clauses.h b/flang/lib/Lower/OpenMP/Clauses.h
index 0f172e0acf626..58bc48d1fce07 100644
--- a/flang/lib/Lower/OpenMP/Clauses.h
+++ b/flang/lib/Lower/OpenMP/Clauses.h
@@ -285,6 +285,7 @@ using To = tomp::clause::ToT<TypeTy, IdTy, ExprTy>;
using UnifiedAddress = tomp::clause::UnifiedAddressT<TypeTy, IdTy, ExprTy>;
using UnifiedSharedMemory =
tomp::clause::UnifiedSharedMemoryT<TypeTy, IdTy, ExprTy>;
+using SelfMaps = tomp::clause::SelfMapsT<TypeTy, IdTy, ExprTy>;
using Uniform = tomp::clause::UniformT<TypeTy, IdTy, ExprTy>;
using Unknown = tomp::clause::UnknownT<TypeTy, IdTy, ExprTy>;
using Untied = tomp::clause::UntiedT<TypeTy, IdTy, ExprTy>;
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index fd2893998205c..ea76be1ede3da 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -5452,6 +5452,10 @@ void OmpStructureChecker::Enter(
CheckAllowedRequiresClause(llvm::omp::Clause::OMPC_unified_shared_memory);
}
+void OmpStructureChecker::Enter(const parser::OmpClause::SelfMaps &x) {
+ CheckAllowedRequiresClause(llvm::omp::Clause::OMPC_self_maps);
+}
+
void OmpStructureChecker::Enter(const parser::DoConstruct &x) {
Base::Enter(x);
loopStack_.push_back(&x);
diff --git a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
index 5dc1c4cb54c7c..e0714e812e5cd 100644
--- a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
+++ b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
@@ -1142,6 +1142,11 @@ struct UnifiedSharedMemoryT {
using EmptyTrait = std::true_type;
};
+template <typename T, typename I, typename E> //
+struct SelfMapsT {
+ using EmptyTrait = std::true_type;
+};
+
// V5.2: [5.10] `uniform` clause
template <typename T, typename I, typename E> //
struct UniformT {
@@ -1245,7 +1250,7 @@ using EmptyClausesT = std::variant<
ReverseOffloadT<T, I, E>, SeqCstT<T, I, E>, SimdT<T, I, E>,
ThreadsT<T, I, E>, UnifiedAddressT<T, I, E>, UnifiedSharedMemoryT<T, I, E>,
UnknownT<T, I, E>, UntiedT<T, I, E>, UseT<T, I, E>, WeakT<T, I, E>,
- WriteT<T, I, E>, NoOpenmpConstructsT<T, I, E>>;
+ WriteT<T, I, E>, NoOpenmpConstructsT<T, I, E>, SelfMapsT<T, I, E>>;
template <typename T, typename I, typename E>
using IncompleteClausesT =
More information about the cfe-commits
mailing list