[clang] [Clang][OpenMP]Default clause variable category (PR #157063)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 11 12:34:38 PDT 2025
https://github.com/SunilKuravinakop updated https://github.com/llvm/llvm-project/pull/157063
>From dce17e9499e18ff0db4452d3ae316fdfc678fd2f Mon Sep 17 00:00:00 2001
From: Sunil Kuravinakop <kuravina at pe31.hpc.amslabs.hpecorp.net>
Date: Thu, 7 Aug 2025 03:41:16 -0500
Subject: [PATCH 1/9] Parsing and storing of "variable category" in Sema
(default clause class) done.
---
clang/include/clang/AST/OpenMPClause.h | 18 +++++++-
.../clang/Basic/DiagnosticSemaKinds.td | 2 +
clang/include/clang/Basic/OpenMPKinds.def | 11 +++++
clang/include/clang/Basic/OpenMPKinds.h | 10 +++++
clang/include/clang/Sema/SemaOpenMP.h | 10 ++---
clang/lib/Basic/OpenMPKinds.cpp | 10 +++++
clang/lib/Parse/ParseOpenMP.cpp | 27 +++++++++++-
clang/lib/Sema/SemaOpenMP.cpp | 44 +++++++++++--------
clang/lib/Sema/TreeTransform.h | 7 ++-
9 files changed, 112 insertions(+), 27 deletions(-)
diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h
index 1118d3e062e68..9f2483a722c16 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -1269,6 +1269,12 @@ class OMPDefaultClause : public OMPClause {
/// Start location of the kind in source code.
SourceLocation KindKwLoc;
+ /// Variable-Category to indicate where Kind is applied
+ OpenMPDefaultClauseVariableCategory VC = OMPC_DEFAULT_VC_all;
+
+ /// Start location of Variable-Category
+ SourceLocation VCLoc;
+
/// Set kind of the clauses.
///
/// \param K Argument of clause.
@@ -1279,6 +1285,11 @@ class OMPDefaultClause : public OMPClause {
/// \param KLoc Argument location.
void setDefaultKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
+ /// Set Variable Category used with the Kind Clause (Default Modifier)
+ void setDefaultVariableCategory(OpenMPDefaultClauseVariableCategory VC) { this->VC = VC; }
+
+ void setDefaultVariableCategoryLocation(SourceLocation VCLoc) { this->VCLoc = VCLoc; }
+
public:
/// Build 'default' clause with argument \a A ('none' or 'shared').
///
@@ -1288,10 +1299,11 @@ class OMPDefaultClause : public OMPClause {
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
OMPDefaultClause(llvm::omp::DefaultKind A, SourceLocation ALoc,
+ OpenMPDefaultClauseVariableCategory VC, SourceLocation VCLoc,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
: OMPClause(llvm::omp::OMPC_default, StartLoc, EndLoc),
- LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {}
+ LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc), VC(VC), VCLoc(VCLoc) {}
/// Build an empty clause.
OMPDefaultClause()
@@ -1310,6 +1322,10 @@ class OMPDefaultClause : public OMPClause {
/// Returns location of clause kind.
SourceLocation getDefaultKindKwLoc() const { return KindKwLoc; }
+ OpenMPDefaultClauseVariableCategory getDefaultVC() { return VC; }
+
+ SourceLocation getDefaultVCLoc() { return VCLoc; }
+
child_range children() {
return child_range(child_iterator(), child_iterator());
}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 94b174c758a5c..10446ab7f2ebf 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11662,6 +11662,8 @@ def note_omp_default_dsa_none : Note<
"explicit data sharing attribute requested here">;
def note_omp_defaultmap_attr_none : Note<
"explicit data sharing attribute, data mapping attribute, or is_device_ptr clause requested here">;
+def err_omp_default_vc : Error<
+ "wrong variable category specified with modifier %0 in the default clause">;
def err_omp_wrong_dsa : Error<
"%0 variable cannot be %1">;
def err_omp_variably_modified_type_not_supported : Error<
diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def
index 9d6f816eea91f..79c11b851c557 100644
--- a/clang/include/clang/Basic/OpenMPKinds.def
+++ b/clang/include/clang/Basic/OpenMPKinds.def
@@ -35,6 +35,9 @@
#ifndef OPENMP_DIST_SCHEDULE_KIND
#define OPENMP_DIST_SCHEDULE_KIND(Name)
#endif
+#ifndef OPENMP_DEFAULT_VARIABLE_CATEGORY
+#define OPENMP_DEFAULT_VARIABLE_CATEGORY(Name)
+#endif
#ifndef OPENMP_DEFAULTMAP_KIND
#define OPENMP_DEFAULTMAP_KIND(Name)
#endif
@@ -112,6 +115,13 @@ OPENMP_SCHEDULE_MODIFIER(simd)
OPENMP_DEVICE_MODIFIER(ancestor)
OPENMP_DEVICE_MODIFIER(device_num)
+// Variable-category attributes for 'default' clause.
+OPENMP_DEFAULT_VARIABLE_CATEGORY(aggregate)
+OPENMP_DEFAULT_VARIABLE_CATEGORY(all)
+OPENMP_DEFAULT_VARIABLE_CATEGORY(allocatable)
+OPENMP_DEFAULT_VARIABLE_CATEGORY(pointer)
+OPENMP_DEFAULT_VARIABLE_CATEGORY(scalar)
+
// Static attributes for 'defaultmap' clause.
OPENMP_DEFAULTMAP_KIND(scalar)
OPENMP_DEFAULTMAP_KIND(aggregate)
@@ -267,6 +277,7 @@ OPENMP_DOACROSS_MODIFIER(source_omp_cur_iteration)
#undef OPENMP_MAP_MODIFIER_KIND
#undef OPENMP_MOTION_MODIFIER_KIND
#undef OPENMP_DIST_SCHEDULE_KIND
+#undef OPENMP_DEFAULT_VARIABLE_CATEGORY
#undef OPENMP_DEFAULTMAP_KIND
#undef OPENMP_DEFAULTMAP_MODIFIER
#undef OPENMP_DOACROSS_MODIFIER
diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h
index f40db4c13c55a..e63f1cfd23ca0 100644
--- a/clang/include/clang/Basic/OpenMPKinds.h
+++ b/clang/include/clang/Basic/OpenMPKinds.h
@@ -107,6 +107,14 @@ enum OpenMPDistScheduleClauseKind {
OMPC_DIST_SCHEDULE_unknown
};
+/// OpenMP variable-category for 'default' clause.
+enum OpenMPDefaultClauseVariableCategory {
+#define OPENMP_DEFAULT_VARIABLE_CATEGORY(Name) \
+ OMPC_DEFAULT_VC_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+ OMPC_DEFAULT_VC_unknown
+};
+
/// OpenMP attributes for 'defaultmap' clause.
enum OpenMPDefaultmapClauseKind {
#define OPENMP_DEFAULTMAP_KIND(Name) \
@@ -257,6 +265,8 @@ struct OMPInteropInfo final {
llvm::SmallVector<Expr *, 4> PreferTypes;
};
+unsigned getOpenMPDefaultVariableCategory(StringRef Str, const LangOptions &LangOpts);
+
unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str,
const LangOptions &LangOpts);
const char *getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type);
diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h
index 91c3d4bd5210e..35c01b22a0b28 100644
--- a/clang/include/clang/Sema/SemaOpenMP.h
+++ b/clang/include/clang/Sema/SemaOpenMP.h
@@ -951,11 +951,11 @@ class SemaOpenMP : public SemaBase {
SourceLocation LParenLoc,
SourceLocation EndLoc);
/// Called on well-formed 'default' clause.
- OMPClause *ActOnOpenMPDefaultClause(llvm::omp::DefaultKind Kind,
- SourceLocation KindLoc,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
+ OMPClause *ActOnOpenMPDefaultClause(
+ llvm::omp::DefaultKind M, SourceLocation MLoc,
+ OpenMPDefaultClauseVariableCategory VCKind, SourceLocation VCKindLoc,
+ 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/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 220b31b0f19bc..d99953154d73e 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -20,6 +20,14 @@
using namespace clang;
using namespace llvm::omp;
+unsigned clang::getOpenMPDefaultVariableCategory(StringRef Str, const LangOptions &LangOpts) {
+ unsigned VC = llvm::StringSwitch<unsigned>(Str)
+#define OPENMP_DEFAULT_VARIABLE_CATEGORY(Name) .Case(#Name, OMPC_DEFAULT_VC_##Name)
+#include "clang/Basic/OpenMPKinds.def"
+ .Default(OMPC_DEFAULT_VC_unknown);
+ return VC;
+}
+
unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
const LangOptions &LangOpts) {
switch (Kind) {
@@ -92,6 +100,8 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
.Default(OMPC_DIST_SCHEDULE_unknown);
case OMPC_defaultmap:
return llvm::StringSwitch<unsigned>(Str)
+#define OPENMP_DEFAULT_VARIABLE_CATEGORY(Name) \
+ .Case(#Name, static_cast<unsigned>(OMPC_DEFAULT_VC_##Name))
#define OPENMP_DEFAULTMAP_KIND(Name) \
.Case(#Name, static_cast<unsigned>(OMPC_DEFAULTMAP_##Name))
#define OPENMP_DEFAULTMAP_MODIFIER(Name) \
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index aa6a0c61a2c17..d6d0e3bbf4e6b 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -3083,7 +3083,6 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
break;
case OMPC_fail:
- case OMPC_default:
case OMPC_proc_bind:
case OMPC_atomic_default_mem_order:
case OMPC_at:
@@ -3115,6 +3114,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
case OMPC_schedule:
case OMPC_dist_schedule:
case OMPC_defaultmap:
+ case OMPC_default:
case OMPC_order:
// OpenMP [2.7.1, Restrictions, p. 3]
// Only one schedule clause can appear on a loop directive.
@@ -3734,6 +3734,31 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind,
ConsumeAnyToken();
if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
DelimLoc = ConsumeAnyToken();
+ } else if (Kind == OMPC_default) {
+ // Get a default modifier
+ unsigned Modifier = getOpenMPSimpleClauseType(
+ Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok), getLangOpts());
+
+ Arg.push_back(Modifier);
+ KLoc.push_back(Tok.getLocation());
+ if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
+ Tok.isNot(tok::annot_pragma_openmp_end))
+ ConsumeAnyToken();
+ // Parse ':'
+ if (Tok.is(tok::colon) && getLangOpts().OpenMP >= 60) {
+ ConsumeAnyToken();
+ // Get a variable-category attribute for default clause modifier
+ unsigned VariableCategory = getOpenMPDefaultVariableCategory(
+ Tok.isAnnotation() ? "" : PP.getSpelling(Tok), getLangOpts());
+ Arg.push_back(VariableCategory);
+ KLoc.push_back(Tok.getLocation());
+ if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
+ Tok.isNot(tok::annot_pragma_openmp_end))
+ ConsumeAnyToken();
+ } else {
+ Arg.push_back(OMPC_DEFAULT_VC_all);
+ KLoc.push_back(SourceLocation());
+ }
} else if (Kind == OMPC_defaultmap) {
// Get a defaultmap modifier
unsigned Modifier = getOpenMPSimpleClauseType(
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 2c5d97c3064ac..606119715a91f 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -16231,10 +16231,6 @@ OMPClause *SemaOpenMP::ActOnOpenMPSimpleClause(
SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
OMPClause *Res = nullptr;
switch (Kind) {
- case OMPC_default:
- Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
- ArgumentLoc, StartLoc, LParenLoc, EndLoc);
- break;
case OMPC_proc_bind:
Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
ArgumentLoc, StartLoc, LParenLoc, EndLoc);
@@ -16315,6 +16311,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPSimpleClause(
case OMPC_num_tasks:
case OMPC_hint:
case OMPC_dist_schedule:
+ case OMPC_default:
case OMPC_defaultmap:
case OMPC_unknown:
case OMPC_uniform:
@@ -16348,38 +16345,41 @@ OMPClause *SemaOpenMP::ActOnOpenMPSimpleClause(
return Res;
}
-OMPClause *SemaOpenMP::ActOnOpenMPDefaultClause(DefaultKind Kind,
- SourceLocation KindKwLoc,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc) {
- if (Kind == OMP_DEFAULT_unknown) {
- Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
+OMPClause *SemaOpenMP::ActOnOpenMPDefaultClause(
+ llvm::omp::DefaultKind M, SourceLocation MLoc,
+ OpenMPDefaultClauseVariableCategory VCKind, SourceLocation VCKindLoc,
+ SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
+ if (M == OMP_DEFAULT_unknown) {
+ Diag(MLoc, diag::err_omp_unexpected_clause_value)
<< getListOfPossibleValues(OMPC_default, /*First=*/0,
/*Last=*/unsigned(OMP_DEFAULT_unknown))
<< getOpenMPClauseNameForDiag(OMPC_default);
return nullptr;
}
- switch (Kind) {
+ switch (M) {
case OMP_DEFAULT_none:
- DSAStack->setDefaultDSANone(KindKwLoc);
+ DSAStack->setDefaultDSANone(MLoc);
break;
case OMP_DEFAULT_shared:
- DSAStack->setDefaultDSAShared(KindKwLoc);
+ DSAStack->setDefaultDSAShared(MLoc);
break;
case OMP_DEFAULT_firstprivate:
- DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
+ DSAStack->setDefaultDSAFirstPrivate(MLoc);
break;
case OMP_DEFAULT_private:
- DSAStack->setDefaultDSAPrivate(KindKwLoc);
+ DSAStack->setDefaultDSAPrivate(MLoc);
break;
default:
llvm_unreachable("DSA unexpected in OpenMP default clause");
}
+ if (VCKind < 0 || VCKind >= OMPC_DEFAULT_VC_unknown) {
+ Diag(VCKindLoc, diag::err_omp_default_vc) << getOpenMPSimpleClauseTypeName(OMPC_default, unsigned(M));
+ }
+
return new (getASTContext())
- OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
+ OMPDefaultClause(M, MLoc, VCKind, VCKindLoc, StartLoc, LParenLoc, EndLoc);
}
OMPClause *SemaOpenMP::ActOnOpenMPProcBindClause(ProcBindKind Kind,
@@ -16685,6 +16685,15 @@ OMPClause *SemaOpenMP::ActOnOpenMPSingleExprWithArgClause(
static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
break;
+ case OMPC_default:
+ enum { DefaultModifier, DefaultVarCategory };
+ Res = ActOnOpenMPDefaultClause(
+ static_cast<llvm::omp::DefaultKind>(Argument[DefaultModifier]),
+ ArgumentLoc[DefaultModifier],
+ static_cast<OpenMPDefaultClauseVariableCategory>(Argument[DefaultVarCategory]),
+ ArgumentLoc[DefaultVarCategory],
+ StartLoc, LParenLoc, EndLoc);
+ break;
case OMPC_defaultmap:
enum { Modifier, DefaultmapKind };
Res = ActOnOpenMPDefaultmapClause(
@@ -16733,7 +16742,6 @@ OMPClause *SemaOpenMP::ActOnOpenMPSingleExprWithArgClause(
case OMPC_sizes:
case OMPC_allocator:
case OMPC_collapse:
- case OMPC_default:
case OMPC_proc_bind:
case OMPC_private:
case OMPC_firstprivate:
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index c7428d1a02345..5f26427c490b2 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -1804,11 +1804,13 @@ class TreeTransform {
/// By default, performs semantic analysis to build the new OpenMP clause.
/// Subclasses may override this routine to provide different behavior.
OMPClause *RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc,
+ OpenMPDefaultClauseVariableCategory VCKind,
+ SourceLocation VCLoc,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc) {
return getSema().OpenMP().ActOnOpenMPDefaultClause(
- Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
+ Kind, KindKwLoc, VCKind, VCLoc, StartLoc, LParenLoc, EndLoc);
}
/// Build a new OpenMP 'proc_bind' clause.
@@ -10587,7 +10589,8 @@ template <typename Derived>
OMPClause *
TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
return getDerived().RebuildOMPDefaultClause(
- C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getBeginLoc(),
+ C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getDefaultVC(), C->getDefaultVCLoc(),
+ C->getBeginLoc(),
C->getLParenLoc(), C->getEndLoc());
}
>From f8a23a01bbd8f6d2b14c437ef47659aa0e2b8be4 Mon Sep 17 00:00:00 2001
From: Sunil Kuravinakop <kuravina at pe31.hpc.amslabs.hpecorp.net>
Date: Tue, 12 Aug 2025 05:30:23 -0500
Subject: [PATCH 2/9] Serializer and git-clang-format on some of the files in
previous commit.
---
clang/include/clang/AST/OpenMPClause.h | 10 +++++++---
clang/include/clang/Basic/OpenMPKinds.h | 7 ++++---
clang/include/clang/Sema/SemaOpenMP.h | 10 +++++-----
clang/lib/AST/OpenMPClause.cpp | 2 ++
clang/lib/Basic/OpenMPKinds.cpp | 19 ++++++++++++++++---
clang/lib/Sema/SemaOpenMP.cpp | 9 +++++----
clang/lib/Sema/TreeTransform.h | 10 +++++-----
clang/lib/Serialization/ASTReader.cpp | 3 +++
clang/lib/Serialization/ASTWriter.cpp | 2 ++
9 files changed, 49 insertions(+), 23 deletions(-)
diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h
index 9f2483a722c16..a01a4f449e939 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -1286,9 +1286,13 @@ class OMPDefaultClause : public OMPClause {
void setDefaultKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
/// Set Variable Category used with the Kind Clause (Default Modifier)
- void setDefaultVariableCategory(OpenMPDefaultClauseVariableCategory VC) { this->VC = VC; }
+ void setDefaultVariableCategory(OpenMPDefaultClauseVariableCategory VC) {
+ this->VC = VC;
+ }
- void setDefaultVariableCategoryLocation(SourceLocation VCLoc) { this->VCLoc = VCLoc; }
+ void setDefaultVariableCategoryLocation(SourceLocation VCLoc) {
+ this->VCLoc = VCLoc;
+ }
public:
/// Build 'default' clause with argument \a A ('none' or 'shared').
@@ -1299,7 +1303,7 @@ class OMPDefaultClause : public OMPClause {
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
OMPDefaultClause(llvm::omp::DefaultKind A, SourceLocation ALoc,
- OpenMPDefaultClauseVariableCategory VC, SourceLocation VCLoc,
+ OpenMPDefaultClauseVariableCategory VC, SourceLocation VCLoc,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
: OMPClause(llvm::omp::OMPC_default, StartLoc, EndLoc),
diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h
index e63f1cfd23ca0..ab542ca5a1227 100644
--- a/clang/include/clang/Basic/OpenMPKinds.h
+++ b/clang/include/clang/Basic/OpenMPKinds.h
@@ -109,8 +109,7 @@ enum OpenMPDistScheduleClauseKind {
/// OpenMP variable-category for 'default' clause.
enum OpenMPDefaultClauseVariableCategory {
-#define OPENMP_DEFAULT_VARIABLE_CATEGORY(Name) \
- OMPC_DEFAULT_VC_##Name,
+#define OPENMP_DEFAULT_VARIABLE_CATEGORY(Name) OMPC_DEFAULT_VC_##Name,
#include "clang/Basic/OpenMPKinds.def"
OMPC_DEFAULT_VC_unknown
};
@@ -265,7 +264,9 @@ struct OMPInteropInfo final {
llvm::SmallVector<Expr *, 4> PreferTypes;
};
-unsigned getOpenMPDefaultVariableCategory(StringRef Str, const LangOptions &LangOpts);
+unsigned getOpenMPDefaultVariableCategory(StringRef Str,
+ const LangOptions &LangOpts);
+const char *getOpenMPDefaultVariableCategoryName(unsigned VC);
unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str,
const LangOptions &LangOpts);
diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h
index 35c01b22a0b28..23827051ed724 100644
--- a/clang/include/clang/Sema/SemaOpenMP.h
+++ b/clang/include/clang/Sema/SemaOpenMP.h
@@ -951,11 +951,11 @@ class SemaOpenMP : public SemaBase {
SourceLocation LParenLoc,
SourceLocation EndLoc);
/// Called on well-formed 'default' clause.
- OMPClause *ActOnOpenMPDefaultClause(
- llvm::omp::DefaultKind M, SourceLocation MLoc,
- OpenMPDefaultClauseVariableCategory VCKind, SourceLocation VCKindLoc,
- SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc);
+ OMPClause *
+ ActOnOpenMPDefaultClause(llvm::omp::DefaultKind M, SourceLocation MLoc,
+ OpenMPDefaultClauseVariableCategory VCKind,
+ SourceLocation VCKindLoc, 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 de8b5996818de..06f34ecf2684c 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -1911,6 +1911,8 @@ void OMPClausePrinter::VisitOMPDefaultClause(OMPDefaultClause *Node) {
OS << "default("
<< getOpenMPSimpleClauseTypeName(OMPC_default,
unsigned(Node->getDefaultKind()))
+ << ":"
+ << getOpenMPDefaultVariableCategoryName(unsigned(Node->getDefaultVC()))
<< ")";
}
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index d99953154d73e..46e926a9f0a1a 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -20,14 +20,27 @@
using namespace clang;
using namespace llvm::omp;
-unsigned clang::getOpenMPDefaultVariableCategory(StringRef Str, const LangOptions &LangOpts) {
+unsigned clang::getOpenMPDefaultVariableCategory(StringRef Str,
+ const LangOptions &LangOpts) {
unsigned VC = llvm::StringSwitch<unsigned>(Str)
-#define OPENMP_DEFAULT_VARIABLE_CATEGORY(Name) .Case(#Name, OMPC_DEFAULT_VC_##Name)
+#define OPENMP_DEFAULT_VARIABLE_CATEGORY(Name) \
+ .Case(#Name, OMPC_DEFAULT_VC_##Name)
#include "clang/Basic/OpenMPKinds.def"
- .Default(OMPC_DEFAULT_VC_unknown);
+ .Default(OMPC_DEFAULT_VC_unknown);
return VC;
}
+const char *clang::getOpenMPDefaultVariableCategoryName(unsigned VC) {
+ switch (VC) {
+#define OPENMP_DEFAULT_VARIABLE_CATEGORY(Name) \
+ case OMPC_DEFAULT_VC_##Name: \
+ return #Name;
+#include "clang/Basic/OpenMPKinds.def"
+ default:
+ return "unknown";
+ }
+}
+
unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
const LangOptions &LangOpts) {
switch (Kind) {
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 606119715a91f..b22a445f814ab 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -16375,7 +16375,8 @@ OMPClause *SemaOpenMP::ActOnOpenMPDefaultClause(
}
if (VCKind < 0 || VCKind >= OMPC_DEFAULT_VC_unknown) {
- Diag(VCKindLoc, diag::err_omp_default_vc) << getOpenMPSimpleClauseTypeName(OMPC_default, unsigned(M));
+ Diag(VCKindLoc, diag::err_omp_default_vc)
+ << getOpenMPSimpleClauseTypeName(OMPC_default, unsigned(M));
}
return new (getASTContext())
@@ -16690,9 +16691,9 @@ OMPClause *SemaOpenMP::ActOnOpenMPSingleExprWithArgClause(
Res = ActOnOpenMPDefaultClause(
static_cast<llvm::omp::DefaultKind>(Argument[DefaultModifier]),
ArgumentLoc[DefaultModifier],
- static_cast<OpenMPDefaultClauseVariableCategory>(Argument[DefaultVarCategory]),
- ArgumentLoc[DefaultVarCategory],
- StartLoc, LParenLoc, EndLoc);
+ static_cast<OpenMPDefaultClauseVariableCategory>(
+ Argument[DefaultVarCategory]),
+ ArgumentLoc[DefaultVarCategory], StartLoc, LParenLoc, EndLoc);
break;
case OMPC_defaultmap:
enum { Modifier, DefaultmapKind };
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 5f26427c490b2..c9964bce550fb 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -1804,8 +1804,8 @@ class TreeTransform {
/// By default, performs semantic analysis to build the new OpenMP clause.
/// Subclasses may override this routine to provide different behavior.
OMPClause *RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc,
- OpenMPDefaultClauseVariableCategory VCKind,
- SourceLocation VCLoc,
+ OpenMPDefaultClauseVariableCategory VCKind,
+ SourceLocation VCLoc,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc) {
@@ -10589,9 +10589,9 @@ template <typename Derived>
OMPClause *
TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
return getDerived().RebuildOMPDefaultClause(
- C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getDefaultVC(), C->getDefaultVCLoc(),
- C->getBeginLoc(),
- C->getLParenLoc(), C->getEndLoc());
+ C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getDefaultVC(),
+ C->getDefaultVCLoc(), C->getBeginLoc(), C->getLParenLoc(),
+ C->getEndLoc());
}
template <typename Derived>
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 682d26394c0d5..1ca2d3629876d 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -11641,6 +11641,9 @@ void OMPClauseReader::VisitOMPDefaultClause(OMPDefaultClause *C) {
C->setDefaultKind(static_cast<llvm::omp::DefaultKind>(Record.readInt()));
C->setLParenLoc(Record.readSourceLocation());
C->setDefaultKindKwLoc(Record.readSourceLocation());
+ C->setDefaultVariableCategory(
+ static_cast<OpenMPDefaultClauseVariableCategory>(Record.readInt()));
+ C->setDefaultVariableCategoryLocation(Record.readSourceLocation());
}
void OMPClauseReader::VisitOMPProcBindClause(OMPProcBindClause *C) {
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index a6957e54b66f1..d280c47115187 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -7873,6 +7873,8 @@ void OMPClauseWriter::VisitOMPDefaultClause(OMPDefaultClause *C) {
Record.push_back(unsigned(C->getDefaultKind()));
Record.AddSourceLocation(C->getLParenLoc());
Record.AddSourceLocation(C->getDefaultKindKwLoc());
+ Record.push_back(unsigned(C->getDefaultVC()));
+ Record.AddSourceLocation(C->getDefaultVCLoc());
}
void OMPClauseWriter::VisitOMPProcBindClause(OMPProcBindClause *C) {
>From 3d6a174d6048e45066dc54bd8e0f5ee1e4695d05 Mon Sep 17 00:00:00 2001
From: Sunil Kuravinakop <kuravina at pe31.hpc.amslabs.hpecorp.net>
Date: Mon, 25 Aug 2025 13:07:01 -0500
Subject: [PATCH 3/9] Code for restricting the modifier of the default clause
based on the variable category attribute.
---
clang/lib/Sema/SemaOpenMP.cpp | 81 ++++++++++++++++++++++++++++++++++-
1 file changed, 79 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index b22a445f814ab..18e6690fbc26f 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -72,6 +72,18 @@ enum DefaultDataSharingAttributes {
DSA_firstprivate = 1 << 3, /// Default data sharing attribute 'firstprivate'.
};
+/// Variable Category attributes to restrict the modifier of the
+/// default clause (DefaultDataSharingAttributes)
+/// Not mentioning any Variable category attribute indicates
+/// the modifier (DefaultDataSharingAttributes) is for all variables.
+enum DefaultDataSharingVCAttributes {
+ DSA_VC_all = 0, /// for all variables.
+ DSA_VC_aggregate = 1 << 0, /// for aggregate variables.
+ DSA_VC_allocatable = 1 << 1, /// for allocatable variables.
+ DSA_VC_pointer = 1 << 2, /// for pointer variables.
+ DSA_VC_scalar = 1 << 3, /// for scalar variables.
+};
+
/// Stack for tracking declarations used in OpenMP directives and
/// clauses and their data-sharing attributes.
class DSAStackTy {
@@ -167,6 +179,8 @@ class DSAStackTy {
LoopControlVariablesMapTy LCVMap;
DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
SourceLocation DefaultAttrLoc;
+ DefaultDataSharingVCAttributes DefaultVCAttr = DSA_VC_all;
+ SourceLocation DefaultAttrVCLoc;
DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown + 1];
OpenMPDirectiveKind Directive = OMPD_unknown;
DeclarationNameInfo DirectiveName;
@@ -734,6 +748,31 @@ class DSAStackTy {
getTopOfStack().DefaultAttr = DSA_firstprivate;
getTopOfStack().DefaultAttrLoc = Loc;
}
+ /// Set default data sharing variable category attribute to aggregate.
+ void setDefaultDSAVCAggregate(SourceLocation VCLoc) {
+ getTopOfStack().DefaultVCAttr = DSA_VC_aggregate;
+ getTopOfStack().DefaultAttrVCLoc = VCLoc;
+ }
+ /// Set default data sharing variable category attribute to all.
+ void setDefaultDSAVCAll(SourceLocation VCLoc) {
+ getTopOfStack().DefaultVCAttr = DSA_VC_all;
+ getTopOfStack().DefaultAttrVCLoc = VCLoc;
+ }
+ /// Set default data sharing variable category attribute to allocatable.
+ void setDefaultDSAVCAllocatable(SourceLocation VCLoc) {
+ getTopOfStack().DefaultVCAttr = DSA_VC_allocatable;
+ getTopOfStack().DefaultAttrVCLoc = VCLoc;
+ }
+ /// Set default data sharing variable category attribute to pointer.
+ void setDefaultDSAVCPointer(SourceLocation VCLoc) {
+ getTopOfStack().DefaultVCAttr = DSA_VC_pointer;
+ getTopOfStack().DefaultAttrVCLoc = VCLoc;
+ }
+ /// Set default data sharing variable category attribute to scalar.
+ void setDefaultDSAVCScalar(SourceLocation VCLoc) {
+ getTopOfStack().DefaultVCAttr = DSA_VC_scalar;
+ getTopOfStack().DefaultAttrVCLoc = VCLoc;
+ }
/// Set default data mapping attribute to Modifier:Kind
void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
OpenMPDefaultmapClauseKind Kind, SourceLocation Loc) {
@@ -1325,11 +1364,33 @@ DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
return DVar;
}
+ DefaultDataSharingAttributes IterDA = Iter->DefaultAttr;
+ switch (Iter->DefaultVCAttr) {
+ case DSA_VC_aggregate:
+ if (!VD->getType()->isAggregateType())
+ IterDA = DSA_none;
+ break;
+ case DSA_VC_allocatable:
+ if (!(VD->getType()->isPointerType() ||
+ VD->getType()->isVariableArrayType()))
+ IterDA = DSA_none;
+ break;
+ case DSA_VC_pointer:
+ if (!VD->getType()->isPointerType())
+ IterDA = DSA_none;
+ break;
+ case DSA_VC_scalar:
+ if (!VD->getType()->isScalarType())
+ IterDA = DSA_none;
+ break;
+ default:;
+ }
+
// OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
// in a Construct, C/C++, implicitly determined, p.1]
// In a parallel or task construct, the data-sharing attributes of these
// variables are determined by the default clause, if present.
- switch (Iter->DefaultAttr) {
+ switch (IterDA) {
case DSA_shared:
DVar.CKind = OMPC_shared;
DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
@@ -16374,7 +16435,23 @@ OMPClause *SemaOpenMP::ActOnOpenMPDefaultClause(
llvm_unreachable("DSA unexpected in OpenMP default clause");
}
- if (VCKind < 0 || VCKind >= OMPC_DEFAULT_VC_unknown) {
+ switch (VCKind) {
+ case OMPC_DEFAULT_VC_aggregate:
+ DSAStack->setDefaultDSAVCAggregate(VCKindLoc);
+ break;
+ case OMPC_DEFAULT_VC_all:
+ DSAStack->setDefaultDSAVCAll(VCKindLoc);
+ break;
+ case OMPC_DEFAULT_VC_allocatable:
+ DSAStack->setDefaultDSAVCAllocatable(VCKindLoc);
+ break;
+ case OMPC_DEFAULT_VC_pointer:
+ DSAStack->setDefaultDSAVCPointer(VCKindLoc);
+ break;
+ case OMPC_DEFAULT_VC_scalar:
+ DSAStack->setDefaultDSAVCScalar(VCKindLoc);
+ break;
+ default:
Diag(VCKindLoc, diag::err_omp_default_vc)
<< getOpenMPSimpleClauseTypeName(OMPC_default, unsigned(M));
}
>From 333132859872dad6d47dde705baa566c42a68866 Mon Sep 17 00:00:00 2001
From: Sunil Kuravinakop <kuravina at pe31.hpc.amslabs.hpecorp.net>
Date: Fri, 5 Sep 2025 02:17:42 -0500
Subject: [PATCH 4/9] Clearing up check-clang and check-openmp test results.
Removing redundant "#define OPENMP_DEFAULT_VARIABLE_CATEGORY" in
clang/lib/Basic/OpenMPKinds.cpp.
---
clang/lib/AST/OpenMPClause.cpp | 11 +++--
clang/lib/Basic/OpenMPKinds.cpp | 2 -
clang/lib/Parse/ParseOpenMP.cpp | 12 ++++++
clang/test/OpenMP/parallel_ast_print.cpp | 42 +++++++++++++++++++
.../test/OpenMP/parallel_default_messages.cpp | 18 ++++++++
5 files changed, 79 insertions(+), 6 deletions(-)
diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index 06f34ecf2684c..900227294590c 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -1910,10 +1910,13 @@ void OMPClausePrinter::VisitOMPDetachClause(OMPDetachClause *Node) {
void OMPClausePrinter::VisitOMPDefaultClause(OMPDefaultClause *Node) {
OS << "default("
<< getOpenMPSimpleClauseTypeName(OMPC_default,
- unsigned(Node->getDefaultKind()))
- << ":"
- << getOpenMPDefaultVariableCategoryName(unsigned(Node->getDefaultVC()))
- << ")";
+ unsigned(Node->getDefaultKind()));
+ if (Version >= 60 && Node->getDefaultVC() != OMPC_DEFAULT_VC_all) {
+ OS << ":"
+ << getOpenMPDefaultVariableCategoryName(unsigned(Node->getDefaultVC()));
+ }
+
+ OS << ")";
}
void OMPClausePrinter::VisitOMPProcBindClause(OMPProcBindClause *Node) {
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 46e926a9f0a1a..0883a2bb42784 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -113,8 +113,6 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
.Default(OMPC_DIST_SCHEDULE_unknown);
case OMPC_defaultmap:
return llvm::StringSwitch<unsigned>(Str)
-#define OPENMP_DEFAULT_VARIABLE_CATEGORY(Name) \
- .Case(#Name, static_cast<unsigned>(OMPC_DEFAULT_VC_##Name))
#define OPENMP_DEFAULTMAP_KIND(Name) \
.Case(#Name, static_cast<unsigned>(OMPC_DEFAULTMAP_##Name))
#define OPENMP_DEFAULTMAP_MODIFIER(Name) \
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index d6d0e3bbf4e6b..625e015f267c2 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -3957,6 +3957,18 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind,
if (NeedAnExpression && Val.isInvalid())
return nullptr;
+ if (Kind == OMPC_default && getLangOpts().OpenMP < 51 && Arg[0] &&
+ (static_cast<DefaultKind>(Arg[0]) == OMP_DEFAULT_private ||
+ static_cast<DefaultKind>(Arg[0]) == OMP_DEFAULT_firstprivate)) {
+ Diag(KLoc[0], diag::err_omp_invalid_dsa)
+ << getOpenMPClauseName(static_cast<DefaultKind>(Arg[0]) ==
+ OMP_DEFAULT_private
+ ? OMPC_private
+ : OMPC_firstprivate)
+ << getOpenMPClauseName(OMPC_default) << "5.1";
+ return nullptr;
+ }
+
if (ParseOnly)
return nullptr;
return Actions.OpenMP().ActOnOpenMPSingleExprWithArgClause(
diff --git a/clang/test/OpenMP/parallel_ast_print.cpp b/clang/test/OpenMP/parallel_ast_print.cpp
index 15439ea31215a..28dc611bf864d 100644
--- a/clang/test/OpenMP/parallel_ast_print.cpp
+++ b/clang/test/OpenMP/parallel_ast_print.cpp
@@ -21,11 +21,19 @@
// RUN: %clang_cc1 -DOMP60 -verify -Wno-vla -fopenmp-simd -fopenmp-version=60 -ast-print %s | FileCheck -check-prefixes=CHECK,OMP60 %s
// RUN: %clang_cc1 -DOMP60 -fopenmp-simd -fopenmp-version=60 -x c++ -std=c++11 -emit-pch -o %t %s
// RUN: %clang_cc1 -DOMP60 -fopenmp-simd -fopenmp-version=60 -std=c++11 -include-pch %t -verify -Wno-vla %s -ast-print | FileCheck -check-prefixes=CHECK,OMP60 %s
+// RUN: %clang_cc1 -DOMP60 -fopenmp-simd -fopenmp-version=60 -std=c++11 -verify -Wno-vla %s -ast-dump | FileCheck -check-prefixes=OMP60_DUMP %s
// expected-no-diagnostics
#ifndef HEADER
#define HEADER
+#ifdef OMP60
+int global;
+int global2;
+
+void bar(int j) { };
+#endif
+
void foo() {}
struct S1 {
@@ -185,6 +193,32 @@ T tmain(T argc, T *argv) {
return 0;
}
+
+#ifdef OMP60
+// OMP60_DUMP: FunctionDecl {{.*}}mainVC {{.*}}
+// OMP60_DUMP: OMPParallelDirective {{.*}}
+// OMP60_DUMP-NEXT: OMPSharedClause{{.*}}
+// OMP60_DUMP-NEXT: {{.*}}DeclRefExpr{{.*}} 'global' 'int'{{.*}}
+// OMP60_DUMP-NEXT: OMPDefaultClause {{.*}}
+// OMP60_DUMP-NEXT: OMPFirstprivateClause{{.*}}
+// OMP60_DUMP-NEXT: {{.*}}DeclRefExpr{{.*}} 'h' 'int[20]'{{.*}}
+// OMP60_DUMP: OMPParallelDirective {{.*}}
+// OMP60_DUMP-NEXT: OMPPrivateClause{{.*}}
+// OMP60_DUMP-NEXT: {{.*}}DeclRefExpr{{.*}} 'global2' 'int'{{.*}}
+// OMP60_DUMP-NEXT: OMPDefaultClause {{.*}}
+// OMP60_DUMP-NEXT: OMPPrivateClause {{.*}}
+// OMP60_DUMP-NEXT: {{.*}}DeclRefExpr{{.*}} 'j' 'int'{{.*}}
+int mainVC(int argc, int *argv) {
+ int h[20];
+ int j;
+#pragma omp parallel shared(global) default(firstprivate: aggregate)
+ bar(h[1]), h[1] = global;
+#pragma omp parallel private(global2) default(private: scalar)
+ bar(global2), j = global2;
+ return 0;
+}
+#endif
+
// CHECK: template <typename T, int C> T tmain(T argc, T *argv) {
// CHECK-NEXT: T b = argc, c, d, e, f, g;
// CHECK-NEXT: static T a;
@@ -237,6 +271,14 @@ T tmain(T argc, T *argv) {
// OMP60-NEXT: #pragma omp parallel if(1) num_threads(strict: s) proc_bind(close) reduction(^: e,f,arr[0:1][:argc]) reduction(default, &&: g) reduction(task, +: argc) message("msg") severity(warning)
// OMP60-NEXT: foo()
+// OMP60: int mainVC(int argc, int *argv) {
+// OMP60-NEXT: int h[20];
+// OMP60-NEXT: int j;
+// OMP60-NEXT: #pragma omp parallel shared(global) default(firstprivate:aggregate)
+// OMP60-NEXT: bar(h[1]) , h[1] = global;
+// OMP60-NEXT: #pragma omp parallel private(global2) default(private:scalar)
+// OMP60-NEXT: bar(global2) , j = global2;
+
enum Enum { };
int main (int argc, char **argv) {
diff --git a/clang/test/OpenMP/parallel_default_messages.cpp b/clang/test/OpenMP/parallel_default_messages.cpp
index 37d3b5565f83c..842b1ac5a96b8 100644
--- a/clang/test/OpenMP/parallel_default_messages.cpp
+++ b/clang/test/OpenMP/parallel_default_messages.cpp
@@ -6,6 +6,7 @@
// RUN: %clang_cc1 -verify -fopenmp-version=30 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized
// RUN: %clang_cc1 -verify=expected,ge40 -fopenmp -DOMP51 -ferror-limit 100 -o - %s -Wuninitialized
// RUN: %clang_cc1 -verify=expected,ge40 -fopenmp-simd -DOMP51 -ferror-limit 100 -o - %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,ge40 -fopenmp-version=60 -fopenmp -DOMP60 -ferror-limit 100 -o - %s -Wuninitialized
void foo();
@@ -47,6 +48,23 @@ int main(int argc, char **argv) {
}
#endif
+#ifdef OMP60
+#pragma omp parallel default(shared:) private(x,y) // expected-error {{wrong variable category specified with modifier shared in the default clause}}
+ {
+ ++x;
+ ++y;
+ }
+#pragma omp parallel default(shared: junk) private(x,y) // expected-error {{wrong variable category specified with modifier shared in the default clause}}
+ {
+ ++x;
+ ++y;
+ }
+#pragma omp parallel default(firstprivate: junk) private(x,y) // expected-error {{wrong variable category specified with modifier firstprivate in the default clause}}
+ {
+ ++x;
+ ++y;
+ }
+#endif
return 0;
}
>From 01e164f089a0dd6f43f6a27741fa8ffbf7381e98 Mon Sep 17 00:00:00 2001
From: Sunil Kuravinakop <kuravina at pe31.hpc.amslabs.hpecorp.net>
Date: Fri, 5 Sep 2025 15:53:16 -0500
Subject: [PATCH 5/9] Taking care of review feedback: 1) Avoiding casting to
unsigned but, using the enum as return value in
getOpenMPDefaultVariableCategory(). 2) default is not needed
getOpenMPDefaultVariableCategoryName().
---
clang/include/clang/Basic/OpenMPKinds.h | 4 ++--
clang/lib/Basic/OpenMPKinds.cpp | 13 +++++--------
clang/lib/Parse/ParseOpenMP.cpp | 5 +++--
3 files changed, 10 insertions(+), 12 deletions(-)
diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h
index ab542ca5a1227..be0e79ae17123 100644
--- a/clang/include/clang/Basic/OpenMPKinds.h
+++ b/clang/include/clang/Basic/OpenMPKinds.h
@@ -264,8 +264,8 @@ struct OMPInteropInfo final {
llvm::SmallVector<Expr *, 4> PreferTypes;
};
-unsigned getOpenMPDefaultVariableCategory(StringRef Str,
- const LangOptions &LangOpts);
+OpenMPDefaultClauseVariableCategory
+getOpenMPDefaultVariableCategory(StringRef Str, const LangOptions &LangOpts);
const char *getOpenMPDefaultVariableCategoryName(unsigned VC);
unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str,
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 0883a2bb42784..21b67aba52cdf 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -20,14 +20,14 @@
using namespace clang;
using namespace llvm::omp;
-unsigned clang::getOpenMPDefaultVariableCategory(StringRef Str,
- const LangOptions &LangOpts) {
- unsigned VC = llvm::StringSwitch<unsigned>(Str)
+OpenMPDefaultClauseVariableCategory
+clang::getOpenMPDefaultVariableCategory(StringRef Str,
+ const LangOptions &LangOpts) {
+ return llvm::StringSwitch<OpenMPDefaultClauseVariableCategory>(Str)
#define OPENMP_DEFAULT_VARIABLE_CATEGORY(Name) \
.Case(#Name, OMPC_DEFAULT_VC_##Name)
#include "clang/Basic/OpenMPKinds.def"
- .Default(OMPC_DEFAULT_VC_unknown);
- return VC;
+ .Default(OMPC_DEFAULT_VC_unknown);
}
const char *clang::getOpenMPDefaultVariableCategoryName(unsigned VC) {
@@ -36,8 +36,6 @@ const char *clang::getOpenMPDefaultVariableCategoryName(unsigned VC) {
case OMPC_DEFAULT_VC_##Name: \
return #Name;
#include "clang/Basic/OpenMPKinds.def"
- default:
- return "unknown";
}
}
@@ -917,4 +915,3 @@ bool clang::checkFailClauseParameter(OpenMPClauseKind FailClauseParameter) {
FailClauseParameter == llvm::omp::OMPC_relaxed ||
FailClauseParameter == llvm::omp::OMPC_seq_cst;
}
-
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 32b9ba95db9ed..7dceb2d208352 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -3748,8 +3748,9 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind,
if (Tok.is(tok::colon) && getLangOpts().OpenMP >= 60) {
ConsumeAnyToken();
// Get a variable-category attribute for default clause modifier
- unsigned VariableCategory = getOpenMPDefaultVariableCategory(
- Tok.isAnnotation() ? "" : PP.getSpelling(Tok), getLangOpts());
+ OpenMPDefaultClauseVariableCategory VariableCategory =
+ getOpenMPDefaultVariableCategory(
+ Tok.isAnnotation() ? "" : PP.getSpelling(Tok), getLangOpts());
Arg.push_back(VariableCategory);
KLoc.push_back(Tok.getLocation());
if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
>From 3393f230a1537b877005e81bada934c73a789fa4 Mon Sep 17 00:00:00 2001
From: Sunil Kuravinakop <kuravina at pe31.hpc.amslabs.hpecorp.net>
Date: Fri, 5 Sep 2025 16:11:03 -0500
Subject: [PATCH 6/9] Avoiding a non-Null return warning.
---
clang/lib/Basic/OpenMPKinds.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 21b67aba52cdf..e0cffcd270f94 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -37,6 +37,7 @@ const char *clang::getOpenMPDefaultVariableCategoryName(unsigned VC) {
return #Name;
#include "clang/Basic/OpenMPKinds.def"
}
+ return "unknown";
}
unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
>From 0f4a8841c32379918dcdba679384b95286ddc1af Mon Sep 17 00:00:00 2001
From: Sunil Kuravinakop <kuravina at pe31.hpc.amslabs.hpecorp.net>
Date: Sat, 6 Sep 2025 00:53:17 -0500
Subject: [PATCH 7/9] Using llvm_unreachable instead of return "unknown".
---
clang/lib/Basic/OpenMPKinds.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index e0cffcd270f94..b957652d1383c 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -37,7 +37,7 @@ const char *clang::getOpenMPDefaultVariableCategoryName(unsigned VC) {
return #Name;
#include "clang/Basic/OpenMPKinds.def"
}
- return "unknown";
+ llvm_unreachable("Invalid Variable Category in the default clause");
}
unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
>From 803bc30543926dc35752d01a027a9d551071bcdb Mon Sep 17 00:00:00 2001
From: Sunil Kuravinakop <kuravina at pe31.hpc.amslabs.hpecorp.net>
Date: Thu, 11 Sep 2025 13:51:12 -0500
Subject: [PATCH 8/9] Incorporating feedback from Alexey.
---
clang/include/clang/AST/OpenMPClause.h | 4 ++--
clang/lib/Sema/SemaOpenMP.cpp | 3 ++-
clang/lib/Serialization/ASTReader.cpp | 2 +-
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h
index f6211d4497531..b2a6d4b9182b0 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -1326,9 +1326,9 @@ class OMPDefaultClause : public OMPClause {
/// Returns location of clause kind.
SourceLocation getDefaultKindKwLoc() const { return KindKwLoc; }
- OpenMPDefaultClauseVariableCategory getDefaultVC() { return VC; }
+ OpenMPDefaultClauseVariableCategory getDefaultVC() const { return VC; }
- SourceLocation getDefaultVCLoc() { return VCLoc; }
+ SourceLocation getDefaultVCLoc() const { return VCLoc; }
child_range children() {
return child_range(child_iterator(), child_iterator());
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index c14bc9b3cb61f..b7e494c201caa 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -1384,7 +1384,8 @@ DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
if (!VD->getType()->isScalarType())
IterDA = DSA_none;
break;
- default:;
+ case DSA_VC_all:
+ break;
}
// OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 7015087647d31..ac70e8c7dcfb0 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -11647,7 +11647,7 @@ void OMPClauseReader::VisitOMPDefaultClause(OMPDefaultClause *C) {
C->setLParenLoc(Record.readSourceLocation());
C->setDefaultKindKwLoc(Record.readSourceLocation());
C->setDefaultVariableCategory(
- static_cast<OpenMPDefaultClauseVariableCategory>(Record.readInt()));
+ Record.readEnum<OpenMPDefaultClauseVariableCategory>());
C->setDefaultVariableCategoryLocation(Record.readSourceLocation());
}
>From aa4c6075af0392decfc914265defa5f4cce5896a Mon Sep 17 00:00:00 2001
From: Sunil Kuravinakop <kuravina at pe31.hpc.amslabs.hpecorp.net>
Date: Thu, 11 Sep 2025 14:32:47 -0500
Subject: [PATCH 9/9] Incorporating feedback from Alexey.
---
clang/lib/Sema/SemaOpenMP.cpp | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index b7e494c201caa..55538e413ab70 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -78,11 +78,11 @@ enum DefaultDataSharingAttributes {
/// Not mentioning any Variable category attribute indicates
/// the modifier (DefaultDataSharingAttributes) is for all variables.
enum DefaultDataSharingVCAttributes {
- DSA_VC_all = 0, /// for all variables.
- DSA_VC_aggregate = 1 << 0, /// for aggregate variables.
- DSA_VC_allocatable = 1 << 1, /// for allocatable variables.
- DSA_VC_pointer = 1 << 2, /// for pointer variables.
- DSA_VC_scalar = 1 << 3, /// for scalar variables.
+ DSA_VC_all = 0, /// for all variables.
+ DSA_VC_aggregate, /// for aggregate variables.
+ DSA_VC_allocatable, /// for allocatable variables.
+ DSA_VC_pointer, /// for pointer variables.
+ DSA_VC_scalar, /// for scalar variables.
};
/// Stack for tracking declarations used in OpenMP directives and
More information about the cfe-commits
mailing list