Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clang/docs/OpenMPSupport.rst
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,7 @@ implementation.
| | | | |
| | | | Flang parser: https://github.com/llvm/llvm-project/pull/153807 |
| | | | Flang sema: https://github.com/llvm/llvm-project/pull/154779 |
| | | | Clang parse/sema: https://github.com/llvm/llvm-project/pull/158134 |
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
| variable-category on default clause | :good:`done` | :none:`unclaimed` | |
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
Expand Down
1 change: 1 addition & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,7 @@ OpenMP Support
- Added support for ``variable-category`` modifier in ``default clause``.
- Added support for ``defaultmap`` directive implicit-behavior ``storage``.
- Added support for ``defaultmap`` directive implicit-behavior ``private``.
- Added parsing and semantic analysis support for ``groupprivate`` directive.

Improvements
^^^^^^^^^^^^
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/AST/ASTMutationListener.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ class ASTMutationListener {
/// \param D the declaration marked OpenMP threadprivate.
virtual void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {}

/// A declaration is marked as OpenMP groupprivate which was not
/// previously marked as groupprivate.
///
/// \param D the declaration marked OpenMP groupprivate.
virtual void DeclarationMarkedOpenMPGroupPrivate(const Decl *D) {}

/// A declaration is marked as OpenMP declaretarget which was not
/// previously marked as declaretarget.
///
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/AST/ASTNodeTraverser.h
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,11 @@ class ASTNodeTraverser
Visit(E);
}

void VisitOMPGroupPrivateDecl(const OMPGroupPrivateDecl *D) {
for (const auto *E : D->varlist())
Visit(E);
}

void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) {
Visit(D->getCombiner());
if (const auto *Initializer = D->getInitializer())
Expand Down
62 changes: 62 additions & 0 deletions clang/include/clang/AST/DeclOpenMP.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,68 @@ class OMPThreadPrivateDecl final : public OMPDeclarativeDirective<Decl> {
static bool classofKind(Kind K) { return K == OMPThreadPrivate; }
};

/// This represents '#pragma omp groupprivate ...' directive.
/// For example, in the following, both 'a' and 'A::b' are groupprivate:
///
/// \code
/// int a;
/// #pragma omp groupprivate(a)
/// struct A {
/// static int b;
/// #pragma omp groupprivate(b)
/// };
/// \endcode
///
class OMPGroupPrivateDecl final : public OMPDeclarativeDirective<Decl> {
friend class OMPDeclarativeDirective<Decl>;

LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION();

OMPGroupPrivateDecl(DeclContext *DC = nullptr,
SourceLocation L = SourceLocation())
: OMPDeclarativeDirective<Decl>(OMPGroupPrivate, DC, L) {}

ArrayRef<const Expr *> getVars() const {
auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
return {Storage, Data->getNumChildren()};
}

MutableArrayRef<Expr *> getVars() {
auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
return {Storage, Data->getNumChildren()};
}

void setVars(ArrayRef<Expr *> VL);

public:
static OMPGroupPrivateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, ArrayRef<Expr *> VL);
static OMPGroupPrivateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
unsigned N);

typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
typedef llvm::iterator_range<varlist_iterator> varlist_range;
typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;

unsigned varlist_size() const { return Data->getNumChildren(); }
bool varlist_empty() const { return Data->getChildren().empty(); }

varlist_range varlist() {
return varlist_range(varlist_begin(), varlist_end());
}
varlist_const_range varlist() const {
return varlist_const_range(varlist_begin(), varlist_end());
}
varlist_iterator varlist_begin() { return getVars().begin(); }
varlist_iterator varlist_end() { return getVars().end(); }
varlist_const_iterator varlist_begin() const { return getVars().begin(); }
varlist_const_iterator varlist_end() const { return getVars().end(); }

static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == OMPGroupPrivate; }
};

enum class OMPDeclareReductionInitKind {
Call, // Initialized by function call.
Direct, // omp_priv(<expr>)
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/AST/RecursiveASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -1887,6 +1887,12 @@ DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
}
})

DEF_TRAVERSE_DECL(OMPGroupPrivateDecl, {
for (auto *I : D->varlist()) {
TRY_TO(TraverseStmt(I));
}
})

DEF_TRAVERSE_DECL(OMPRequiresDecl, {
for (auto *C : D->clauselists()) {
TRY_TO(TraverseOMPClause(C));
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -4585,6 +4585,12 @@ def OMPThreadPrivateDecl : InheritableAttr {
let Documentation = [InternalOnly];
}

def OMPGroupPrivateDecl : InheritableAttr {
let Spellings = [];
let SemaHandler = 0;
let Documentation = [InternalOnly];
}

def OMPCaptureNoInit : InheritableAttr {
// This attribute has no spellings as it is only ever created implicitly.
let Spellings = [];
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/DeclNodes.td
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ def OutlinedFunction : DeclNode<Decl>, DeclContext;
def Captured : DeclNode<Decl>, DeclContext;
def Import : DeclNode<Decl>;
def OMPThreadPrivate : DeclNode<Decl>;
def OMPGroupPrivate : DeclNode<Decl>;
def OMPAllocate : DeclNode<Decl>;
def OMPRequires : DeclNode<Decl>;
def Empty : DeclNode<Decl>;
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -11708,6 +11708,10 @@ def err_omp_threadprivate_incomplete_type : Error<
"threadprivate variable with incomplete type %0">;
def err_omp_no_dsa_for_variable : Error<
"variable %0 must have explicitly specified data sharing attributes">;
def err_omp_groupprivate_incomplete_type : Error<
"groupprivate variable with incomplete type %0">;
def err_omp_groupprivate_with_initializer : Error<
"variable %0 with initializer cannot appear in groupprivate directive">;
def err_omp_defaultmap_no_attr_for_variable : Error<
"variable %0 must have explicitly specified data sharing attributes, data mapping attributes, or in an is_device_ptr clause">;
def note_omp_default_dsa_none : Note<
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Sema/SemaOpenMP.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,12 @@ class SemaOpenMP : public SemaBase {
/// Builds a new OpenMPThreadPrivateDecl and checks its correctness.
OMPThreadPrivateDecl *CheckOMPThreadPrivateDecl(SourceLocation Loc,
ArrayRef<Expr *> VarList);
/// Called on well-formed '#pragma omp groupprivate'.
DeclGroupPtrTy ActOnOpenMPGroupPrivateDirective(SourceLocation Loc,
ArrayRef<Expr *> VarList);
/// Builds a new OpenMPGroupPrivateDecl and checks its correctness.
OMPGroupPrivateDecl *CheckOMPGroupPrivateDecl(SourceLocation Loc,
ArrayRef<Expr *> VarList);
/// Called on well-formed '#pragma omp allocate'.
DeclGroupPtrTy ActOnOpenMPAllocateDirective(SourceLocation Loc,
ArrayRef<Expr *> VarList,
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/DeclBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -986,6 +986,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case ObjCCategoryImpl:
case Import:
case OMPThreadPrivate:
case OMPGroupPrivate:
case OMPAllocate:
case OMPRequires:
case OMPCapturedExpr:
Expand Down
28 changes: 28 additions & 0 deletions clang/lib/AST/DeclOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,34 @@ void OMPThreadPrivateDecl::setVars(ArrayRef<Expr *> VL) {
llvm::copy(VL, getVars().begin());
}

//===----------------------------------------------------------------------===//
// OMPGroupPrivateDecl Implementation.
//===----------------------------------------------------------------------===//

void OMPGroupPrivateDecl::anchor() {}

OMPGroupPrivateDecl *OMPGroupPrivateDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
ArrayRef<Expr *> VL) {
auto *D = OMPDeclarativeDirective::createDirective<OMPGroupPrivateDecl>(
C, DC, {}, VL.size(), L);
D->setVars(VL);
return D;
}

OMPGroupPrivateDecl *OMPGroupPrivateDecl::CreateDeserialized(ASTContext &C,
GlobalDeclID ID,
unsigned N) {
return OMPDeclarativeDirective::createEmptyDirective<OMPGroupPrivateDecl>(
C, ID, 0, N);
}

void OMPGroupPrivateDecl::setVars(ArrayRef<Expr *> VL) {
assert(VL.size() == Data->getNumChildren() &&
"Number of variables is not the same as the preallocated buffer");
llvm::copy(VL, getVars().begin());
}

//===----------------------------------------------------------------------===//
// OMPAllocateDecl Implementation.
//===----------------------------------------------------------------------===//
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/AST/OpenMPClause.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
case OMPC_untied:
case OMPC_mergeable:
case OMPC_threadprivate:
case OMPC_groupprivate:
case OMPC_flush:
case OMPC_depobj:
case OMPC_read:
Expand Down Expand Up @@ -222,6 +223,7 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
case OMPC_untied:
case OMPC_mergeable:
case OMPC_threadprivate:
case OMPC_groupprivate:
case OMPC_flush:
case OMPC_depobj:
case OMPC_read:
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Basic/OpenMPKinds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
}
case OMPC_unknown:
case OMPC_threadprivate:
case OMPC_groupprivate:
case OMPC_if:
case OMPC_final:
case OMPC_safelen:
Expand Down Expand Up @@ -565,6 +566,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
llvm_unreachable("Invalid OpenMP 'num_threads' clause modifier");
case OMPC_unknown:
case OMPC_threadprivate:
case OMPC_groupprivate:
case OMPC_if:
case OMPC_final:
case OMPC_safelen:
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CodeGen/CGDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ void CodeGenFunction::EmitDecl(const Decl &D, bool EvaluateConditionDecl) {
case Decl::UnnamedGlobalConstant:
case Decl::TemplateParamObject:
case Decl::OMPThreadPrivate:
case Decl::OMPGroupPrivate:
case Decl::OMPAllocate:
case Decl::OMPCapturedExpr:
case Decl::OMPRequires:
Expand Down
32 changes: 32 additions & 0 deletions clang/lib/Parse/ParseOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2009,6 +2009,19 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
}
break;
}
case OMPD_groupprivate: {
ConsumeToken();
DeclDirectiveListParserHelper Helper(this, DKind);
if (!ParseOpenMPSimpleVarList(DKind, Helper,
/*AllowScopeSpecifier=*/true)) {
skipUntilPragmaOpenMPEnd(DKind);
// Skip the last annot_pragma_openmp_end.
ConsumeAnnotationToken();
return Actions.OpenMP().ActOnOpenMPGroupPrivateDirective(
Loc, Helper.getIdentifiers());
}
break;
}
case OMPD_allocate: {
ConsumeToken();
DeclDirectiveListParserHelper Helper(this, DKind);
Expand Down Expand Up @@ -2731,6 +2744,24 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
SkipUntil(tok::annot_pragma_openmp_end);
break;
}
case OMPD_groupprivate: {
if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
ParsedStmtContext()) {
Diag(Tok, diag::err_omp_immediate_directive)
<< getOpenMPDirectiveName(DKind, OMPVersion) << 0;
}
ConsumeToken();
DeclDirectiveListParserHelper Helper(this, DKind);
if (!ParseOpenMPSimpleVarList(DKind, Helper,
/*AllowScopeSpecifier=*/false)) {
skipUntilPragmaOpenMPEnd(DKind);
DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPGroupPrivateDirective(
Loc, Helper.getIdentifiers());
Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
}
SkipUntil(tok::annot_pragma_openmp_end);
break;
}
case OMPD_allocate: {
// FIXME: Should this be permitted in C++?
if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
Expand Down Expand Up @@ -3285,6 +3316,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
skipUntilPragmaOpenMPEnd(DKind);
break;
case OMPC_threadprivate:
case OMPC_groupprivate:
case OMPC_uniform:
case OMPC_match:
if (!WrongDirective)
Expand Down
Loading